將 GSAP 動畫轉換為動畫 GIF:使用 modern-gif 的分步指南
關鍵要點
本文將解釋如何使用 modern-gif 將使用 GSAP 創建的動畫轉換為動畫 GIF。
以下是一個我之前製作的動畫預覽:
在下面的鏈接中,您可以找到本文中將要參考的所有代碼的實時預覽:
代碼庫中有兩個“頁面”。 index 包含上面 GIF 的所有代碼,simple 是本文中介紹的步驟的起點。
我用來將 GSAP 動畫轉換為 GIF 的方法涉及在補間的每次“更新”時捕獲 SVG 數據並將其寫入 HTML 畫布。補間完成後,我就可以將 SVG 數據轉換為光柵化圖像數據,modern-gif 可以使用它來創建動畫 GIF 的每一幀。
這是我在簡單示例中使用的代碼,我將用它來解釋從 GSAP 動畫創建動畫 GIF 所需的每個步驟:
<code class="language-html"><!DOCTYPE html> <meta charset="utf-8"> <title>Simple</title> <main> <svg id="svg" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 400 200" width="{400}" height="{200}" style="{{" border: solid red> <rect id="rect" x="0" y="75" width="50" height="50" fill="red"></rect> </svg> <canvas id="canvas" style="{{" border: solid blue width="{400}" height="{200}"></canvas> <img src="https://img.php.cn/upload/article/000/000/000/173898187373194.jpg" alt="How to Create Animated GIFs from GSAP Animations "> <h2>将 SVG 数据转换为光栅化数据</h2> <pre class="brush:php;toolbar:false"><code class="language-javascript">gsap.timeline({ onUpdate: () => { const xml = new XMLSerializer().serializeToString(svg); const src = `data:image/svg+xml;base64,${btoa(xml)}`; animationFrames.push(src); }, onComplete: () => { let inc = 0; const renderSvgDataToCanvas = () => { const virtualImage = new Image(); virtualImage.src = animationFrames[inc]; virtualImage.onload = () => { ctx.clearRect(0, 0, 400, 200); ctx.drawImage(virtualImage, 0, 0, 400, 200); canvasFrames.push(canvas.toDataURL('image/jpeg')); inc++; if (inc < animationFrames.length) { renderSvgDataToCanvas(); } else { //console.log(canvasFrames); //调试用 generateGif(); } }; }; renderSvgDataToCanvas(); }, }) .fromTo('#rect', { x: -50 }, { duration: 2, x: 350, ease: 'power.ease2' });</code>
此步驟稍微複雜一些,需要對 animationFrames 數組的每個索引執行一個操作。
通過使用遞歸函數 renderSvgDataToCanvas,我可以使用 animationFrames 數組中的圖像數據,將其寫入畫布。然後,通過使用 canvas.toDataURL('image/jpeg'),我可以將動畫每一幀的光柵化數據存儲在 canvasFrames 數組中。
如果已在 onComplete 函數中添加 console.log,則應在瀏覽器控制台中看到類似於以下內容。但是,這次請注意數據的 MIME 類型:它不是 svg xml,而是 image/jpeg。這對於我接下來要做的工作很重要。
這是最後一步,它涉及將 canvasFrames 數組的每個索引傳遞到 modern-gif。
<code class="language-html"><!DOCTYPE html> <meta charset="utf-8"> <title>Simple</title> <main> <svg id="svg" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 400 200" width="{400}" height="{200}" style="{{" border: solid red> <rect id="rect" x="0" y="75" width="50" height="50" fill="red"></rect> </svg> <canvas id="canvas" style="{{" border: solid blue width="{400}" height="{200}"></canvas> <img src="https://img.php.cn/upload/article/000/000/000/173898187373194.jpg" alt="How to Create Animated GIFs from GSAP Animations "> <h2>将 SVG 数据转换为光栅化数据</h2> <pre class="brush:php;toolbar:false"><code class="language-javascript">gsap.timeline({ onUpdate: () => { const xml = new XMLSerializer().serializeToString(svg); const src = `data:image/svg+xml;base64,${btoa(xml)}`; animationFrames.push(src); }, onComplete: () => { let inc = 0; const renderSvgDataToCanvas = () => { const virtualImage = new Image(); virtualImage.src = animationFrames[inc]; virtualImage.onload = () => { ctx.clearRect(0, 0, 400, 200); ctx.drawImage(virtualImage, 0, 0, 400, 200); canvasFrames.push(canvas.toDataURL('image/jpeg')); inc++; if (inc < animationFrames.length) { renderSvgDataToCanvas(); } else { //console.log(canvasFrames); //调试用 generateGif(); } }; }; renderSvgDataToCanvas(); }, }) .fromTo('#rect', { x: -50 }, { duration: 2, x: 350, ease: 'power.ease2' });</code>
使用 modernGif.encode,您可以將數據數組傳遞到 frames 並為每一幀定義延遲,我選擇添加 0 秒的延遲。
代碼的下一部分處理轉換 modernGif.ecode 數據並將其轉換為“另一個”MIME 類型,這次是 image/gif。
一旦我有了表示動畫 GIF 的最終“blob”數據,我就將其轉換為 URL,然後設置 image 和 link 元素的 src 和 href,以便我可以在瀏覽器中查看和下載 GIF。
您可能會注意到最終的GIF 運行速度相當慢,這是因為在瀏覽器中運行的動畫通常每秒播放60 幀(fps),而GIF 的幀速率通常要慢得多,為12 或24 fps。
為了“丟棄”一些動畫幀,我使用數組過濾器和 JavaScript 餘數運算符來確定索引是否可以被某個數字整除,在我的例子中,我選擇 6。不能被 6 整除的索引將從數組中過濾掉。生成的動畫 GIF 雖然有點笨拙,但播放速度會快得多。
我已經在 generateGif
函數中添加了 filter
方法來實現幀速率的調整。
就是這樣,您可以通過 HTML 畫布將 GSAP SVG 動畫轉換為動畫 GIF!
如果您對本文中描述的任何內容有任何疑問,請隨時在 Twitter/X 上找到我:@PaulieScanlon。
以上是如何從GSAP動畫創建動畫GIF的詳細內容。更多資訊請關注PHP中文網其他相關文章!