首页 > web前端 > js教程 > 如何从GSAP动画创建动画GIF

如何从GSAP动画创建动画GIF

Christopher Nolan
发布: 2025-02-08 10:31:09
原创
433 人浏览过

将 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 所需的每个步骤:

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='utf-8' />
  <title>Simple</title>
</head>
<body>
  <main>
    <svg id='svg'
      xmlns='http://www.w3.org/2000/svg'
      viewBox='0 0 400 200'
      width={400}
      height={200}
      style={{ border: '1px solid red' }}
    >
      <rect id='rect' x='0' y='75' width='50' height='50' fill='red'></rect>
    </svg>
    <canvas id='canvas' style={{ border: '1px 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 " /></p>
<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' });
登录后复制
登录后复制

此步骤稍微复杂一些,需要对 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。

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='utf-8' />
  <title>Simple</title>
</head>
<body>
  <main>
    <svg id='svg'
      xmlns='http://www.w3.org/2000/svg'
      viewBox='0 0 400 200'
      width={400}
      height={200}
      style={{ border: '1px solid red' }}
    >
      <rect id='rect' x='0' y='75' width='50' height='50' fill='red'></rect>
    </svg>
    <canvas id='canvas' style={{ border: '1px 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 " /></p>
<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' });
登录后复制
登录后复制

使用 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
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板