简介
gsap 高性能的 JavaScript 动画库,在现代网页设计和开发中运用。
安装
npm install gsap
React 框架中使用
可以考滤使用 react-gsap-enhancer
库,或者 @gasp/react
。
类组件使用 react-gsap-enhancer
高阶组件,函数组件使用 @gasp/react
自定义 Hook。
npm install react-gsap-enhancer
#or
yarn add react-gsap-enhancer
TextPlugin
逐个单词更新
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";
import { TextPlugin } from "gsap/dist/TextPlugin";gsap.registerPlugin(useGSAP, TextPlugin);const TextAnimation = () => {useGSAP(() => {gsap.to(".gasp-text", {duration: 2, // 动画持续时间stext: {value: "Your new text", // 新文本delimiter: " ", // 折分文本的字符newClass: "text-red-500", // 新文本样式},});});return (<div><h1 className="gasp-text">Hello World!</h1></div>);
};export default TextAnimation;
ScrambleTextPlugin
解码字符串
使用随机字符(默认大写,但您可以定义小写或一组自定义字符)打乱 DOM 元素中的文本,并定期刷新新的随机字符,同时在补间过程中(默认从左到右)逐渐显示新文本(或原始文本)。视觉上,它看起来像计算机正在解码一串文本。非常适合用于滚动效果。
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";
import { ScrambleTextPlugin } from "gsap/ScrambleTextPlugin";gsap.registerPlugin(useGSAP, ScrambleTextPlugin);const TextAnimation = () => {useGSAP(() => {gsap.to(".gasp-text", {duration: 2, // 动画持续时间sscrambleText: "This is new text",});});return (<div><h1 className="gasp-text">Hello World!</h1></div>);
};export default TextAnimation;
SplitText
分割文本
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";
import { SplitText } from "gsap/SplitText";gsap.registerPlugin(useGSAP, SplitText);const TextAnimation = () => {useGSAP(() => {const _split = new SplitText(".gasp-text", {type: "chars",charsClass: "char",});gsap.to(".char", {duration: 2, // 动画持续时间sy: 100,});});return (<div><h1 className="gasp-text">Hello World!</h1></div>);
};export default TextAnimation;
综合示例
目前的示例效果都是单个元素,如果多个元素,按顺序执行的效果处理方式应该如何了?这个就需要使用创建动画时间线方法。
timeline 动画时间线
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";gsap.registerPlugin(useGSAP);const TextAnimation = () => {useGSAP(() => {// 设置初始状态gsap.set([".timeline-1", ".timeline-2", ".timeline-3"], {opacity: 0,y: 20,});// 创建动画时间线const tl = gsap.timeline({defaults: {duration: 1,ease: "power2.inOut",},});tl.to(".timeline-1", {opacity: 1,y: 0,stagger: 0.1,ease: "power2.inOut",duration: 1,}).to(".timeline-2", {opacity: 1,y: 0,stagger: 0.1,ease: "power2.inOut",duration: 1,}).to(".timeline-3", {opacity: 1,y: 0,stagger: 0.1,ease: "power2.inOut",duration: 1,});});return (<div><div className="timeline-1">Join our</div><div className="timeline-2">growing</div><div className="timeline-3">community</div></div>);
};export default TextAnimation;
时间线和 SplitText 同时运用
在逐块元素显示的基础上,每块元素并逐个单词显示
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";
import { SplitText } from "gsap/SplitText";gsap.registerPlugin(useGSAP, SplitText);const TextAnimation = () => {useGSAP(() => {// 创建动画时间线const tl = gsap.timeline({defaults: {duration: 1,ease: "power2.inOut",},});// 为每个时间线元素创建 SplitText 实例const split1 = SplitText.create(".timeline-1", { type: "words" });const split2 = SplitText.create(".timeline-2", { type: "words" });const split3 = SplitText.create(".timeline-3", { type: "words" });// 设置分割后的单词初始状态gsap.set([split1.words, split2.words, split3.words], {opacity: 0,y: 20,});tl.to(".timeline-1", {opacity: 1,y: 0,duration: 0.5,onComplete: () => {gsap.to(split1.words, {opacity: 1,y: 0,stagger: 0.1,duration: 0.5,});},}).to(".timeline-2", {opacity: 1,y: 0,duration: 0.5,onComplete: () => {gsap.to(split2.words, {opacity: 1,y: 0,stagger: 0.1,duration: 0.5,});},}).to(".timeline-3", {opacity: 1,y: 0,duration: 0.5,onComplete: () => {gsap.to(split3.words, {opacity: 1,y: 0,stagger: 0.1,duration: 0.5,});},});});return (<div><div className="timeline-1">Join our growing community</div><div className="timeline-2">Hello World</div><div className="timeline-3">A New Day</div></div>);
};export default TextAnimation;
以上动画都是页面加载时执行,如果需要做到页面滚动到指定位置时执行,可以使用 ScrollTrigger 插件。
ScrollTrigger 视窗进入离开
import React from "react";
import { gsap } from "gsap";
import { useGSAP } from "@gsap/react";
import { SplitText } from "gsap/SplitText";
import { ScrollTrigger } from "gsap/ScrollTrigger";gsap.registerPlugin(useGSAP, SplitText, ScrollTrigger);const TextAnimation = () => {useGSAP(() => {// 为每个时间线元素创建 SplitText 实例const split1 = SplitText.create(".timeline-1", { type: "words" });const split2 = SplitText.create(".timeline-2", { type: "words" });const split3 = SplitText.create(".timeline-3", { type: "words" });// 设置分割后的单词初始状态gsap.set([split1.words, split2.words, split3.words], {opacity: 0,y: 20,});// 设置时间线元素的初始状态gsap.set([".timeline-1", ".timeline-2", ".timeline-3"], {opacity: 0,y: 20,});// 创建动画时间线const tl = gsap.timeline({scrollTrigger: {trigger: ".page2",start: "top 80%", // 当页面顶部到达视窗80%位置时触发end: "bottom 20%", // 当页面底部到达视窗20%位置时结束toggleActions: "play none none none", // 只播放一次markers: true, // 显示触发标记,方便调试},});// play reverse play reverse// 添加动画序列tl.to(".timeline-1", {opacity: 1,y: 0,duration: 0.5,ease: "power2.out",}).to(split1.words,{opacity: 1,y: 0,stagger: 0.1,duration: 0.3,ease: "power2.out",},"-=0.2") // 稍微提前开始单词动画.to(".timeline-2", {opacity: 1,y: 0,duration: 0.5,ease: "power2.out",}).to(split2.words,{opacity: 1,y: 0,stagger: 0.1,duration: 0.3,ease: "power2.out",},"-=0.2").to(".timeline-3", {opacity: 1,y: 0,duration: 0.5,ease: "power2.out",}).to(split3.words,{opacity: 1,y: 0,stagger: 0.1,duration: 0.3,ease: "power2.out",},"-=0.2");});return (<div><div className="page1 h-[2000px]">高度: 2000px</div><div className="page2"><div className="timeline-1">Join our growing community</div><div className="timeline-2">Hello World</div><div className="timeline-3">A New Day</div></div></div>);
};export default TextAnimation;
以上代码动画执行一次之后再次进入视窗并不会再次执行. 如果需要重复执行也很简单
const tl = gsap.timeline({scrollTrigger: {start: "top bottom-=100", // 当页面顶部到达视窗底部-100px位置时触发toggleActions: "play none none reverse", // 反复执行},
});
为了更好的调试,可以开启 markers: true,这样会在浏览器中显示触发标记,更加直观。
const tl = gsap.timeline({scrollTrigger: {markers: true, // 显示触发标记,方便调试},
});
更多使用示例