JavaScript基于libgif.js實現(xiàn)控制gif動畫幀
一、原理
1.canvas、img、video,都是圖像對象,屬于圖像類型的節(jié)點。這種圖像對象不是Image 對象,而是對加載圖像數(shù)據(jù)流的節(jié)點的統(tǒng)稱。
- img 里的圖像數(shù)據(jù)來源于提前制作好圖片文件的,是靜止的,比如.jpg,.png,.svg 等。.gif 是個特殊存在,另當別論。
- vedio 里的視頻數(shù)據(jù)來源于提前制作好的視頻文件,是動起來的。
- canvas 圖像數(shù)據(jù)是動態(tài)生成的。
2.圖像對象的數(shù)據(jù)的讀寫
讀取圖像數(shù)據(jù)
- img 和video 沒有直接獲取ImageData 的方法,但可以通過canvas 獲取
- canvas 使用getImageData 方法讀取自身的圖像數(shù)據(jù)
寫入圖像數(shù)據(jù)
- img 和video 只能通過src ,以資源路徑的方式設置其顯示圖像(img 的src 還可以使用base64)。但他們無法直接用ImageData 設置圖像。
- canvas 可以用drawImage 或fillStyle 方法,以圖像對象為參數(shù),為canvas 或其內部元素寫入圖像數(shù)據(jù)。canvas 也可以通過putImageData方法,以ImageData 對象為參數(shù),為其寫入圖像數(shù)據(jù)。
- gif 是介于圖片和視頻之間的特殊存在。
用讀取image 數(shù)據(jù)的原理讀取它,只能讀到第一幀gif 圖片。
直接繪制gif 肯定是不好使的,這里就用到了一個插件libgif.js
二、插件libgif.js
libgif.js已經完成了對gif 的解析,并將其寫入了canvas 中。
libgif.js網址:github.com/buzzfeed/libgif-js
下面是我從官網上復制粘貼下來,用百度翻譯一下 ,然后略作調整。英語好的可以跳過這里,看官網。
1.寫在圖片標簽里的屬性 Image tag attributes
- rel:animated_src - 如果指定了此url,則將其加載到播放器而不是src中。這允許顯示預覽幀,直到動畫gif數(shù)據(jù)流入畫布
- rel:auto_play - 如果未指定,則默認為1。如果設置為零,則需要調用play()方法
- rel:rubbable - 如果未指定,則默認為0。如果設置為1,則gif將是一個帶有處理程序的畫布來處理摩擦。
2.構造函數(shù) Constructor options
- gif - 必填。img標簽的DOM元素。
- loop_mode - 可選。將此設置為false將強制禁用gif的循環(huán)。
- auto_play - 可選。與上面的rel:auto_play屬性相同,此arg會覆蓋img標記信息。
- max_width - 可選。將圖像從max_width縮放到max_width。有助于移動。
- rubbable - 可選。讓它可以擦掉。
- on_end - 可選。添加一個回調,用于當gif到達單個循環(huán)結束時(一次迭代)。傳遞的第一個參數(shù)將是gif HTMLElement。
- loop_delay - 可選。每次循環(huán)(迭代)后暫停的時間(以毫秒為單位)。
- progressbar_height - 可選。進度條的高度。
- progressbar_background_color - 可選。進度條的背景顏色。
- progressbar_foreground_color - 可選。進度條的前景色。
3.loading 事件
- load(callback) - 將src指定的gif或img標記的rel:animated_src sttributie加載到canvas元素中,然后調用callback(如果有的話)
- load_url(src,callback) - 將src參數(shù)中指定的gif文件加載到canvas元素中,如果傳遞了一個,則調用callback
4.播放控制器 play controls
- play - 開始玩GIF
- pause - 停止播放gif
- move_to(i) - 移動到gif的第i幀
- move_relative(i) - 向前移動i幀(如果i <0則向后移動)
5.數(shù)據(jù)獲取 getters
- get_canvas - gif正在播放的canvas元素。方便分配事件處理程序。
- get_playing - gif當前是否正在播放
- get_loading - gif是否已完成加載/解析
- get_auto_play - 是否將gif設置為自動播放
- get_length - gif中的幀數(shù)
- get_current_frame - 當前顯示的gif幀的索引
6.官方案例
<center> <h1>控制gif播放/暫停/快進快退</h1> <img id="example1" src="./example_gifs/rub_test_preview.jpg" rel:animated_src="./example_gifs/rub_test.gif" rel:auto_play="0" width="467" height="375" /> <br> <script type="text/javascript"> var sup1 = new SuperGif({ gif: document.getElementById('example1') } ); sup1.load(); </script> <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onmousedown="sup1.play(); return false;">播放</a> | <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onmousedown="sup1.pause(); return false;">暫停</a> <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onmousedown="sup1.move_to(0); return false;">還原</a> | <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onmousedown="sup1.move_relative(1); return false;">下一幀</a> | <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onmousedown="sup1.move_relative(-1); return false;">上一幀</a> </center> <img src="./example1_preview.gif" rel:animated_src="./example1.gif" width="360" height="360" rel:auto_play="1" rel:rubbable="1" /> <script type="text/javascript"> $$('img').each(function (img_tag) { if (/.*\.gif/.test(img_tag.src)) { var rub = new SuperGif({ gif: img_tag } ); rub.load(function(){ console.log('oh hey, now the gif is loaded'); }); } }); </script>
提示:
- RubbableGif 對象繼承自 SuperGif 對象,SuperGif是解析gif 的核心。
- 前端建立的 節(jié)點,只是一個向SuperGif 對象傳遞數(shù)據(jù)的工具,等SuperGif 解析完了gif,就會用canvas 將img 替換掉。
三、實際應用
前景是這樣的,用gif做一個進度條,等待gif動畫播放完成后,顯示按鈕;
一開始我是用了一個定時器設置時間跟gif動畫時間一樣長,時間到動畫播放完成,按鈕顯示,沒毛??; 但是,在實際運用過程中發(fā)現(xiàn),加載gif由于網絡原因跟定時器就不會同步,很多情況是,定時器走完了,gif才播放一半,顯然效果不理想,后來經過產品提醒,能不能判斷gif播放完畢后,再顯示這個按鈕;于是查找資料,發(fā)現(xiàn)了這個libgif.js插件挺好的,于是做了嘗試,完美解決問題,在此記錄一下。
本文重點講述運用libgif.js實現(xiàn),加載一個load.gif完成后,進行下一步的業(yè)務邏輯,代碼如下:
<!--樣式--> <style type="text/css"> *{margin: 0; padding: 0;} .load_p{ position: relative; width: 100vw; height: 100vh; } a.play_2{display: none; position: absolute; left: 50%; top: 50%; margin-left:-370px; margin-top:-37px;} </style>
<!--dom結構--> <script type="text/javascript" src="./libgif.js"></script> <div class="load_p"> <img id="load" src="./example_gifs/loadbg.gif" rel:animated_src="./example_gifs/loadbg.gif" rel:auto_play="0"/> <a href="javascript://" rel="external nofollow" class="play_2" id="btn"><img src="./example_gifs/p1_btn_v.png" alt=""/></a> </div>
<!--js--> <script type="text/javascript"> var gif = new SuperGif({ gif: document.getElementById('load'), //img標簽的DOM元素。 loop_mode:false, //將此設置為false將強制禁用gif的循環(huán)。 progressbar_foreground_color: "rgba(255,255,255,0.1)", progressbar_background_color: "rgba(255,255,255,0.1)", progressbar_height: 1 }); gif.load(function() { var lastFrameIndex = gif.get_length() - 1; // 獲取最后一幀的索引 gif.play(); // 設置一個定時器,周期性檢查當前幀 var timer = setInterval(function() { if (gif.get_current_frame() === lastFrameIndex) { console.log("播放結束"); document.getElementById('btn').style.display='block'; clearInterval(timer); // 清除定時器 } }, 100); }); </script>
最終效果,是loadbg.gif動畫播放完成后,a.play_2按鈕顯示。
附上libgif.js github:github.com/buzzfeed/libgif-js?tab=readme-ov-file
到此這篇關于JavaScript基于libgif.js實現(xiàn)控制gif動畫幀的文章就介紹到這了,更多相關JavaScript控制動畫幀內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Javascript表單序列化原理及實現(xiàn)代碼詳解
這篇文章主要介紹了Javascript表單序列化原理及實現(xiàn)代碼詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-10-10JavaScript+canvas實現(xiàn)七色板效果實例
這篇文章主要介紹了JavaScript+canvas實現(xiàn)七色板效果的方法,結合實例形式詳細分析了JavaScript結合html5的canvas技術實現(xiàn)繪制七色板效果的相關技巧,需要的朋友可以參考下2016-02-02JavaScript循環(huán)_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了JavaScript循環(huán)的相關資料,JavaScript的兩種循環(huán)方式,一種是for循環(huán),另while一種是循環(huán)具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06jQuery animate()實現(xiàn)背景色漸變效果的處理方法【使用jQuery.color.js插件】
這篇文章主要介紹了jQuery animate()實現(xiàn)背景色漸變效果的處理方法,結合實例形式分析了jQuery顏色插件jquery.color.js實現(xiàn)背景色漸變的簡單操作技巧,需要的朋友可以參考下2017-03-03