gsap入门教程,实现复杂的交互动画

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

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

正文开始...

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

  • 如何使用,开始一个最简单的gasp

  • 连续动画如何实现

  • 如何暂停开启动画

registerEffect

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

html 复制代码
 <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>

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

  • 注册动画
  • 初始化时间线
  • 按照顺序调用自定义动画
js 复制代码
// 注册一个动画名
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方法,如果我想每组动画都一样,那么需要怎么办呢?

  • 首先定义一组数据
js 复制代码
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  }
    }
]
  • 注册多个动画
js 复制代码
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
              })
          }
      }
  })
})
  • 执行动画
js 复制代码
 const timeline = gsap.timeline();
timeline.setRed(".text1", {duration: 3}).setBlue(".text2", {duration: 1}).setGreen(".text3", 1)

最后的效果

暂停/开始动画

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

对应的html结构

html 复制代码
<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>
js 复制代码
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();
})

只要你调用了pause、play、reverse三个方法就行

react中如何卸载动画

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

js 复制代码
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);
})

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

其实你只需要这样就行

js 复制代码
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

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

html 复制代码
<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>

上面这段动画意思就是从y轴100的位置,opacity为0的状态持续时间1s钟开始执行

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

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

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

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

html 复制代码
<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>

总结

  • 主要介绍了在gasp中比较常用的几个动画,如何使用registerEffect注册定义的动画,如何实现一个连续动画

  • 如何在react中卸载动画

  • 如何暂停一个动画,如何使用fromTo与from的动画

  • 本文示例code example

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学4 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端