当我们浏览互联网时,我们经常会看到很多网站。当页面滚动条向下滑动时,有非常丰富的页面动画效果。相信很多朋友也好奇这样的网站效果是如何制作出来的。在这篇文章中,我们将深入学习如何使用GSAP库,为后面实现炫酷的动画效果打下基础。
首先,这种滚动效果与fullpage.js和Swiper.js的全屏翻页滚动效果不同。页面元素的位置极度依赖于滚动条的位置,因此需要监听滚动条事件;笔者在研究使用better-scroll.js、scrollReveal.js、iScroll.js等一系列插件后,发现这些插件并不能满足需求。
笔者曾经想过自己不依赖库也能实现类似的效果。不就是为了监听页面的滚动吗?但想想这么多元素在滚动时的动画效果所带来的性能问题以及调整大小后如何重新计算页面,这是不可能的。这是一个小问题,所以我放弃了这个不切实际的想法。
笔者在挖掘了很多网站的源码后,发现了一个很多网站都使用的动画库:GSAP;但奇怪的是,当我们在网站上搜索这个库时,发现这样一个易于使用的动画库的教程很少。信息不应该如此缺乏;但看到官网的全英文教程以及有时无法访问demo教程,以及各种有点难以理解的概念后,我似乎知道了原因。
由于我们想要实现的动画效果很多都依赖于GSAP,所以我们先来看看如何使用GSAP的教程。
总体规划计划
首先,我们需要知道这个库能做什么。 GreenSock动画平台(GSAP)是一个非常强大的动画平台,可以帮助我们实现大部分的动画需求,并构建适合所有主流浏览器的高性能应用程序。动画片; GSAP非常灵活,可以处理任何框架上可以通过js改变的页面所有元素。它不仅可以对div的css属性进行动画处理,还可以对SVG、React、Vue、WebGL进行动画处理,甚至可以与Threejs一起使用。
除了GSAP核心库之外,还有很多实用的插件。例如,结合ScrollTrigger插件,我们可以实现非常震撼的滚动触发效果;同时,无需担心响应能力。 GSAP确保项目快速、高效、顺利地响应。
动画属性
我们先来看一个简单的例子,首先将一个.box元素沿X轴移动200px;
gsap.to('.box', { x: 200 });
演示1
如果我们对.box元素进行元素检查,我们会发现GSAP实际上一直在修改transform属性,直到最终停在transform:translate(200px, 0px);我们继续回到上面的代码。
gsap.to
在上面的代码中,我们发现这段代码包含了三个层次的含义:函数、目标和变量;首先,目标是我们要移动的元素,它可以是 CSS 选择器、DOM 元素,甚至是数组字符串:
// CSS选择器
gsap.to(".box", { x: 200 });
gsap.to("#box1", { x: 200 });
// dom元素
const box = document.querySelector(".box");
gsap.to(box, { x: 200 })
// 元素数组
let square = document.querySelector(".square");
let circle = document.querySelector(".circle");
gsap.to([square, circle], { x: 200 })
然后是函数,动画函数有四种类型:
gsap.to:最常用的动画类型,从当前状态开始。
gsap.from:与.to相反,从一个状态开始到当前状态。
gsap.fromTo:可以自定义开始和结束状态。
gsap.set:立即设置属性,无动画效果。
我们直接看效果就可以明白这些函数的含义。
gsap.from(".box", {
x: 300,
});
演示3
gsap.fromTo(
".box",
{
x: 0,
y: 0,
},
{
x: 400,
y: 50,
},
);
演示4
gsap.set(".box", {
x: 400,
y: 50,
});
演示5
最后是变量对象。这个对象可以包含的信息类型比较丰富。它可以是您想要设置动画的任何 CSS 属性,也可以是影响动画性能的特殊属性,例如持续时间和重复次数。
gsap.to(target, {
x: 400,
y: 50,
rotation: 180,
// 特殊属性
duration: 3,
repeat: 2
});
演示6
GSAP可以对任何属性进行动画处理,没有明确的列表,包括CSS属性、自定义对象属性甚至CSS变量和复杂字符串。最常见的动画属性是变换和透明度。在动画中,transforms 属性消耗的性能最少。您可以使用它来移动元素、旋转或放大和缩小。因为它们不会影响页面的布局,更不用说重新排列页面,所以它们具有更好的性能。
❝
尽可能使用变换而不是布局属性(例如顶部、左侧或边距)以获得更流畅的动画体验。
❞
我们可能熟悉以下变换属性:
transform: rotate(360deg) translateX(10px) translateY(50%);
GSAP 提供以下缩写形式。上面的transforms属性可以直接简写为下面的属性(yPercent代表百分比元素的高度):
{ rotation: 360, x: 10, yPercent: 50 }
❝
GSAP支持将CSS属性转换为camelCase,例如background-color变为backgroundColor。
❞
通过上面的例子,我们还发现默认情况下GSAP会使用px和度数单位作为transform属性。例如{x:10,rotation:360}表示x轴10px,旋转360度;但有时我们想使用其他单位,例如 vw、弧度或相对单位。
x: 200, // 默认px
x: "+=200" // 相对值
x: '40vw', // 视窗单位
x: () => window.innerWidth / 2, // 函数计算
rotation: 360 // 默认角度
rotation: "1.25rad" // 使用弧度单位
GSAP的神奇之处在于,它不仅可以对dom元素进行动画处理,还可以对非dom元素进行动画处理,比如svg、js对象等;对于svg元素,我们添加attr属性来额外处理一些svg属性,例如宽度,高度,填充,描边,不透明度等。
演示8
gsap.to(".svgBox", {
duration: 2,
x: 100,
xPercent: -100,
// svg属性
attr: {
fill: "#8d3dae",
rx: 50,
},
});
即使我们为 js 对象设置动画,我们也不需要任何 dom 元素来为任何 js 对象的任何属性设置动画。 onUpdate函数用于监听动画的更新过程:
let obj = { myNum: 10, myColor: "red" };
gsap.to(obj, {
myNum: 200,
myColor: "blue",
onUpdate: () => console.log(obj.myNum, obj.myColor)
});
特殊性能
特殊属性用于调整动画的表现力。我们在上面使用了重复和持续时间。以下文档提供了一些常用的属性:
属性名称 描述
期间
动画时长(单位:秒)默认0.5秒
延迟
动画重复次数
溜溜球
布尔值,如果为 true,则所有其他动画都会向相反方向移动(如悠悠球)。默认为 false。
错开
每个目标动画开始之间的时间(秒)
舒适
控制动画过程中的变化率,默认“power1.out”
完成时
动画完成时的回调函数
Repeat属性是重复次数,会导致动画被执行多次;需要注意的是,如果我们填写的值为2,那么实际的动画数量为3,所以我们总结一下公式:真实的动作数量=重复属性+1。
❝
如果我们希望动画永远重复,请使用repeat: -1。
❞
Repeat一般与yoyo属性一起使用。当 yoyo 为 true 时,运动将在每个动画结束时反转。需要说明的是,一个运动周期包含正向运动和反向运动,并且反向运动也包含在运动次数中。中间。
gsap.to(".box", {
rotation: 360,
x: 300,
xPercent: -100,
duration: 2,
repeat: 2,
yoyo: true,
});
我们这里写的repeat是2次,在实际的动画中,正好是3次运动,1.5次循环往复运动。
延迟也很容易理解。动画开始时有一段延迟时间。如果后面有重复动画,则不会有延迟;如果我们想为任何后续重复运动添加延迟,我们可以使用repeatDelay属性。
gsap.to(".green", {
rotation: 360,
duration: 1,
delay: 1,
repeat: 1,
});
gsap.to(".purple", {
rotation: 360,
duration: 1,
repeat: 1,
repeatDelay: 1,
});
演示11
我们发现也是一共2次重复的旋转动作。绿色div动画开始前有停顿,但后续重复动作前没有停顿;而紫色div动画开始之前没有停顿,并且后续每次重复运动之前也没有停顿。有一个停顿,这就是repeatDelay的作用。
缓动速度曲线也是动画效果的一部分。我们可以看到,不同的速度曲线有不同的旋转效果。
gsap.to(".green", {
rotation: 360,
duration: 2,
ease: "none",
});
gsap.to(".purple", {
rotation: 360,
duration: 2,
ease: "bounce.out",
});
交错属性也是一个有趣的属性。我们可以用它来控制多个目标之间动画的延迟差异,形成奇妙而美丽的交错效果。
gsap.to(".box", {
duration: 0.5,
opacity: 0,
y: -100,
stagger: 0.1,
ease: "back.in",
});
演示13
例如,让div错开并消失;或者要对数组进行动画处理,您只需告诉 GSAP 有多少行和列。
gsap.to(".box", {
scale: 0.1,
y: 30,
yoyo: true,
repeat: -1,
ease: "power1.inOut",
delay: 1,
stagger: {
amount: 1.5,
grid: "auto",
from: "center",
},
});
demo14 时间线 时间线
我们的动画经常会遇到多个对象。虽然我们可以利用上面的delay进行简单的控制来延迟对象的动画开始时间;但如果中间一个物体的动画执行时间突然延长,那么其后面的所有物体的动画时间都需要手动延迟,这是非常不方便的;因此我们需要引入时间线的概念。
❝
时间线是GSAP最重要的概念之一
❞
我们通过gsap.timeline()创建一个时间轴,然后通过时间轴控制每个动画的顺序执行;这样,即使我们中间修改了一个动画的时长,也不会影响后续的时间轴。
const t1 = gsap.timeline();
t1.to(".green", {
x: 600,
duration: 2,
});
t1.to(".purple", {
x: 600,
duration: 1,
});
t1.to(".orange", {
x: 600,
duration: 1,
});
演示15
但如果我们想在一个动画开始的同时执行另一个动画,除了创建一个额外的时间轴之外,我们还可以在 to 函数后面添加一些小参数来进行精确控制。
const t1 = gsap.timeline();
t1.to(".red", { x: 400,duration: 1 });
// 在1秒开始插入动画(绝对值)
t1.to(".green", { x: 400, duration: 1 }, 1);
// 在上个动画的开始插入动画
t1.to(".purple", { x: 400, duration: 1 }, "<");
// 在最后一个动画结束后一秒插入动画
t1.to(".orange", { x: 400, duration: 1 }, "+=1");
演示16
了解上面代码中的这些小参数可以帮助我们构建许多复杂而精美的动画效果,让我们可以在任何时间点执行任何动画效果;上面的例子乍一看可能不是那么容易理解,但是没关系,我们一点一点地理解。
虽然上面我们使用了gsap.to作为例子,但是其他函数如from()、fromTo()、add()等也是适用的;需要注意的是,这些参数跟随变量对象,因此函数的代码结构如下:
❝
.method(目标、变量、位置)
❞
如果我们对这些参数进行简单的分类,会更容易理解。其实主要有以下几种:
绝对值表示动画以绝对秒数执行。例如,上面演示中的绿色元素在 1 秒时执行动画;该符号表示上一个动画结束的时间。用法类似,这里不再赘述。
相对符号表示动画结束的时间点。 +=1表示上一个动画结束后1秒,-=2表示上一个动画结束前2秒。
标签值很容易理解。在某个时间点插入一个标签,并在该标签之前或之后的某个时间执行。我们来看看它的用法:
const t1 = gsap.timeline();
t1.to(".green", { x: 400, duration: 1 })
.add("myLabel", 2)
.to(".purple", { x: 400, duration: 1 }, "myLabel+=1")
.to(".orange",{ x: 400, duration: 1 }, "myLabel-=1");
通过gsap.add函数,我们在2秒处放置一个myLabel标志,后面使用myLabel+=1和myLabel-=1来控制相对于这个标志的时间。
演示18
不同时间线中的动画可能具有相同的特殊属性,例如重复和延迟。我们可以在时间线创建函数中统一设置,避免重复:
const tl = gsap.timeline({ repeat: 1, repeatDelay: 1, yoyo: true });
tl.to(".green", { rotation: 360 })
.to(".purple", { rotation: 360 })
.to(".orange", { rotation: 360 });
如果你发现自己多次重复使用某个属性,比如x、scale、duration等,我们可以使用defaults属性。添加到 defaults 属性的任何参数都将由以下函数继承。
const tl = gsap.timeline({
defaults: {
scale: 1.2,
duration: 2,
},
});
tl.to(".green", {
x: 200,
})
.to(".purple", {
x: 400,
})
.to(".orange", {
x: 600,
});
回调函数
某些情况下,我们需要在动画开始、过程、结束的某个时间点执行回调操作。 gsap提供了以下回调函数:
gsap.to(".class", {
x: 100,
onComplete: () => console.log("the tween is complete")
}
// 时间线所有动画结束时调用
gsap.timeline({onComplete: tlComplete});
function tlComplete() {
console.log("the tl is complete");
// ...
}
滚动触发
现在我们对gsap的基本用法有了一定的了解,我们来看看插件的使用;插件可以帮助我们扩展动画的高级功能,让动画表现更加丰富;我们主要了解ScrollTrigger的使用。
我们先看一下ScrollTrigger的简单用法。
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
gsap.to(".green", {
rotation: 360,
scale: 1.5,
backgroundColor: "red",
scrollTrigger: {
trigger: ".green",
scrub: true,
},
});
gsap.to(".purple", {
rotation: 360,
scale: 1.5,
backgroundColor: "red",
scrollTrigger: {
trigger: ".purple",
scrub: 1,
},
});
当然,使用插件之前必须先注册该插件。使用 gsap.registerPlugin 注册 ScrollTrigger。不然我们下面操作的时候会发现没有效果。
在to函数中,我们添加了一个scrollTrigger属性。 Trigger表示当前动画触发的元素。这很容易理解。我们使用当前元素;是否标记标记,scrub表示是否将动画效果链接到滚动条。作为滚动条的平滑处理;如果为 false(默认),动画将在元素出现在窗口中时直接触发。如果为真,动画将会平滑。我们看一下效果:
❝
Scrub也可以是一个具体值,表示滚动条动画延迟多少秒;例如这里的1表示延迟动画的执行1秒。
❞
当我们滚动浏览器时,我们可以使用pin属性将元素固定在某个位置; pin 可以是 css 选择器字符串、布尔值或直接 dom 元素;如果为true,则直接固定当前动画元素;我们这里用pin来固定紫色元素的起始位置:
gsap.to(".green", {
x: 400,
duration: 2,
scrollTrigger: {
trigger: ".green",
pin: ".purple",
},
});
开始和结束
start和end属性用于确定滚动触发元素的起始位置,可以是字符串、值或函数。两者的用法类似。我们以开始为例; start的默认值是“top Bottom”,表示当触发对象(trigger)的顶部(top)接触到浏览器的底部(bottom)时;我们来看看标记打开时的触发位置。
开始和结束默认触发位置
我们看到滚动条起始线是浏览器窗口的边界线。当浏览器向下滚动时,当这一行滚动到对象的起始行时,触发动画效果;同理,向上滚动时,当滚动结束线碰到end时,动画结束。
起始值看起来很奇怪并且难以理解。其实我们可以拆成两部分来看;第一个顶部值表示对象的上边界。同样,我们可以将其设置为底部(对象的下边界)和中心(对象)。 middle)或特定值(100px,80%),即控制对象旁边的起始线。
第二个值表示由浏览器窗口滚动触发的滚动条开始线。 Bottom 代表窗口的底部。我们还可以将其设置为top或center或数值,以及百分比(例如80%,代表整个窗口高度的80%),甚至是相对位置,例如bottom-=100px。
切换类
有些情况下,我们并不想要gsap动画,而是想使用自己自定义的css类名来实现某些动画效果。 toggleClass 属性允许我们在触发的元素上添加或删除这些类名,从它的名字也可以看出它处理类名;可以是字符串,如toggleClass: "active",表示要添加/删除的类名。
toggleClass 也可以是一个对象,您可以在其他元素上添加/删除类名,例如:
toggleClass: {targets: ".my-selector", className: "active"}
我们可以将ScrollTrigger与时间轴结合起来创建动画。
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".wrap",
scrub: true,
},
});
tl.to(".green", {
x: 200,
});
tl.to(".purple", {
x: 400,
});
总结
本文所有GSAP使用教程大致到这里就结束了。本文涉及一些动画概念。如果有任何不准确的地方,请纠正我。
- EOF -
推荐阅读 点击标题可跳转
觉得本文对你有帮助?请分享给更多人
推荐关注「前端大全」,提升前端技能
点赞和在看就是最大的支持❤️
本网站每日更新互联网创业教程,一年会员只需98,全站资源免费下载点击查看会员权益