本教程详细介绍了如何将基于鼠标悬停事件的视差文本动画转换为平滑的自动滚动效果。通过替换传统的事件监听器,利用 `requestanimationframe` api优化动画性能,并结合javascript逻辑实现动画的持续更新和时长控制。文章提供了完整的代码示例,帮助开发者理解并实现高性能的web动画。
在深入实现自动滚动之前,我们首先需要理解原始视差文本动画的工作原理。这个动画通过CSS和JavaScript的协同作用,创造出文本层叠和深度移动的视觉效果。
原始的CSS代码定义了文本的视觉样式和动画行为:
原始的JavaScript代码非常简洁,其核心在于将用户鼠标的水平位置与CSS变量 --x 绑定:
const position = document.documentElement;
position.addEventListener("mousemove", (e) => {
position.style.setProperty("--x", e.clientX + "px");
});这段代码监听整个文档的 mousemove 事件。每当鼠标在页面上移动时,它就会获取鼠标当前的X坐标 (e.clientX),并将其值赋给CSS变量 --x。这样,鼠标的移动直接驱动了CSS中定义的视差和阴影效果。
为了将上述鼠标事件驱动的动画转换为自动播放,我们需要一个机制来持续地、平滑地更新 --x 变量,而无需用户交互。requestAnimationFrame 是实现这一目标的理想选择。
requestAnimationFrame (rAF) 是浏览器提供的一个API,用于请求浏览器在下一次重绘之前执行一个动画帧。它的优势在于:
我们将用一个循环函数配合 requestAnimationFrame 来逐步改变 --x 的值。具体步骤如下:
以下是实现自动视差文本滚动效果的完整代码。
const position = document.documentElement;
// 记录动画开始时间,以及动画帧计数器x
let startTime = Date.now();
let x = 0; // 用于控制水平偏移的像素值
const move = () => {
// 检查动画是否已运行超过10秒 (10000毫秒)
if (Date.now() - startTime > 10000) {
return; // 动画结束,停止递归调用
}
// 更新CSS变量 --x,使文本产生水平移动
// x++ 使得每次调用时 x 值递增1,实现连续滚动
position.style.setProperty("--x", (x++) + "px");
// 请求浏览器在下一帧执行move函数,实现动画循环
requestAnimationFrame(move);
};
// 启动动画
move();@import url('https://fonts.fonts.googleapis.com/css2?family=Poppins:wght@900&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "poppins"; font-weight: 900; } a { text-decoration: none; } section { position: relative; width: 100vw; height: 100vh; overflow: hidden; background: #111; } .text { position: relative; transform: skewY(350deg) translateY(-200px); animation: animatecolor 5s linear infinite; /* 颜色动画保持不变 */ } @keyframes animatecolor { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } } .text h2 { position: relative; width: 100%; font-size: 8em; color: #fff; pointer-events: none; line-height: 1em; white-space: nowrap; /* 关键的视差效果,依赖于 --x 变量 */ text-shadow: calc(var(--x)) 100px 0 rgba(255, 255, 255, 0.1); transform: translateX(calc(0% - var(--x) * var(--i))); } .text h2 span { color: #0f0; margin: 0 10px; } .text h2 span:nth-child(even) { color: transparent; -webkit-text-stroke: 2px #fff; }
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COM
WGRAPHISTE.COMWGRAPHISTE.COMWGRAPHISTE.COMWGRAPH