前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gsap太硬核了,实现复杂的交互动画

gsap太硬核了,实现复杂的交互动画

作者头像
Maic
发布2023-09-11 13:20:08
7730
发布2023-09-11 13:20:08
举报
文章被收录于专栏:Web技术学苑Web技术学苑

通常在C端交互上,产品与UI会在交互上提出一些比较炫酷的效果,面对视觉效果,通常来说,我们会借助第三方优秀的动画库来满足这些需求。通俗来说,就是我们并不是原生从0到1去实现,而是结合现有的库与框架帮我们高效的实现那些看似非常炫酷的效果。

今天介绍一个非常强大动画库,希望看完在业务中能带来一些思考和帮助

正文开始...

开始之前主要从以下几点介绍

  • 如何使用,开始一个最简单的gsap[1]
  • 连续动画如何实现
  • 如何暂停开启动画

registerEffect

现在有个需求,我想让一个动画按照顺序依次消失

代码语言:javascript
复制

 <div id="app">
  <p class="text1">欢迎关注</p>
  <p class="text2">公众号:Web技术学苑</p>
  <p class="text3">好好学习,天天向上</p>
</div>
<script src="./lib/gsap-latest-beta.min.js"></script>

然后我们写一段简短的动画

  • 注册动画
  • 初始化时间线
  • 按照顺序调用自定义动画
代码语言:javascript
复制

// 注册一个动画名
gsap.registerEffect({
        name: "myFade",
        effect: (targets, config) => {
            return gsap.to(targets, {duration: config.duration, opacity: 0,repeat: -1});
        },
        defaults: {duration: 2},
        extendTimeline: true
 });
 // 初始化一个timeline时间线
 const timeline = gsap.timeline();
 // 调用动画
 timeline.myFade(".text1", {duration: 1}).myFade(".text2", {duration: 2}).myFade(".text3");

最终效果

从以上我们发现text1,text2,text3都依次执行了我们自定义注册的myFade方法,如果我想每组动画都一样,那么需要怎么办呢?

  • 首先定义一组数据
代码语言:javascript
复制

const gsapData = [
    {
        name: "setRed",
        props: { opacity: 0.5, x: 300, yoyo: true, repeat: -1 }
    },
    {
        name: "setBlue",
        animate: 'from', 
        props: { opacity: 0.25, x: 300, yoyo: true,  }
    },
    {
        name: "setGreen",
        animate: 'fromTo', 
        props: { opacity: 0.1, x: 300}, 
        props2: { opacity: 1, x: 600, yoyo: true, repeat: -1  }
    }
]
  • 注册多个动画
代码语言:javascript
复制

gsapData.forEach(v => {
  gsap.registerEffect({
      name: v.name,
      defaults: { duration: 1 },
      extendTimeline: true,
      effect(target, config) {
          if (config.animate === "from") {
              return gsap.from(target, {
                  ...v.props,
                  ...config
              })
          } else if (config.animate === 'fromTo') {
              return gsap.fromTo(target, {
                  ...v.props,
                  ...config
              }, {...config.props2})
          } else {
              return gsap.to(target, {
                  ...v.props,
                  ...config
              })
          }
      }
  })
})
  • 执行动画
代码语言:javascript
复制

 const timeline = gsap.timeline();
timeline.setRed(".text1", {duration: 3}).setBlue(".text2", {duration: 1}).setGreen(".text3", 1)

最后的效果

暂停/开始动画

如果我想暂停动画或者开始动画,那么我需要手动控制

对应的html结构

代码语言:javascript
复制

<div id="app">
  <p class="text1">欢迎关注</p>
  <p class="text2">公众号:Web技术学苑</p>
  <p class="text3">好好学习,天天向上</p>
  <button id="stop">暂停</button>
  <button id="play">播放</button>
  <button id="reset">重置</button>
</div>
代码语言:javascript
复制

const stopBtn = document.getElementById('stop');
const playBtn = document.getElementById('play');
const resetBtn = document.getElementById('reset');
...
const timeline = gsap.timeline();
timeline.setRed(".text1", {duration: 3}).setBlue(".text2", {duration: 1}).setGreen(".text3", 1);

stopBtn.addEventListener('click', () => {
    timeline.pause();
})
playBtn.addEventListener('click', () => {
    timeline.play();
})

resetBtn.addEventListener('click', () => {
    timeline.reverse();
})

只要你调用了pauseplayreverse三个方法就行

react中如何卸载动画

比如我们在react中写了这一段动画

代码语言:javascript
复制

useEffect(() => {
  const stopBtn = document.getElementById('stop');
  const playBtn = document.getElementById('play');
  const resetBtn = document.getElementById('reset');
  ...
  const timeline = gsap.timeline();
  timeline.setRed(".text1", {duration: 3}).setBlue(".text2", {duration: 1}).setGreen(".text3", 1);
})

初略一看好像并没有什么问题,但实际上当我们组件销毁的时候,我们需要重置这些动画

其实你只需要这样就行

代码语言:javascript
复制

const ctx = gsap.context(() => {
  const stopBtn = document.getElementById('stop');
  const playBtn = document.getElementById('play');
  const resetBtn = document.getElementById('reset');
  ...
  const timeline = gsap.timeline();
  timeline.setRed(".text1", {duration: 3}).setBlue(".text2", {duration: 1}).setGreen(".text3", 1);
  return () => ctx.revert()
})

from and fromTo

在以上动画中我们有用到fromfromTo这两个执行动画

代码语言:javascript
复制

<div id="app">
  <p class="text">公众号:Web技术学苑</p>
</div>
<script src="./lib/gsap-latest-beta.min.js"></script>
<script>
    window.onload = function () {
        gsap.from(".text", {
            opacity: 0,
            y:100,
            duration: 1
        })
    }
</script>

上面这段动画意思就是从y100的位置,opacity0的状态持续时间1s钟开始执行

当我们使用fromTo时会是怎么样呢?

代码语言:javascript
复制

  <script>
  window.onload = function () {
      gsap.fromTo(".text", {
          opacity: 0
      }, {
      opacity: 1,
      duration: 2,
      delay: 1,
      x: 100,
      repeat:-1
    })
  }
</script>

从上面得知fromTo(className, start, end)其实是更加友好的控制动画的开始与结尾。

如果我们想手动控制动画执行呢

代码语言:javascript
复制

<div id="app">
  <p class="text">公众号:Web技术学苑</p>
  <button value="start" id="start"></button>
</div>
<script src="./lib/gsap-latest-beta.min.js"></script>
<script>
  window.onload = function () {
      const startDom = document.getElementById("start");
      let tween = gsap.fromTo(".text", {
          opacity: 0,
      }, {
          opacity: 1,
          duration: 2,
          delay: 1,
          x: 100,
          repeat:-1
      });
      tween.pause();
      startDom.addEventListener("click", () => {
          tween.seek(2);
          tween.progress(0.5);
          tween.play();
      })
  }
</script>

总结

  • 主要介绍了在gsap中比较常用的几个动画,如何使用registerEffect注册定义的动画,如何实现一个连续动画
  • 如何在react中卸载动画
  • 如何暂停一个动画,如何使用fromTofrom的动画
  • 本文示例code example[2]

参考资料

[1]gsap: https://greensock.com/docs/

[2]code example: https://github.com/maicFir/lessonNote/tree/master/javascript/23-gasp

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Web技术学苑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • registerEffect
  • 暂停/开始动画
  • react中如何卸载动画
  • from and fromTo
  • 总结
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档