首頁 >web前端 >js教程 >如何從GSAP動畫創建動畫GIF

如何從GSAP動畫創建動畫GIF

Christopher Nolan
Christopher Nolan原創
2025-02-08 10:31:09413瀏覽

將 GSAP 動畫轉換為動畫 GIF:使用 modern-gif 的分步指南

關鍵要點

  • 可以使用一個過程將 GSAP 動畫轉換為動畫 GIF,該過程涉及在每次調整補間時捕獲 SVG 數據並將其寫入 HTML 畫布。然後,可以將此 SVG 數據轉換為光柵化圖像數據,然後由 modern-gif 用於創建動畫 GIF 的每一幀。
  • 轉換過程涉及多個步驟,包括捕獲 SVG 數據、將 SVG 數據轉換為光柵化數據,最後將光柵化數據轉換為 GIF。每個步驟都涉及特定的代碼修改和使用數組來存儲捕獲和轉換的數據。
  • 由於瀏覽器動畫和 GIF 之間的幀速率通常不同,因此最終 GIF 的幀速率可能比原始動畫慢。為了加快 GIF 的速度,可以使用數組過濾器和 JavaScript 餘數運算符來確定索引是否可以被某個數字整除,從而丟棄一些幀。

本文將解釋如何使用 modern-gif 將使用 GSAP 創建的動畫轉換為動畫 GIF。

以下是一個我之前製作的動畫預覽:

How to Create Animated GIFs from GSAP Animations

在下面的鏈接中,您可以找到本文中將要參考的所有代碼的實時預覽:

  • ? 預覽:
    • 索引:gsap-animation-to-gif.netlify.app
    • 簡易版:gsap-animation-to-gif.netlify.app/simple
  • ⚙️ 代碼庫:github.com/PaulieScanlon/gsap-animation-to-gif

代碼庫中有兩個“頁面”。 index 包含上面 GIF 的所有代碼,simple 是本文中介紹的步驟的起點。

如何將 GSAP 動畫轉換為 GIF

我用來將 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。這對於我接下來要做的工作很重要。

How to Create Animated GIFs from GSAP Animations

將光柵化數據轉換為 GIF

這是最後一步,它涉及將 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。

How to Create Animated GIFs from GSAP Animations

幀速率

您可能會注意到最終的GIF 運行速度相當慢,這是因為在瀏覽器中運行的動畫通常每秒播放60 幀(fps),而GIF 的幀速率通常要慢得多,為12 或24 fps。

為了“丟棄”一些動畫幀,我使用數組過濾器和 JavaScript 餘數運算符來確定索引是否可以被某個數字整除,在我的例子中,我選擇 6。不能被 6 整除的索引將從數組中過濾掉。生成的動畫 GIF 雖然有點笨拙,但播放速度會快得多。

我已經在 generateGif 函數中添加了 filter 方法來實現幀速率的調整。

就是這樣,您可以通過 HTML 畫布將 GSAP SVG 動畫轉換為動畫 GIF!

如果您對本文中描述的任何內容有任何疑問,請隨時在 Twitter/X 上找到我:@PaulieScanlon。

以上是如何從GSAP動畫創建動畫GIF的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn