From 577c6988a3b4555244525909e761ffed97fdb32b Mon Sep 17 00:00:00 2001 From: Reinder Nijhoff Date: Mon, 27 May 2024 13:11:57 +0200 Subject: [PATCH] Added timeout option to image source --- README.md | 5 ++++- example/src/exampleWithCustomCanvas.js | 2 +- src/lib/FastImageSequence.ts | 16 ++++++++++++---- src/lib/ImageSource.ts | 7 ++++++- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8f1259d..69fbb69 100644 --- a/README.md +++ b/README.md @@ -137,8 +137,11 @@ will automatically fall back to the best matching available image when rendering - **maxCachedImages**: `number` - Number of images to cache. Default: `32` - **available**: `((index: number) => boolean) | undefined` - Callback returning whether an image is available. Optional. -- **image**: `((index: number) => CanvasImageSource) | undefined` - Callback returning the image given its index. +- **image**: `((index: number) => Promise) | undefined` - Callback returning the image given its + index. Optional. +- **timeout**: `number` - Only start loading an image if the same frame is visible for this amount of time (in + milliseconds). Optional. ## Methods diff --git a/example/src/exampleWithCustomCanvas.js b/example/src/exampleWithCustomCanvas.js index a5a4671..37385a7 100644 --- a/example/src/exampleWithCustomCanvas.js +++ b/example/src/exampleWithCustomCanvas.js @@ -74,7 +74,7 @@ export async function initExampleWithCustomCanvas(container) { { image: (i) => createCustomCanvas(i, frames), maxCachedImages: frames, - }, + } ], // optional arguments: loop: true, // default false diff --git a/src/lib/FastImageSequence.ts b/src/lib/FastImageSequence.ts index dce0471..74b9cb2 100644 --- a/src/lib/FastImageSequence.ts +++ b/src/lib/FastImageSequence.ts @@ -86,6 +86,7 @@ export class FastImageSequence { private logElement: HTMLElement | undefined; private initialized: boolean = false; private posterImage: HTMLImageElement | undefined; + private timeFrameVisible: number = 0; /** * Creates an instance of FastImageSequence. @@ -414,7 +415,13 @@ export class FastImageSequence { } } - this.process(dt); + if (this.wrapIndex(this.frame) === this.wrapIndex(this.prevFrame)) { + this.timeFrameVisible += dt; + } else { + this.timeFrameVisible = 0; + } + + this.process(); this.tickFuncs.forEach(func => func(dt)); @@ -476,10 +483,11 @@ export class FastImageSequence { this.context.drawImage(image, 0, 0, imageWidth, imageHeight, dx, dy, this.width, this.height); } - private process(dt: number) { + private process() { for (const source of this.sources) { - this.setLoadingPriority(); - source.process(() => this.setLoadingPriority()); + if (this.timeFrameVisible >= source.options.timeout / 1000) { + source.process(() => this.setLoadingPriority()); + } } } diff --git a/src/lib/ImageSource.ts b/src/lib/ImageSource.ts index 5cbbe65..9e6530a 100644 --- a/src/lib/ImageSource.ts +++ b/src/lib/ImageSource.ts @@ -17,7 +17,8 @@ export type ImageSourceType = typeof INPUT_SRC | typeof INPUT_TAR; * @property {number} maxCachedImages - The number of images to cache. * @property {number} maxConnectionLimit - The maximum number of images to load at once. * @property {((index: number) => boolean) | undefined} available - A callback function that returns if an image is available given its index. - * @property {((index: number) => CanvasImageSource) | undefined} image - A callback function that returns the image element given its index. + * @property {((index: number) => Promise) | undefined} image - A callback function that returns the image element given its index. + * @property {number} timeout - Only start loading an image if the same frame is visible for this amount of time (in milliseconds). */ export type ImageSourceOptions = { imageURL: ((index: number) => string) | undefined, @@ -27,6 +28,7 @@ export type ImageSourceOptions = { maxConnectionLimit: number, available: ((index: number) => boolean) | undefined, image: ((index: number) => Promise) | undefined, + timeout: number, } export default class ImageSource { @@ -38,6 +40,7 @@ export default class ImageSource { maxConnectionLimit: 4, available: undefined, image: undefined, + timeout: -1, }; public options: ImageSourceOptions; @@ -90,6 +93,8 @@ export default class ImageSource { } public process(setLoadingPriority: () => void) { + setLoadingPriority(); + let {numLoading, numLoaded} = this.getLoadStatus(); const maxConnectionLimit = this.options.maxConnectionLimit; const imagesToLoad = this.images.filter(a => a.available && a.image === undefined && !a.loading && a.frame.priority).sort((a, b) => a.frame.priority - b.frame.priority);