Use HTMLImageElement.decode if available

This commit is contained in:
Frederic Junod
2019-03-21 10:42:18 +01:00
parent 5a4541dadb
commit 2e34dd0faf
3 changed files with 51 additions and 27 deletions
+36 -8
View File
@@ -120,13 +120,12 @@ class ImageWrapper extends ImageBase {
if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) { if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {
this.state = ImageState.LOADING; this.state = ImageState.LOADING;
this.changed(); 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.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 * @private
*/ */
unlistenImage_() { unlistenImage_() {
this.imageListenerKeys_.forEach(unlistenByKey); unlistenImage(this.imageListenerKeys_);
this.imageListenerKeys_ = null;
} }
} }
/**
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.
* @param {function():any} loadHandler Load callback function.
* @param {function():any} errorHandler Error callback function.
* @return {Array<import("./events.js").EventsKey>} 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<import("./events.js").EventsKey>} listenerKeys listener keys.
*/
export function unlistenImage(listenerKeys) {
if (listenerKeys) {
listenerKeys.forEach(unlistenByKey);
listenerKeys = null;
}
}
export default ImageWrapper; export default ImageWrapper;
+7 -10
View File
@@ -4,8 +4,7 @@
import Tile from './Tile.js'; import Tile from './Tile.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
import {createCanvasContext2D} from './dom.js'; import {createCanvasContext2D} from './dom.js';
import {listenOnce, unlistenByKey} from './events.js'; import {listenImage, unlistenImage} from './Image.js';
import EventType from './events/EventType.js';
class ImageTile extends Tile { class ImageTile extends Tile {
@@ -134,13 +133,12 @@ class ImageTile extends Tile {
if (this.state == TileState.IDLE) { if (this.state == TileState.IDLE) {
this.state = TileState.LOADING; this.state = TileState.LOADING;
this.changed(); 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.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 * @private
*/ */
unlistenImage_() { unlistenImage_() {
this.imageListenerKeys_.forEach(unlistenByKey); unlistenImage(this.imageListenerKeys_);
this.imageListenerKeys_ = null;
} }
} }
+8 -9
View File
@@ -3,11 +3,12 @@
*/ */
import {createCanvasContext2D} from '../dom.js'; import {createCanvasContext2D} from '../dom.js';
import {listenOnce, unlistenByKey} from '../events.js';
import EventTarget from '../events/Target.js'; import EventTarget from '../events/Target.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import ImageState from '../ImageState.js'; import ImageState from '../ImageState.js';
import {shared as iconImageCache} from './IconImageCache.js'; import {shared as iconImageCache} from './IconImageCache.js';
import {listenImage, unlistenImage} from '../Image.js';
class IconImage extends EventTarget { class IconImage extends EventTarget {
/** /**
@@ -185,17 +186,16 @@ class IconImage extends EventTarget {
load() { load() {
if (this.imageState_ == ImageState.IDLE) { if (this.imageState_ == ImageState.IDLE) {
this.imageState_ = ImageState.LOADING; this.imageState_ = ImageState.LOADING;
this.imageListenerKeys_ = [
listenOnce(this.image_, EventType.ERROR,
this.handleImageError_, this),
listenOnce(this.image_, EventType.LOAD,
this.handleImageLoad_, this)
];
try { try {
/** @type {HTMLImageElement} */ (this.image_).src = this.src_; /** @type {HTMLImageElement} */ (this.image_).src = this.src_;
} catch (e) { } catch (e) {
this.handleImageError_(); this.handleImageError_();
} }
this.imageListenerKeys_ = listenImage(
this.image_,
this.handleImageLoad_.bind(this),
this.handleImageError_.bind(this)
);
} }
} }
@@ -233,8 +233,7 @@ class IconImage extends EventTarget {
* @private * @private
*/ */
unlistenImage_() { unlistenImage_() {
this.imageListenerKeys_.forEach(unlistenByKey); unlistenImage(this.imageListenerKeys_);
this.imageListenerKeys_ = null;
} }
} }