使用 GSAP 在滚动上动画 SVG

Animate SVG on scroll using GSAP

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

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

<svg width="596" height="255">
  
  <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" width="100%" height="100%" fill="url(#prog-mask)"/>     
  </mask>
  
  <pattern id="pattern-circles" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
    <circle cx="6" cy="6" r="3" stroke="red" stroke-width="2" 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" width="100%" height="100%" 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 width="596" height="255">
  
  <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" width="100%" height="100%" fill="url(#prog-mask)"/>     
  </mask>
  
  <pattern id="pattern-circles" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
    
    <circle cx="6" cy="6" r="0" stroke="red" stroke-width="1.5" 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" width="100%" height="100%" fill="url(#pattern-circles)" mask="url(#prog-render)"/>
</svg>
</section>

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

此时点立即显示出来,左上角底部以线性方式显示对.

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

  1. 我是否必须在 GSAP 中制作此 SVG 动画才能使用 ScrollTrigger?
  2. 如何使用 GSAP 获取原始动画结果?
  3. 为什么在 GSAP 代码中会出现这种颜色渐变?

Do I have to animate this SVG in GSAP to use ScrollTrigger?

视情况而定。如果您只想触发动画(SMIL 动画、CSS 动画、GSAP 动画等),您可以使用 ScrollTrigger 回调来实现。

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

话虽这么说,几乎每个制作 SVG 动画的人都经常建议在大多数情况下使用 JS 制作 SVG 动画(更多信息 here)。

Why does this color gradient happen in the GSAP code?

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

How can I get the original animation result using GSAP?

我会利用 GSAP's timeline functionality to set things up like this: Demo