使用 GSAP 滚动 SVG 动画

问题描述

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,delay: 2
});

// 3. r = radius
gsap.to("circle",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 代码中会出现这种颜色渐变?

解决方法

我是否必须在 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...