使用 GSAP 在滚动上为 SVG 设置动画

Posted

技术标签:

【中文标题】使用 GSAP 在滚动上为 SVG 设置动画【英文标题】:Animate SVG on scroll using GSAP 【发布时间】:2021-05-06 17:43:47 【问题描述】:

GSAP 有这个ScrollTrigger 插件,可以在滚动时触发动画,我想使用它。

我已经有了一个可以工作的 SVG 动画(没有 GSAP):

<svg  >
  
  <linearGradient id="prog-mask" x1=0% x2="100%" y1="0%" y2="100%">
      <stop offset="0%"  stop-color="white" stop-opacity="1" />
      <stop offset="5%"  stop-color="white" stop-opacity="0">
      <animate attributeName="offset" values="0; 1" dur="2s" begin="0s" repeatCount="0" fill="freeze" />
      <animate attributeName="stop-opacity" values="0; 1" dur="2s" begin="2s" repeatCount="0" fill="freeze" />
    </stop>
 <stop offset="100%"  stop-color="white" stop-opacity="0" />
  </linearGradient>
  
  
  <mask id="prog-render">
  <rect x="0" y="0"   fill="url(#prog-mask)"/>     
  </mask>
  
  <pattern id="pattern-circles" x="0" y="0"   patternUnits="userSpaceOnUse">
    <circle cx="6" cy="6" r="3" stroke="red" stroke- fill="transparent">

      <animate attributeName="r" values="0; 5" dur="2s" begin="0s" repeatCount="0" fill="freeze" />
    </circle>

  </pattern>
  <!-- The canvas with our applied pattern -->
  <rect x="0" y="0"   fill="url(#pattern-circles)" mask="url(#prog-render)"/>
</svg>

如前所述,这个 SVG 动画没有与 GSAP 挂钩(如果它应该与 ScrollTrigger 插件一起使用,我认为这是必须的?)

这就是我尝试使用 GSAP 创建此动画的原因:

// 1. offset
gsap.to("#prog-mask stop:nth-child(2)", 
  duration: 2,
  attr:  offset: 1, fill: "freeze" ,
  repeat: 1,
  delay: 0
);

// 2. stop-opacity
gsap.to("#prog-mask stop:nth-child(2)", 
  duration: 5,
  attr:  stopOpacity: 1, fill: "freeze" ,
  repeat: 1,
  delay: 2
);

// 3. r = radius
gsap.to("circle", 
  duration: 5,
  attr:  r: 5, fill: "transparent" ,
  repeat: 0,
  delay: 0
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/gsap.min.js"></script>

<section>
<svg  >
  
  <linearGradient id="prog-mask" x1=0% x2="100%" y1="0%" y2="100%">
    
      <stop offset="0%" stop-color="white" stop-opacity="1" />
    
      <stop offset="5%"  stop-color="white" stop-opacity="0">
        
    <!-- <animate attributeName="offset" values="0; 1" dur="2s" begin="0s" repeatCount="0" fill="freeze" />
        
      <animate attributeName="stop-opacity" values="0; 1" dur="2s" begin="2s" repeatCount="0" fill="freeze" />-->
        
    </stop>
    
 <stop offset="100%"  stop-color="white" stop-opacity="0" />
  </linearGradient>
  
  
  <mask id="prog-render">
  <rect x="0" y="0"   fill="url(#prog-mask)"/>     
  </mask>
  
  <pattern id="pattern-circles" x="0" y="0"   patternUnits="userSpaceOnUse">
    
    <circle cx="6" cy="6" r="0" stroke="red" stroke- fill="transparent">

      <!--<animate attributeName="r" values="0; 5" dur="2s" begin="0s" repeatCount="0" fill="freeze" />-->
      
    </circle>

  </pattern>
  <!-- The canvas with our applied pattern -->
  <rect id="rect" x="0" y="0"   fill="url(#pattern-circles)" mask="url(#prog-render)"/>
</svg>
</section>

如您所知,我基本上只是尝试用一些 GSAP 代码替换三个 &lt;animate&gt; 元素。

此时点会立即显示出来,而以线性方式从左上角右下角显示。

另外,不知什么原因,整个矩形都是渐变的(其实我不介意这种效果,但我不明白为什么会这样?)。

    我是否必须在 GSAP 中为这个 SVG 设置动画才能使用 ScrollTrigger? 如何使用 GSAP 获得原始动画效果? 为什么在 GSAP 代码中会出现这种颜色渐变?

【问题讨论】:

【参考方案1】:

我是否必须在 GSAP 中为这个 SVG 设置动画才能使用 ScrollTrigger?

这取决于。如果您只想触发动画(SMIL 动画、CSS 动画、GSAP 动画等),您可以使用 ScrollTrigger 回调来执行此操作。

如果您想浏览动画,在 GSAP 中制作动画可能很有意义,因为它更容易更新。 AFAIK,您无法像使用 GSAP 那样告诉 SMIL 动画进入特定的进度点。

话虽如此,几乎所有制作 SVG 动画的人都经常建议在大多数情况下使用 JS 来制作 SVG 动画(有关 here 的更多信息)。

为什么在 GSAP 代码中会出现这种颜色渐变?

如果您使用开发工具查看 GSAP 版本的 SVG,您会发现它正在为 stopOpacity 属性而不是 stop-opacity 属性设置动画。在引号内使用常规属性名称(即不是驼峰式)可以解决此问题。

如何使用 GSAP 获得原始动画效果?

我会使用GSAP's timeline functionality 来设置这样的东西:Demo。

【讨论】:

以上是关于使用 GSAP 在滚动上为 SVG 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画

在 Internet Explorer 中的曲线路径上为 SVG 设置动画

GSAP库解决复杂动画

使用 GSAP scrollTrigger 缩放滚动图像

如何在鼠标滚轮滚动上为剪贴蒙版设置动画

SVG 交点设置颜色