diff --git a/src/ol/Image.js b/src/ol/Image.js index fdfec05be1..45d0cf07cf 100644 --- a/src/ol/Image.js +++ b/src/ol/Image.js @@ -120,13 +120,12 @@ class ImageWrapper extends ImageBase { if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) { this.state = ImageState.LOADING; this.changed(); - this.imageListenerKeys_ = [ - listenOnce(this.image_, EventType.ERROR, - this.handleImageError_, this), - listenOnce(this.image_, EventType.LOAD, - this.handleImageLoad_, this) - ]; this.imageLoadFunction_(this, this.src_); + this.imageListenerKeys_ = listenImage( + this.image_, + this.handleImageLoad_.bind(this), + this.handleImageError_.bind(this) + ); } } @@ -143,10 +142,39 @@ class ImageWrapper extends ImageBase { * @private */ unlistenImage_() { - this.imageListenerKeys_.forEach(unlistenByKey); - this.imageListenerKeys_ = null; + unlistenImage(this.imageListenerKeys_); } } +/** + * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element. + * @param {function():any} loadHandler Load callback function. + * @param {function():any} errorHandler Error callback function. + * @return {Array} listener keys. + */ +export function listenImage(image, loadHandler, errorHandler) { + const img = /** @type {HTMLImageElement} */ (image); + if (img.decode) { + img.decode().then(loadHandler).catch(errorHandler); + return null; + } else { + const listenerKeys = [ + listenOnce(img, EventType.LOAD, loadHandler), + listenOnce(img, EventType.ERROR, errorHandler) + ]; + return listenerKeys; + } + +} + +/** + * @param {Array} listenerKeys listener keys. + */ +export function unlistenImage(listenerKeys) { + if (listenerKeys) { + listenerKeys.forEach(unlistenByKey); + listenerKeys = null; + } +} export default ImageWrapper; diff --git a/src/ol/ImageTile.js b/src/ol/ImageTile.js index a5ae93b667..b6a5496e03 100644 --- a/src/ol/ImageTile.js +++ b/src/ol/ImageTile.js @@ -4,8 +4,7 @@ import Tile from './Tile.js'; import TileState from './TileState.js'; import {createCanvasContext2D} from './dom.js'; -import {listenOnce, unlistenByKey} from './events.js'; -import EventType from './events/EventType.js'; +import {listenImage, unlistenImage} from './Image.js'; class ImageTile extends Tile { @@ -134,13 +133,12 @@ class ImageTile extends Tile { if (this.state == TileState.IDLE) { this.state = TileState.LOADING; this.changed(); - this.imageListenerKeys_ = [ - listenOnce(this.image_, EventType.ERROR, - this.handleImageError_, this), - listenOnce(this.image_, EventType.LOAD, - this.handleImageLoad_, this) - ]; this.tileLoadFunction_(this, this.src_); + this.imageListenerKeys_ = listenImage( + this.image_, + this.handleImageLoad_.bind(this), + this.handleImageError_.bind(this) + ); } } @@ -150,8 +148,7 @@ class ImageTile extends Tile { * @private */ unlistenImage_() { - this.imageListenerKeys_.forEach(unlistenByKey); - this.imageListenerKeys_ = null; + unlistenImage(this.imageListenerKeys_); } } diff --git a/src/ol/style/IconImage.js b/src/ol/style/IconImage.js index 8f1cc8069f..45214a22cd 100644 --- a/src/ol/style/IconImage.js +++ b/src/ol/style/IconImage.js @@ -3,11 +3,12 @@ */ import {createCanvasContext2D} from '../dom.js'; -import {listenOnce, unlistenByKey} from '../events.js'; import EventTarget from '../events/Target.js'; import EventType from '../events/EventType.js'; import ImageState from '../ImageState.js'; import {shared as iconImageCache} from './IconImageCache.js'; +import {listenImage, unlistenImage} from '../Image.js'; + class IconImage extends EventTarget { /** @@ -185,17 +186,16 @@ class IconImage extends EventTarget { load() { if (this.imageState_ == ImageState.IDLE) { this.imageState_ = ImageState.LOADING; - this.imageListenerKeys_ = [ - listenOnce(this.image_, EventType.ERROR, - this.handleImageError_, this), - listenOnce(this.image_, EventType.LOAD, - this.handleImageLoad_, this) - ]; try { /** @type {HTMLImageElement} */ (this.image_).src = this.src_; } catch (e) { this.handleImageError_(); } + this.imageListenerKeys_ = listenImage( + this.image_, + this.handleImageLoad_.bind(this), + this.handleImageError_.bind(this) + ); } } @@ -233,8 +233,7 @@ class IconImage extends EventTarget { * @private */ unlistenImage_() { - this.imageListenerKeys_.forEach(unlistenByKey); - this.imageListenerKeys_ = null; + unlistenImage(this.imageListenerKeys_); } }