GreenSock Animation Platform (GSAP) 是一个业界知名的动画库,它被1100多万个网站使用,有超过50%的获奖的网站都是用了它。不管是在原生环境中,还是任意的框架中,你可以使用GSAP去让非常多的东西动起来。不管你是想要去让UI界面产生交互动画,还是SVG图形产生动画,甚至是Threejs还是React组件,GSAP都可以轻松搞定!

创建一个动画

让我们先让一个class为'box'的HTML元素动起来

gsap.to(".box",{x:200})

动画方法 (Methods)

有四种Tween的动画方式

gsap.to() 这是一种最常用的动画,就是让元素从初始状态变化到目标状态。

gsap.from() 有点像to方法的逆向变化,就是让元素从目标状态变化到初始状态。

gsap.fromTo() 需要自己定义两个状态的数据,然后从前一个变化到后一个。

gsap.set() 直接设置成想要的状态,没有任何过度与动画效果。本质上就是duration为0的 .to 方法

目标元素 (target)

接下来我们需要去告诉GSAP去让什么元素变化。GSAP在底层实际上是使用了document.querySelector( )去选择元素,所以你可以用任何css选择器进行元素的选择。或者你也可以直接传入一个DOM元素或者一个数组

// 使用类名或者id名,其实css选择器都可以
gsap.to(".box", { x: 200 }); // 复杂一些的css选择器
gsap.to("section > .box", { x: 200 }); // 一个变量,其实是把获取到的DOM元素直接传进去
let box = document.querySelector(".box");
gsap.to(box, { x: 200 }) // 可以把dom元素放到数组里面一起传入
let square = document.querySelector(".square");
let circle = document.querySelector(".circle"); gsap.to([square, circle], { x: 200 })

对象数据 (variables)

这个对象包含着所有动画变化相关的信息。你可以设置任意的你想要发生变化的属性和值,或者一些特殊的会影响动画过程的一些属性,比如duration(动画时长),onComplete(动画完成时触发事件)或者repeat(动画重复的次数)

gsap.to(target, {
// 传入这样一个对象
// 这里面包含了需要进行变化的各种样式属性
x: 200,
rotation: 360,
// 以及变化过程的属性设置
duration: 2,
})

下面这个是Transform最常用相关的一些变化的属性和值的写法

GSAP CSS 作用
x:100 transform:translateX(100px) 水平移动 (px或者svg单位)
y:100 transform:translateY(100px) 垂直移动 (px或者svg单位)
xPercent:-50% transform:translateX(-50%) 横向移动 (元素本身宽度的百分比)
yPercent:-50% transform:translateY(-50%) 垂直移动 (元素本身高度的百分比)
rotation:360 transform:rotate(360deg) 旋转多少度
scale:2 transform:scale(2,2) 元素整体放大或缩小
skewX:45 transform:skewX(45deg) 元素倾斜
transformOrigin:"0% 100%" transform-origin: 0% 100%; 设置旋转中心点。这里设置的旋转中心点是元素左下角

特别的属性,下面是常用

属性 作用
duration 动画变化的时长(秒)默认是0.5
delay 动画变化开始前的延迟时长(秒),默认是0.5
repeat 动画的重复次数 设置为-1表示无数次
repeatDelay 重复延迟,重复之间的秒
repeatRefresh 重复刷新
yoyo 如果设置为ture,那么动画会在执行完之后再反向执行一次,就像悠悠球的效果。注意( repeat得设置大于1或者为-1才能看到效果。) 默认是false
stagger 是一个时间的设置(秒),如果有多个元素同时要被驱动,那么当这个属性设置了时间的值之后,元素们会被依次逐个驱动,间隔时长就是这个属性设置的时长
ease 动画过渡的运动曲线的设置,默认是"power1.out"
onComplete 动画结束时执行的回调函数
onStart 动画开始时调用
onUpdata 每次动画更新时调用(在动画处于活动状态时每帧调用)
onRepeat 每次动画重复时调用一次。
onReverseComplete 动画反转后再次到达其起点时调用

Timelines 时间线

时间线能让我们创建非常容易调节的、很灵活的顺序动画效果。下面就是一个简单的包含着三个tween动画的timeline实例效果。默认情况下,这些动画是依次添加的,他们在变化的时候也是依次执行,而且是一个执行完之后再下一个执行

// 创建一个Timeline类型的实例
let tl = gsap.timeline() // 把tween动画添加到timeline实例上,注意我们在用的是tl.to 而不是gsap.to
tl.to(".green", { x: 600, duration: 2 });
tl.to(".purple", { x: 600, duration: 1 });
tl.to(".orange", { x: 600, duration: 1 });

但是,如果我们想要在动画之间加一个停顿或者说间隔改怎么办呢?

let tl = gsap.timeline()

tl.to(".green", { x: 600, duration: 2 });
tl.to(".purple", { x: 600, duration: 1, delay: 1 }); // 在这里延迟1秒执行
tl.to(".orange", { x: 600, duration: 1 });

有一个方式就是我们可以给某个tween动画在启动前提添加一个delay。但是这样的话,一点都不灵活。又或者,如果我们想要实现动画之间在时间上重叠,又或者几个动画同时启动,这些该怎么实现呢?

GSAP Keyframes

如果你发现你写了好几个Tween动画,来让某个元素变化到一个目标状态,那么可能你是需要使用关键帧(KeyFrames)的方式来做了。关键帧动画能让元素的属性变化分段进行,同时又能保持代码的清爽整洁。

比如下面这个代码,同样一个变化效果,我们先用timeline的方式来实现,然后再用关键帧的方式来实现,显然关键帧的方式看起来简洁多了

// timeline
let tl = gsap.timeline();
tl.to(".box", { x: 100 })
.to(".box", { y: 100 })
.to(".box", { x: 0 })
.to(".box", { y: 0 }); // 用数组的方式
gsap.to(".box", {
keyframes: {
x: [0, 100, 100, 0, 0],
y: [0, 0, 100, 100, 0],
ease: "power1.inOut"
},
duration: 2
});

位置参数 Position Parameter

这个参数能帮我们方便的实现执行顺序和执行时间点的精确控制

let tl = gsap.timeline();
// 绿色方块会在整个时间线开始1秒后进行移动
tl.to(".green", { x: 600, duration: 1 }, 1); // 紫色方块会和之前一个添加的动画同时开始运动
tl.to(".purple", { x: 600, duration: 1 }, "<"); // 橘色方块会在之前所有动画都结束一秒后再开始运动
tl.to(".orange", { x: 600, duration: 1 }, "+=1");
  • 绝对时间(秒)的方式,以动画的启动时间点为参考,也就是整个时间线的起始点,比如使用一个数字3
  • '<'符号表示前一个添加到时间线上的动画的起始时间点。如果使用这个符号,那么动画会插入到前面一个动画的起始时间点位置
  • '>'符号表示前一个添加到时间线上的动画的结束时间点。如果使用这个符号,那么动画会插入到前面一个动画的结束时间点位置
  • '+=1' 表示当前时间线结束后再过1秒的时间点位置,相当于有个1秒的间隔
  • '-=1' 表示当前时间线结束时间点前1秒的时间点位置,相当于有个1秒的时间重叠
  • '<+=3' 表示前一个动画起始点后3秒的位置
  • '️' 和上面一个意思('<'和'>'直接跟数字,其实就是和'<+=3'或者'>+=3'是一样的意思)
  • '>-0.5' 前一个动画的结束时间点前0.5秒的时间点位置

注意,+= -= 这种是针对整个时间线动画来说的,而 >(结尾) 和 <(开头) 是针对前一个添加的动画来说的

基于百分比的复杂字符串形式。如果前缀是'+='或者'-=',那么表示的百分比是基于整个时间线已经添加的所有动画的总时长的。如果前缀是'<'或者'>',那么这个是基于前一个添加动画的时长的。注意,总时长是包含了重复或者yoyo效果的时长的

  • '-=25%' 放到前面已经添加的动画总时长的末尾25%的位置
  • '+=50%' 以前面所有动画总时长的50%作为时间间隔
  • '<25%' 以前一个动画启动时间点为时间点,放到前一个动画时长的25%的位置。它这个写法等同于'>-75%',这个就是以前一个动画的结束点为准,往前这个前动画的75%时长的时间点位置
  • '<+=25%' 以前一个动画启动时间点为时间点,向后放到全部动画总时长的25%的时间点的位置。使用百分比的时候,是否搭配'+='或者'-='是很重要的,当使用这两符号,用来计算百分比的时间长度都是整个时间线已经添加的动画的总时间长度
  • 'myLabel+=30%' 以myLabel标记位置为起始点,向后挪以整个以添加到时间线上的动画总时长的30%的时长作为插入的时间点
let tl = gsap.timeline();

tl.to(element, 1, {x: 200})
// 添加到整个时间线结束时间点后1秒,相当于是有了1秒的间隔
.to(element, {duration: 1, y: 200}, "+=1")
// 添加到整个时间线结束的时间点的前0.5秒,也就是有0.5秒的时间是和时间线原本的动画重叠
.to(element, {duration: 1, rotation: 360}, "-=0.5")
// 从时间线动画开头时间点往后6秒的时间点
.to(element, {duration: 1, scale: 4}, 6); // 在时间线2秒的时间点添加一个标记
tl.add("scene1", 2)
// 把动画提添加到 scene1 这个标记所在的时间点
.to(element, {duration: 4, x: 200}, "scene1")
// 把动画添加到 scene1 这个标记点往后3秒的时间点
.to(element, {duration: 1, opacity: 0}, "scene1+=3");

控制动画

比较常见的就是比如说我们想要点击某个按钮或有了某个交互行为之后才会让元素进行动画效果。那么控制动画的几个方法呢可以帮我们实现这个需求,在tween和timeline上都有这些方法,play,pause,reverse或者是加速变化

// 通过一个变量保存对Tween或者Timeline实例的引用
let tween = gsap.to("#logo", {duration: 1, x: 100});
tween.isActive() // 如果当前正在制作动画,则为 true // 播放
tween.play(); // 暂停
tween.pause(); // 恢复(继续)
tween.resume(); // 反向变化
tween.reverse(); // 直接切换到整个动画变化时长的0.5秒的时间点的状态
tween.seek(0.5); // 直接切换到整个变化过程的1/4的节点的状态
tween.progress(0.25); // 让运动减速到0.5倍
tween.timeScale(0.5); // 让变化加速到原来的2倍
tween.timeScale(2); // 直接销毁tween实例,让垃圾回收机制可以处理该实例所占用的内存
tween.kill();

ScrollTrigger滚动触发器

引入方式

<!-- CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
// ES Modules
import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger);

示例

 ScrollTrigger.create({
start:"top top",
end:"+=600",
trigger:".body", //滚动到视口元素
scrub:true, //将动画进度直接链接到滚动触发器的进度
pin:true, // 固定自身元素元素
// markers:true, //开启标注功能
animation:gsap.timeline()
.to(".green", { x: 300, opacity: 1, rotation: -360, duration: 2 })
.to(".purple", { x:0, opacity: 1, rotation: -360, duration: 2 },"-=2")
.to(".blue", { x: -300, opacity: 1, rotation: -360, duration: 2 },"-=2")
})

常用属性

属性 类型 说明
start 数字 | 方位名词 滚动触发器开启滚动的位置(数字,以像素为单位)[触发器][滚动条]
end 数字 | 方位名词 滚动触发器结束滚动的位置(数字,以像素为单位)[触发器][滚动条]
trigger Element | undefined 触发元素
animation Tween | Timeline | undefined 与滚动触发器实例关联的补间或时间线
scrub 布尔 | 数字 布尔值【 scrub:true 将动画进度直接链接到滚动触发器的进度 】
数字 - 播放头“赶上”所需的时间(以秒为单位),因此0将导致动画的播放头需要0.5秒才能赶上滚动条的位置,它非常适合平滑事件
toggleClass 字符串 | 对象 当ScrollTrigger切换活动/非活动时,向一个元素(或多个元素)添加/删除类
markers true 开启标注功能(更好看出滚动开始以及截止的地方 注意:不要在生产环境使用)
scroller Element | window 与滚动触发器关联的滚动元素(或窗口)。它是滚动条连接到滚动触发器的东西。默认是窗口(视口)
pin Element | undefined 固定元素。pin:true 就是自身元素,pin:'.xxx' 就是指定元素

ScrollToPlugin 滚动到插件

对窗口(如执行 window.scrollTo(x, y) )或 DOM 元素(如执行 myDiv.scrollTop = y; myDiv.scrollLeft = x; )的滚动位置进行动画处理。

注意:如果您想制作滚动驱动的动画,其中某些内容在某些滚动条位置被触发,请使用 ScrollTrigger 插件。

| 在 CSS 中使用 scroll-behavior: smooth 会导致冲突

引入方式

<!-- CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollToPlugin.min.js"></script>
// ES Modules
import { gsap } from "gsap"; import { ScrollToPlugin } from "gsap/ScrollToPlugin"; gsap.registerPlugin(ScrollToPlugin);
// 要将窗口滚动到特定位置,请使用窗口作为补间的目标,如下所示:
gsap.to(window, {duration: 2, scrollTo: "#someID"});

如果你想学习一些更深入的内容,我们这里有一些链接可供你学习:

GSAP 基础的更多相关文章

  1. gsap基础一[from,to,fromTo]

    学了几天基础了,感觉总算有点入了一个门的感觉啦,gasp不难,想想一年前我看着官网跟天文一样,今年真的进步很大,在外网发现学习的新世界, 自己的获取知识和查看api源码的能力也增强了许多,现在国内的气 ...

  2. GSAP JS基础教程--动画的控制及事件

    好多天没有写无博文啦,今天无聊就再写一下! 今天要讲的是TweenLite的一些事件以及,TweenLite动画的控制,TweenMax类似,请自行参考官方文档:http://api.greensoc ...

  3. GSAP JS基础教程--TweenLite操作元素的相关属性

    今天来学习用TweenLite操作元素的各种属性,以Div为例,其他元素的操作也是一样的,只是可能一些元素有它们的特殊属性,就可能不同罢了.   代码里用详细注释,我就不再重复啦,大家看代码就可以啦! ...

  4. GSAP JS基础教程--使用缓动函数

    今天来了解一下缓动easeing函数. 开始,如果你还没有GSAP的类包,可以到GreenSock的官网去下载最新版本的类包,或者直接点击这里​来下载 学习之前,先来准备一下:     <!DO ...

  5. GSAP JS基础教程--认识GSAP JS

    第一次写博文呢,这次写博客是因为应一位同学的要求,写一下GSAP JS的一个小教程.为什么说小呢?因为它实际上就是小,只是一个入门级的小教程.如果你想问:“那你为什么不写详细一点呢?”,我想说,说., ...

  6. 新手怎么学JS?JavaScript基础入门

    新手应该怎么学习JS?JavaScript入门 - 01 准备工作 在正式的学习JavaScript之前,我们先来学习一些小工具,帮助我们更好的学习和理解后面的内容. js代码位置 首先是如何编写Ja ...

  7. 前端动画框架GSAP框架随笔

    gsap是目前非常流行的前端动画框架,可以非常轻松构造出复杂的动画效果,这里仅对我实际使用中的一些例子进行总结 官网 示例 文章种所使用代码的在线示例 基础用法 // 声明一个滚动控制器 let ct ...

  8. java基础集合经典训练题

    第一题:要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10; 分析:*1.看到这个题目,或许你脑海中会想到很多方法,比如判 ...

  9. node-webkit 环境搭建与基础demo

    首先去github上面下载(地址),具体更具自己的系统,我的是windows,这里只给出windows的做法 下载windows x64版本 下载之后解压,得到以下东西 为了方便,我们直接在这个目录中 ...

  10. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. [C++核心编程] 4.2、类和对象-对象的初始化和清理

    文章目录 4.2 对象的初始化和清理 4.2.1 构造函数和析构函数 4.2.2 构造函数的分类及调用 4.2.3 拷贝构造函数调用时机 4.2.4 构造函数调用规则 4.2.5 深拷贝与浅拷贝 4. ...

  2. SSM之简单的CRUD

    文章目录 前言 项目介绍 项目代码介绍 数据库文件 源码介绍 代码展示 配置文件 业务逻辑代码 总结 前言 大家好呀,前面不是说最近在学习SSM么,可能学的不是那么深,不过刚刚开始,学完肯定需要先动手 ...

  3. 任务系统之Jenkins子任务

    今天下班即开启五一假期,早上临时定了行程去山东日照,原本计划下班就出发,但下班看了看导航,这一路红得发黑,于是决定还是晚点再走,现在有时间了,写篇简单的技术文章来提升下Blog逐渐降低的技术内容含量吧 ...

  4. JavaWeb 中 Filter过滤器

    Filter过滤器 每博一文案 师傅说:人生无坦途,累是必须的背负,看多了,人情人暖,走遍了离合聚散,有时会 在心里对自己说,我想,我是真的累了,小时候有读不完的书,长大后有赚不尽的力. 白天在外要奋 ...

  5. UML类图——类之间的关系

    关联关系(实线箭头) 是一种结构化关系,表示一类对象与另一类对象之间有联系.Java,c++,c#等编程语言在实现关联关系时,通常将一个类的对象作为另一个类的属性 - 双向关联 - 单向关联 - 自关 ...

  6. blob转string,同步调用

    问题背景 通过接口下载文件的时候,后端设置的responseHeader content-disposition: attachment;filename=文件名.xlsx content-type: ...

  7. stl------stack与queue

    stack与queue 一.stack 二.queue 例题:详见我的另一篇博文: 栈------表达式求值 http://www.cnblogs.com/Cloud-king/p/8453703.h ...

  8. 2022-08-13:以下go语言代码输出什么?A:[5 6 7 1 2 3 4] B:[1 2 3 4 5 6 7] C:[4 5 6 7 1 2 3]。 package main import

    2022-08-13:以下go语言代码输出什么?A:[5 6 7 1 2 3 4] B:[1 2 3 4 5 6 7] C:[4 5 6 7 1 2 3]. package main import ( ...

  9. 2020-12-05:go中,map的扩容流程是什么?

    福哥答案2020-12-05:[答案来自此链接:](https://www.bilibili.com/video/BV1Nr4y1w7aa?p=13) 源码位于runtime/map.go文件中的ha ...

  10. 2021-11-22:给定一个正数数组arr,表示每个小朋友的得分; 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果; 假设所有的小朋友坐

    2021-11-22:给定一个正数数组arr,表示每个小朋友的得分: 任何两个相邻的小朋友,如果得分一样,怎么分糖果无所谓,但如果得分不一样,分数大的一定要比分数少的多拿一些糖果: 假设所有的小朋友坐 ...