UNPKG

image-reader

Version:

Allow you to control and switch an image source to play as a MovieClip.

220 lines (144 loc) 3.71 kB
export default class ImageReader { constructor(images = null, { autoplay = true, el = null, fps = 30, from = 0, loop = false, onComplete = null, onRepeat = null, onRepeatComplete = null, repeat = 0, retina = false, reverse = null, to = null } = {}) { if (!images) throw new Error('images parameter can not be null'); if (!Array.isArray(images)) throw new Error('images parameter must be an array'); this._images = images; this._elTarget = el || new Image(); this._currentRepeat = 0; this._from = from; this._current = from; this._to = to; this._isPlaying = autoplay; this._repeat = loop ? -1 : repeat; this._interval = 1000 / fps; this._then = null; this._onComplete = onComplete; this._onRepeat = onRepeat; this._onRepeatComplete = onRepeatComplete; if (this._to === null) this._to = this._images.length - 1; this._side = reverse || this._from > this._to ? -1 : 1; if (this._side === -1 && this._from < this._to) { const tmpFrom = this._from; const tmpTo = this._to; this._from = Math.max(tmpFrom, tmpTo); this._to = Math.min(tmpFrom, tmpTo); } if (!el) { Object.assign(this._elTarget.style, { width: `${this._images[0].naturalWidth / (retina ? 2 : 1)}px`, height: `${this._images[0].naturalHeight / (retina ? 2 : 1)}px` }); } this.update(true); } draw() { this._elTarget.src = this._images[this._current]; } update(force = false) { if (!this._isPlaying && !force) return; const now = performance.now(); const delta = now - this._then; if (delta < this._interval && !force) return; this._then = now - delta % this._interval; this.draw(); if (this._current === this._to) { if (this._repeat) { this._currentRepeat++; this._current = this._from; this._currentPack = 0; if (this._onRepeat) this._onRepeat(); if (this._repeat > 0 && this._currentRepeat > this._repeat) { this._isPlaying = false; if (this._onRepeatComplete) this._onRepeatComplete(); } } else { this._isPlaying = false; if (this._onComplete) this._onComplete(); } } else if (!force) this._current += this._side; } play() { this._isPlaying = true; } pause() { this._isPlaying = false; } stop() { this._isPlaying = false; this._current = this._from; } reverse(force = null) { if (force !== null) this._side = force ? 1 : -1; else this._side = this._side === 1 ? -1 : 1; const tmpFrom = this._from; const tmpTo = this._to; this._from = this._side === 1 ? Math.min(tmpFrom, tmpTo) : Math.max(tmpFrom, tmpTo); this._to = this._side === 1 ? Math.max(tmpFrom, tmpTo) : Math.min(tmpFrom, tmpTo); } goFromTo(from, to) { if (from >= 0) this._from = from; if (to >= 0) this._to = to; this._current = this._from; this._side = from > to ? -1 : 1; } goToAndPlay(frame) { this._current = frame; this._isPlaying = true; } goToAndStop(frame) { this._current = frame; this._isPlaying = false; this.update(true); } isPlaying() { return this._isPlaying; } destroy() { this._isPlaying = false; this._elTarget.parentNode.remove(this._elTarget); } get el() { return this._elTarget; } get current() { return this._current; } get total() { return this._images.length; } set fps(nbr) { this._interval = 1000 / nbr; } set loop(val) { if (val) this._repeat = -1; else if (this._repeat === -1) this._repeat = 0; } set repeat(nbr) { this._repeat = nbr; this._currentRepeat = 0; } set onComplete(fn) { this._onComplete = fn; } set onRepeat(fn) { this._onRepeat = fn; } set onRepeatComplete(fn) { this._onRepeatComplete = fn; } }