UNPKG

gif-end-detector

Version:

A library for detecting GIF animation end events, based on libgif.js

229 lines (227 loc) 7.9 kB
/** * gifEndDetector - GIFアニメーション終了イベント検知ライブラリ * libgif.jsをベースにしたシンプルなラッパー * * 依存: libgif.js (https://github.com/buzzfeed/libgif-js) */ /** * GIFアニメーション終了検知ライブラリ * @param source - GIFファイルのパスまたはURL * @returns GifEndDetectorインスタンス */ function gifEndDetector(source) { // インスタンス化パターンを強制する if (!(this instanceof gifEndDetector)) { return new gifEndDetector(source); } // libgif.jsが利用可能かチェック if (typeof window === 'undefined' || !window.SuperGif) { console.error('libgif.js (SuperGif) が見つかりません。先にロードしてください。'); this.source = source; this._gif = null; this._canvas = null; this._totalFrames = 0; this._currentFrame = 0; this._isPlaying = false; this._endCallbacks = []; this._frameCallbacks = []; this._loadCallbacks = []; this._errorCallbacks = []; this._onDrawFrame = null; return this; } this.source = source; this._gif = null; this._canvas = null; this._totalFrames = 0; this._currentFrame = 0; this._isPlaying = false; this._endCallbacks = []; this._frameCallbacks = []; this._loadCallbacks = []; this._errorCallbacks = []; this._onDrawFrame = null; return this; } // プロトタイプメソッド gifEndDetector.prototype = { /** * GIFファイルを読み込み、準備完了後にコールバックを実行 * @param callback - 準備完了後に実行されるコールバック関数 * @returns チェーン用のインスタンス */ load: function (callback) { var self = this; if (callback && typeof callback === 'function') { this._loadCallbacks.push(callback); } // libgif.jsのSuperGifを初期化 this._gif = new window.SuperGif({ src: this.source, loop_mode: false, auto_play: false, on_end: function () { // libgif.jsの終了イベント時に自分の終了コールバックを実行 self._handleEnd(); } }); // GIFの読み込みを開始 this._gif.load(function () { // 読み込み完了後の処理 self._canvas = self._gif.get_canvas(); self._totalFrames = self._gif.get_length(); // loadCallbacksを実行 self._loadCallbacks.forEach(function (cb) { cb(self); }); }); return this; }, /** * 終了イベントのコールバックを登録 * @param callback - 終了時に呼び出されるコールバック関数 * @returns チェーン用のインスタンス */ onEnd: function (callback) { if (callback && typeof callback === 'function') { this._endCallbacks.push(callback); } return this; }, /** * フレーム描画イベントのコールバックを登録 * @param callback - フレーム描画時に呼び出されるコールバック関数 * @returns チェーン用のインスタンス */ onFrame: function (callback) { if (callback && typeof callback === 'function') { this._frameCallbacks.push(callback); } return this; }, /** * エラー発生時のコールバックを登録 * @param callback - エラー時に呼び出されるコールバック関数 * @returns チェーン用のインスタンス */ onError: function (callback) { if (callback && typeof callback === 'function') { this._errorCallbacks.push(callback); } return this; }, /** * カスタムフレーム描画関数を設定 * @param drawFunction - カスタム描画関数 * @returns チェーン用のインスタンス */ setOnDrawFrame: function (drawFunction) { if (typeof drawFunction === 'function') { this._onDrawFrame = drawFunction; // libgif.jsの描画関数をオーバーライド if (this._gif) { var self_1 = this; var originalDrawFrame_1 = this._gif.drawFrame.bind(this._gif); this._gif.drawFrame = function () { // オリジナルの描画関数を実行 originalDrawFrame_1(); // 現在のフレーム番号を取得 var frameIndex = self_1._gif.getCurrentFrame(); self_1._currentFrame = frameIndex; // カスタム描画関数を実行 if (self_1._canvas && self_1._onDrawFrame) { var ctx = self_1._canvas.getContext('2d'); if (ctx) { self_1._onDrawFrame(ctx, frameIndex, self_1._totalFrames); } } // フレームコールバックを実行 self_1._frameCallbacks.forEach(function (cb) { cb(frameIndex, self_1._totalFrames); }); // 最後のフレームであれば終了処理 if (frameIndex === self_1._totalFrames - 1) { self_1._handleEnd(); } }; } } return this; }, /** * アニメーションを開始 * @returns チェーン用のインスタンス */ play: function () { if (this._gif && !this._isPlaying) { this._isPlaying = true; this._gif.play(); } return this; }, /** * アニメーションを停止 * @returns チェーン用のインスタンス */ pause: function () { if (this._gif && this._isPlaying) { this._isPlaying = false; this._gif.pause(); } return this; }, /** * アニメーションをリセット(最初のフレームに戻す) * @returns チェーン用のインスタンス */ reset: function () { if (this._gif) { this._gif.move_to(0); } return this; }, /** * 特定のフレームに移動 * @param frameIndex - 移動先のフレーム番号 * @returns チェーン用のインスタンス */ moveToFrame: function (frameIndex) { if (this._gif && frameIndex >= 0 && frameIndex < this._totalFrames) { this._gif.move_to(frameIndex); } return this; }, /** * Canvas要素を取得 * @returns GIFが描画されているCanvas要素 */ getCanvas: function () { return this._canvas; }, /** * 総フレーム数を取得 * @returns GIFの総フレーム数 */ getTotalFrames: function () { return this._totalFrames; }, /** * 現在のフレーム番号を取得 * @returns 現在表示中のフレーム番号 */ getCurrentFrame: function () { return this._currentFrame; }, /** * 終了処理を実行する内部メソッド * @private */ _handleEnd: function () { this._isPlaying = false; // 終了コールバックを実行 this._endCallbacks.forEach(function (cb) { cb(); }); } }; export { gifEndDetector as default };