123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import LRU from '../../core/LRU';
- import { platformApi } from '../../core/platform';
- import { ImageLike } from '../../core/types';
- const globalImageCache = new LRU<CachedImageObj>(50);
- type PendingWrap = {
- hostEl: {dirty: () => void}
- cb: (image: ImageLike, payload: any) => void
- cbPayload: any
- }
- type CachedImageObj = {
- image: ImageLike
- pending: PendingWrap[]
- }
- export function findExistImage(newImageOrSrc: string | ImageLike): ImageLike {
- if (typeof newImageOrSrc === 'string') {
- const cachedImgObj = globalImageCache.get(newImageOrSrc);
- return cachedImgObj && cachedImgObj.image;
- }
- else {
- return newImageOrSrc;
- }
- }
- /**
- * Caution: User should cache loaded images, but not just count on LRU.
- * Consider if required images more than LRU size, will dead loop occur?
- *
- * @param newImageOrSrc
- * @param image Existent image.
- * @param hostEl For calling `dirty`.
- * @param onload params: (image, cbPayload)
- * @param cbPayload Payload on cb calling.
- * @return image
- */
- export function createOrUpdateImage<T>(
- newImageOrSrc: string | ImageLike,
- image: ImageLike,
- hostEl: { dirty: () => void },
- onload?: (image: ImageLike, payload: T) => void,
- cbPayload?: T
- ) {
- if (!newImageOrSrc) {
- return image;
- }
- else if (typeof newImageOrSrc === 'string') {
- // Image should not be loaded repeatly.
- if ((image && (image as any).__zrImageSrc === newImageOrSrc) || !hostEl) {
- return image;
- }
- // Only when there is no existent image or existent image src
- // is different, this method is responsible for load.
- const cachedImgObj = globalImageCache.get(newImageOrSrc);
- const pendingWrap = {hostEl: hostEl, cb: onload, cbPayload: cbPayload};
- if (cachedImgObj) {
- image = cachedImgObj.image;
- !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
- }
- else {
- image = platformApi.loadImage(
- newImageOrSrc, imageOnLoad, imageOnLoad
- );
- (image as any).__zrImageSrc = newImageOrSrc;
- globalImageCache.put(
- newImageOrSrc,
- (image as any).__cachedImgObj = {
- image: image,
- pending: [pendingWrap]
- }
- );
- }
- return image;
- }
- // newImageOrSrc is an HTMLImageElement or HTMLCanvasElement or Canvas
- else {
- return newImageOrSrc;
- }
- }
- function imageOnLoad(this: any) {
- const cachedImgObj = this.__cachedImgObj;
- this.onload = this.onerror = this.__cachedImgObj = null;
- for (let i = 0; i < cachedImgObj.pending.length; i++) {
- const pendingWrap = cachedImgObj.pending[i];
- const cb = pendingWrap.cb;
- cb && cb(this, pendingWrap.cbPayload);
- pendingWrap.hostEl.dirty();
- }
- cachedImgObj.pending.length = 0;
- }
- export function isImageReady(image: ImageLike) {
- return image && image.width && image.height;
- }
|