写点什么

螺旋文字滚动特效源码解析

作者:南城FE
  • 2024-07-31
    广东
  • 本文字数:2102 字

    阅读完需:约 7 分钟


如图所示,今天看到一个很炫酷的双文字螺旋滚动特效,两行文字呈螺旋状变化,在网站中这样的效果对用户很有吸引力。本文将基于原网站解析如何实现这个炫酷的效果,基于这个动图可以分析出需要实现的要点:


  • 文字呈螺旋状滚动

  • 滚动过程中文字大小变化

  • 动画过程无缝链接

  • 两行文字滚动

实现过程

文字展示

为了方便更改文案将文案定义变量,通过 JS 代码动态创建 DOM,定义文案、螺旋的角度以及动画的持续时间:


const words = "螺旋文字滚动特效";const ANGLE = 360;const ANIMATION_DURATION = 4000;
复制代码


将文案创建元素添加到页面中:


const characters = words.split("").forEach((char, i) => {  const createElement = (offset) => {    const div = document.createElement("div");    div.innerText = char;    div.classList.add("character");    div.setAttribute("data-offset", offset);    return div;  };
document.querySelector("#spiral").append(createElement(0)); document .querySelector("#spiral2") .append(createElement(-1 * (ANIMATION_DURATION / 2)));});
复制代码


因为有 2 行文字滚动,所以这里添加了 2 个spiral


<div id="spiral" class="spiral"></div><div id="spiral2" class="spiral"></div>
复制代码


spiral 设置flex布局,此时的页面效果如下:


.spiral{  display: flex;  align-items: center;  gap: 10px;  position: absolute;  color: #e0ecef;  font-family: "sans-serif";}
复制代码


让文字动起来

这里的动画基于CSS Houdini @property实现,首先定义一个自定义属性--angle,接受角度值,初始值为 0 度。


@property --angle {    syntax: '<angle>';    initial-value: 0deg;    inherits: false;}
复制代码


设置关键帧动画,修改定义的--angle属性从 0 度旋转到 360 度。


@keyframes spiral {    0% { --angle: 0deg; }    100% { --angle: 360deg; }}
复制代码


给每个文字的增加animation动画关联定义的关键帧动画spiral


.character{  transform: translateY(calc(sin(var(--angle)) * 100px)) scale(calc(cos(var(--angle)) * 0.5 + 0.5));  animation: spiral 4s linear infinite;}
复制代码


重点代码transform变换,使用transform属性结合calc函数和三角函数来实现 Y 轴的正弦波形偏移和缩放效果。


同时在动画中应用了前面定义的spiral动画。结合这两个函数,transform 属性效果如下:


  • Y 轴位移: 元素根据 --angle 的值在 Y 轴上上下移动,形成波动效果。

  • 缩放效果: 元素的大小根据 --angle 的值进行动态缩放,形成从小到大或从大到小的变化。


此时的动画效果:


螺旋滚动

此时我们的文字已经滚动起来了,只需要最后一步关键的代码就可以实现螺旋滚动效果,仔细看原始效果就能发现其实每个文字滚动的动画轨迹都是一样的,唯一的区别就是执行的动画延迟时间不同,形成了一个波动起伏的效果。


增加延迟动画 CSS,由于我们的文字是通过 JS 创建的,所以需要在 createElement 中增加以下代码即可,根据动画持续时间和当前文字索引计算延迟时间:


div.style.animationDelay = `-${i * (ANIMATION_DURATION / 16) - offset}ms`
复制代码


由于 --angle 设置了关键帧动画,是一个动态变化的变量,这段代码会使得元素在页面上呈现出螺旋或波动的动画效果,增强视觉吸引力。


此时我们的动画效果基本就完成了,如下所示:


兼容火狐

由于 Firefox 不支持@property动画,原作者写了火狐兼容代码,使用 JavaScript 来实现动画效果。


定义一个animation动画函数,使用 requestAnimationFrame 方法实现平滑的动画效果。


const animation = () => {  ANGLE -= 1;   //...  requestAnimationFrame(animation);};
复制代码


在动画函数中遍历所有文字元素来设置动画。


document.querySelectorAll(".spiral *").forEach((el, i) => {  // ...});
复制代码


计算 Y 轴偏移和缩放,使用三角函数计算每个元素的 Y 轴偏移量和缩放比例:


const translateY = Math.sin(ANGLE * (Math.PI / 120)) * 100;const scale = Math.cos(ANGLE * (Math.PI / 120)) * 0.5 + 0.5;
复制代码


设置动画延迟,根据元素索引和数据属性 data-offset 计算动画的延迟时间。


const offset = parseInt(el.dataset.offset);const delay = i * (ANIMATION_DURATION / 16) - offset;
复制代码


最后动态设置 CSS 变换属性transform来应用 Y 轴偏移和缩放。在定时器中使用 delay 延迟时间执行动画。


setTimeout(() => {  el.style.transform = `translateY(${translateY}px) scale(${scale})`;}, delay);
复制代码


火狐浏览器执行动画函数。


let isFirefox = typeof InstallTrigger !== 'undefined';
if(isFirefox){ animation();}
复制代码

在线预览

关注公众号回复【 20240730 】可获取完整源代码~

最后

通过结合 JavaScript 和 CSS,我们成功实现了一个动态的螺旋文字滚动特效。该特效不仅展示了字符的动态变化,还通过延迟时间结合动画效果增强了视觉吸引力。本质实现这个效果是不需要 JavaScript,为了兼容火狐和动态创建文案 DOM 才使用了相关 JavaScript。有兴趣的可以尝试使用纯 CSS 实现这个炫酷的螺旋文字滚动特效。




看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~


专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

发布于: 刚刚阅读数: 5
用户头像

南城FE

关注

公众号@南城大前端 2019-02-12 加入

专注前端开发,分享前端知识

评论

发布
暂无评论
螺旋文字滚动特效源码解析_CSS_南城FE_InfoQ写作社区