From 2e34dd0fafdc40a0bdd2023db55514083b1da87c Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 21 Mar 2019 10:42:18 +0100 Subject: [PATCH] Use HTMLImageElement.decode if available --- src/ol/Image.js | 44 ++++++++++++++++++++++++++++++++------- src/ol/ImageTile.js | 17 +++++++-------- src/ol/style/IconImage.js | 17 +++++++-------- 3 files changed, 51 insertions(+), 27 deletions(-) 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_); } }