在React中使用gsap实现视频滚动播放动画效果

1,065 阅读2分钟

最新遇到一个动画的需求,要求当滚动到视频区域,视频内容固定在页面上,随着滚动来播放视频。在调研了几个动画库之后,选择gsap动画库来开发,先动手练习下,写了一个小的demo,下面为分享的代码。

现在我们开始介绍具体的安装和使用步骤:

一. 安装gsap

npm i gsap

二. 引入gsap库和它的触发插件ScrollTrigger

import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger';

三. gsap注册ScrollTrigger,在滚动时监听是否滚动到触发动画的区域

gsap.registerPlugin(ScrollTrigger);

四. 在react组件内给包含video元素的标签添加样式,以及资源路径,给外层容器和video绑定ref。

const sectionRef = useRef();
const videoRef = useRef();
<div className='screen section' ref={sectionRef}>
  <div className="videoBox">
    <video
      ref={videoRef}
      src={src}
      preload="auto"
      muted="muted"
      playsInline
      webkit-playsinline="true"
    />
  </div>
</div>

触发动画元素的宽度和高度要铺满整个屏幕,当滚动到当前元素时,固定在页面中间。

.scetion {
  width: 100%;
  height: 100vh;
  position: relative;
}

使用绝对定位让video的父容器保持在页面中间,同时设置overflow: hidden; 不让video在滚动时出现滚动的偏差, 同时video铺满整个容器。

.videoBox {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  overflow: hidden;
}
video {
  width: 100%;
  height: 100vh;
  object-fit: cover;
}

五. 在useEffect中等待视频加载成功,确保 video 在触发动画前已加载完成;给video外层容器创建滚动监听,同时在组件被卸载时,销毁所有的滚动监听。

  useEffect(() => {
    gsap.registerPlugin(ScrollTrigger);
    const section = sectionRef.current;
    const video = videoRef.current;
    // 确保 video 在触发动画前已加载完成
    video.onloadedmetadata = () => {
      const videoDuration = video.duration;
      ScrollTrigger.create({
        trigger: section,
        start: 'top top', // 当 section 顶部与视口顶部对齐时开始
        pin: true, // 固定视频
        scrub: 0.25, // 设置为 true 或一个数字,表示 scrub 的平滑度
        end: `+=${videoDuration * 1000}`, // 设置滚动结束位置,这里按视频长度设置
        onUpdate: (self) => {
          // 当触发器更新时,根据滚动比例来更新视频的 currentTime
          video.currentTime = videoDuration * self.progress;
        },
      });
    };

    return () => {
      // 清除所有的 ScrollTrigger 实例
      ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
    };
  }, [])

这样,一个简单的视频滚动动画的功能就完成了。