UNPKG

zrender

Version:

A lightweight graphic library providing 2d draw for Apache ECharts

107 lines (90 loc) 3.05 kB
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; }