GSAP-ScrollTrigger

4,517 阅读5分钟

GSPA:制作网页动画的工具,你可以使用GSAP对几乎所有JavaScript能接触到的东西进行动画处理,可以在任何框架中使用.
官网点这里

ScrollTrigger: gsap的插件,滚动触发动画。
cdn引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
其他下载方法看这里
选择需要的安装方式以及需要的插件,下面会显示引入方法。

image.png

scrollTrigger基本使用:

注册: gsap.registerPlugin(ScrollTrigger);

gsap.to('.box',{
  scrollTrigger: {
    trigger: '.box', // box元素进入视口时触发
    /*
     markers: 开发期间标记,显示动画滚动开始结束的位置,,markers: true 默认值: {startColor: "green", endColor: "red", fontSize: "16px", fontWeigth: "normal", indent: 0} 可自定义其样式。
    */
    markers: {startColor: "green", endColor: "red", fontSize: "12px"}, 
    start: 'top 30%', // 动画开始位置,滚动到距视口顶部30%
    end: 'top 20%', // 动画结束位置,滚动到距视口顶部20%
    // pin: true, // 在动画区域内,这个元素的位置固定不动,会在底部添加padding
    // pinSpacing: false, // pin的元素不在底部添加padding 
    /* 
    scrub: Boolean | Number 
     将动画的进度直接链接到滚动条上
    */
    scrub: true,
    
    onEnter: () => {
      console.log('滚动到start位置触发')
    },
    onEnterBack: () => {
      console.log('滚动超过end位置,再进入滚动区域触发')
    },
    onLeave: () => {
      console.log('滚出end位置时触发')
    },
    onLeaveBack: () => {
      console.log('滚出end位置,再滚回来超过start位置触发')
    },
    onUpdate: (self) => { // 在start和end区域内滚动位置改变时触发
      console.log(self)
    },
    /*
    toggleAction: onEnter onLeave onBackEnter onBackLeave
    在onEnter onLeave onBackEnter onBackLeave这四个位置的动画的方式
    默认是: play none none none
    可以使用的关键字有: play(播放), pause(暂停), resume(恢复), reset(重置), restart(重新开始), complete(完成), reverse(倒退), none(无).
     */
    toggleAction: "play pause resume reset",
    /* 
    toggleClass: String | Object 
    */
    toggleClass: {targets: '.box',className: 'box-pink'}
  },
  x: 100,// normal value
   /**
   * 可以通过函数获取值
   * @param {*} index :跟.box数量有关,如box有两个,index 分别为 0 1
   * @param {*} target : .box类的元素
   * @param {*} targets : 数组
   * @returns
   */
  y: function (index, target, targets) {
    //function-based value
    return index * 50;
  },
})

自定义实例(standalone)
可以用来切换类、在回调函数中做些事情等。

ScrollTrigger.create({
  trigger: '.box',
  markers: true,
  start: '50% 20%',
   // 切换类:className: 要切换成的类名;targets: 切换的目标
  toggleClass: {className: 'box-pink',targets: '.box'},
  onEnter: function() { console.log(1) }, 
  onEnterBack: function() {console.log(2) },
  onLeave: function() { console.log(3) } ,
  onUpdate:function(self){...}
});

// ScrollTrigger.defaults定义一些默认值
ScrollTrigger.defaults({
  toggleActions: "restart pause resume pause",
  scroller: ".container"
});

使用场景

gsap.utils.toArray(".box").forEach((box, i) => {
  ScrollTrigger.create({
    trigger: box,
    start: "center center", 
    pin: true, 
    pinSpacing: false 
  });
});

Timeline 时间轴

// 相同的东西可以写在defaults中,就不用在每个孩子中重复写了
let tl = gsap.timeline({defaults:{duration: 1}});
tl.to('.box',{x: 200})
  .to('.box',{y:60})
  .to('.box',{rotate: 90})

addLabel

  // 在相对于标签的位置插入动画实例(官网例子)
  var tl2 = gsap.timeline();
  tl2.to("#green", {x:750, duration:1})
 /*再timeline中添加label,标记重要位置,就可以再其他方法中引用这个label来进行其他操作
    如seek("myLabel") or add(myTween, "myLabel") or reverse("myLabel")
   */
   // 在timeline结束一秒后添加blueGreenSpin标签
  .addLabel("blueGreenSpin", "+=1")
  // 在blueGreenSpin标签处添加动画实例
  .to("#blue", {x:750, rotation:360, duration:2}, "blueGreenSpin") 
  // 在blueGreenSpin标签0.5s后插入Tween
  .to("#orange", {x:750, rotation:360, duration:2}, "blueGreenSpin+=0.5");
  
  // 还可以通过位置参数精确控制标签位置
  // 从timeline开始3s后精确的插入
   tl.addLabel("myLabel", 3);
  

和scrollTrigger结合使用:

let tl = gsap.timeline({
  scrollTrigger:{
    trigger: '.box',
    start: 'top center',
    scrub: true,
    duration:1,
  }
})
tl.to('.box',{x:100,y: 50,rotation: 360})

注:位置参数
官网滚动例子

其他有趣的东西

keyframes:对同一个对象触发多个动画时使用keyframes可以使代码保持简洁。

// 三种写法 官网例子
// Object keyframes
gsap.to('.box',{
  keyframes: [
    {x:100},
    {y:100,ease:'power2.out'},
    {x:0},
    {y:0,ease: 'power2.in'},
  ],
  rotate: 360,
  transformOrigin: 'center center',
  duration:4
})

// percentage keyframes
gsap.to('.box',{
  keyframes: {
    '25%':{x:200,y:0},
    '50%':{x:0,y:100},
    '75%':{x:100,y:100},
    '100%':{x:0,y:0},
    easeEach:"none"
  },
  rotate:360,
  ease: 'elastic',
  duration:4
})

// Array keyframes
gsap.to('.box',{
  keyframes:{
    x:[0,100,100,0,0],
    y:[0,0,100,100,0],
    easeEach:'power4.out'
  },
  duration:4
})


// 相当于css
.box {
  animation: square 4s ease-out 1s forwards;
}
@keyframes square {
  25% {
    transform: translateX(100px),translateY(0px);
  }
  50% {
    transform: translateX(100px),translateY(100px);
  }
  75% {
    transform: translateX(0px),translateY(100px);
  }
  100% {
    transform: translateX(0px),translateY(0px);
  }
}

stagger
给tween添加stagger可以让tween中的每个元素交错进行动画,而不是作为一个整体一起动画,这会让动画更有趣~

gsap.to('.box',{
  y: 100,
  duration: 0.5,
  // 设置这俩属性可以循环播放 repeat: -1, yoyo: true。设置到stagger里面,代表stagger无限循环(效果不一样哦)
  repeat: -1,
  yoyo: true,
  // stagger可以是number,objects,或function
  // number形式
  // stagger: 0.1,
  // objects形式
  stagger: {
    // 每个动画的时间
    each: 0.3, 
    // stagger开始的位置 number(开始元素的索引) | 'end' | 'start' | 'edges' | 'center' | 'random',
    from: "center", 
     // 所有元素交错出现(staggers)的总时间,如有10个元素,则每个元素stagger的时间是是 0.5 / 10 = 0.05s,也就是each=0.05s
    amount: 0.5,
    // [Array | 'auto'] 如果元素有多行多列,设置grid,gsap可以计算出stagger开始位置(from)近似值.如grid是[5,15]或auto,from是center,stagger会从第三行第八列这个元素开始向外扩展。
    grid: [5,15],
    // 不定义axis默认从x,y轴一起开始stagger,也可以设置'x'| 'y',代表一行一行或一列一列的进行。
    axis: 'y',
    // 动画的速率曲线
    ease: 'power2.in',
    // repeat: -1,
    // yoyo: true,
  }
  // function形式
  // stagger: function(index, target, list) {
  //   // your custom logic here. Return the delay from the start (not between each)
  //   return index * 0.1;
  // }
})

结语

官网很详细,建议看官网(有很多例子,还有视频教学)。