ol
Version:
OpenLayers mapping library
160 lines (145 loc) • 4.13 kB
JavaScript
/**
* @module ol/style/IconImageCache
*/
import ImageState from '../ImageState.js';
import {asArray} from '../color.js';
import {getSharedCanvasContext2D} from '../dom.js';
/**
* @classdesc
* Singleton class. Available through {@link module:ol/style/IconImageCache.shared}.
*/
class IconImageCache {
constructor() {
/**
* @type {!Object<string, import("./IconImage.js").default>}
* @private
*/
this.cache_ = {};
/**
* @type {!Object<string, CanvasPattern>}
* @private
*/
this.patternCache_ = {};
/**
* @type {number}
* @private
*/
this.cacheSize_ = 0;
/**
* @type {number}
* @private
*/
this.maxCacheSize_ = 1024;
}
/**
* FIXME empty description for jsdoc
*/
clear() {
this.cache_ = {};
this.patternCache_ = {};
this.cacheSize_ = 0;
}
/**
* @return {boolean} Can expire cache.
*/
canExpireCache() {
return this.cacheSize_ > this.maxCacheSize_;
}
/**
* FIXME empty description for jsdoc
*/
expire() {
if (this.canExpireCache()) {
let i = 0;
for (const key in this.cache_) {
const iconImage = this.cache_[key];
if ((i++ & 3) === 0 && !iconImage.hasListener()) {
delete this.cache_[key];
delete this.patternCache_[key];
--this.cacheSize_;
}
}
}
}
/**
* @param {string} src Src.
* @param {?string} crossOrigin Cross origin.
* @param {import("../color.js").Color|string|null} color Color.
* @return {import("./IconImage.js").default} Icon image.
*/
get(src, crossOrigin, color) {
const key = getCacheKey(src, crossOrigin, color);
return key in this.cache_ ? this.cache_[key] : null;
}
/**
* @param {string} src Src.
* @param {?string} crossOrigin Cross origin.
* @param {import("../color.js").Color|string|null} color Color.
* @return {CanvasPattern} Icon image.
*/
getPattern(src, crossOrigin, color) {
const key = getCacheKey(src, crossOrigin, color);
return key in this.patternCache_ ? this.patternCache_[key] : null;
}
/**
* @param {string} src Src.
* @param {?string} crossOrigin Cross origin.
* @param {import("../color.js").Color|string|null} color Color.
* @param {import("./IconImage.js").default|null} iconImage Icon image.
* @param {boolean} [pattern] Also cache a `'repeat'` pattern with this `iconImage`.
*/
set(src, crossOrigin, color, iconImage, pattern) {
const key = getCacheKey(src, crossOrigin, color);
const update = key in this.cache_;
this.cache_[key] = iconImage;
if (pattern) {
if (iconImage.getImageState() === ImageState.IDLE) {
iconImage.load();
}
if (iconImage.getImageState() === ImageState.LOADING) {
iconImage.ready().then(() => {
this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
iconImage.getImage(1),
'repeat',
);
});
} else {
this.patternCache_[key] = getSharedCanvasContext2D().createPattern(
iconImage.getImage(1),
'repeat',
);
}
}
if (!update) {
++this.cacheSize_;
}
}
/**
* Set the cache size of the icon cache. Default is `1024`. Change this value when
* your map uses more than 1024 different icon images and you are not caching icon
* styles on the application level.
* @param {number} maxCacheSize Cache max size.
* @api
*/
setSize(maxCacheSize) {
this.maxCacheSize_ = maxCacheSize;
this.expire();
}
}
/**
* @param {string} src Src.
* @param {?string} crossOrigin Cross origin.
* @param {import("../color.js").Color|string|null} color Color.
* @return {string} Cache key.
*/
export function getCacheKey(src, crossOrigin, color) {
const colorString = color ? asArray(color) : 'null';
return crossOrigin + ':' + src + ':' + colorString;
}
export default IconImageCache;
/**
* The {@link module:ol/style/IconImageCache~IconImageCache} for
* {@link module:ol/style/Icon~Icon} images.
* @api
*/
export const shared = new IconImageCache();