所有分类
  • 所有分类
  • Html5资源
  • React资源
  • Vue资源
  • Php资源
  • ‌小程序资源
  • Python资源

react gsap动画库使用详解之text文本动画

简介

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, // 动画持续时间s
      text: {
        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, // 动画持续时间s
      scrambleText: "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 { SplitTextPlugin } from "gsap/SplitTextPlugin";

gsap.registerPlugin(useGSAP, SplitTextPlugin);

const TextAnimation = () => {
  useGSAP(() => {
    const split = new SplitText(".gasp-text", {
      type: "chars",
      charsClass: "char",
    });

    gsap.to(".char", {
      duration: 2, // 动画持续时间s
      y: 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, // 显示触发标记,方便调试
  },
});
原文链接:https://code.ifrontend.net/archives/332,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?