最新遇到一个动画的需求,要求当滚动到视频区域,视频内容固定在页面上,随着滚动来播放视频。在调研了几个动画库之后,选择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());
};
}, [])
这样,一个简单的视频滚动动画的功能就完成了。