螺旋文字滾動特效源碼解析,你學(xué)會了嗎?
圖片
如圖所示,今天看到一個很炫酷的雙文字螺旋滾動特效,兩行文字呈螺旋狀變化,在網(wǎng)站中這樣的效果對用戶很有吸引力。本文將基于原網(wǎng)站解析如何實現(xiàn)這個炫酷的效果,基于這個動圖可以分析出需要實現(xiàn)的要點:
- 文字呈螺旋狀滾動
- 滾動過程中文字大小變化
- 動畫過程無縫鏈接
- 兩行文字滾動
實現(xiàn)過程
文字展示
為了方便更改文案將文案定義變量,通過JS代碼動態(tài)創(chuàng)建DOM,定義文案、螺旋的角度以及動畫的持續(xù)時間:
const words = "螺旋文字滾動特效";
const ANGLE = 360;
const ANIMATION_DURATION = 4000;
將文案創(chuàng)建元素添加到頁面中:
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 設(shè)置flex布局,此時的頁面效果如下:
.spiral{
display: flex;
align-items: center;
gap: 10px;
position: absolute;
color: #e0ecef;
font-family: "sans-serif";
}
圖片
讓文字動起來
這里的動畫基于CSS Houdini @property實現(xiàn),首先定義一個自定義屬性--angle,接受角度值,初始值為0度。
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
設(shè)置關(guān)鍵幀動畫,修改定義的--angle屬性從0度旋轉(zhuǎn)到360度。
@keyframes spiral {
0% { --angle: 0deg; }
100% { --angle: 360deg; }
}
給每個文字的增加animation動畫關(guān)聯(lián)定義的關(guān)鍵幀動畫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屬性結(jié)合calc函數(shù)和三角函數(shù)來實現(xiàn)Y軸的正弦波形偏移和縮放效果。
同時在動畫中應(yīng)用了前面定義的spiral動畫。結(jié)合這兩個函數(shù),transform 屬性效果如下:
- Y 軸位移: 元素根據(jù) --angle 的值在 Y 軸上上下移動,形成波動效果。
- 縮放效果: 元素的大小根據(jù) --angle 的值進(jìn)行動態(tài)縮放,形成從小到大或從大到小的變化。
此時的動畫效果:
圖片
螺旋滾動
此時我們的文字已經(jīng)滾動起來了,只需要最后一步關(guān)鍵的代碼就可以實現(xiàn)螺旋滾動效果,仔細(xì)看原始效果就能發(fā)現(xiàn)其實每個文字滾動的動畫軌跡都是一樣的,唯一的區(qū)別就是執(zhí)行的動畫延遲時間不同,形成了一個波動起伏的效果。
增加延遲動畫CSS,由于我們的文字是通過JS創(chuàng)建的,所以需要在 createElement 中增加以下代碼即可,根據(jù)動畫持續(xù)時間和當(dāng)前文字索引計算延遲時間:
div.style.animationDelay = `-${i * (ANIMATION_DURATION / 16) - offset}ms`
由于 --angle 設(shè)置了關(guān)鍵幀動畫,是一個動態(tài)變化的變量,這段代碼會使得元素在頁面上呈現(xiàn)出螺旋或波動的動畫效果,增強(qiáng)視覺吸引力。
此時我們的動畫效果基本就完成了,如下所示:
圖片
兼容火狐
由于Firefox不支持@property動畫,原作者寫了火狐兼容代碼,使用JavaScript來實現(xiàn)動畫效果。
定義一個animation動畫函數(shù),使用 requestAnimationFrame 方法實現(xiàn)平滑的動畫效果。
const animation = () => {
ANGLE -= 1;
//...
requestAnimationFrame(animation);
};
在動畫函數(shù)中遍歷所有文字元素來設(shè)置動畫。
document.querySelectorAll(".spiral *").forEach((el, i) => {
// ...
});
計算Y軸偏移和縮放,使用三角函數(shù)計算每個元素的Y軸偏移量和縮放比例:
const translateY = Math.sin(ANGLE * (Math.PI / 120)) * 100;
const scale = Math.cos(ANGLE * (Math.PI / 120)) * 0.5 + 0.5;
設(shè)置動畫延遲,根據(jù)元素索引和數(shù)據(jù)屬性data-offset計算動畫的延遲時間。
const offset = parseInt(el.dataset.offset);
const delay = i * (ANIMATION_DURATION / 16) - offset;
最后動態(tài)設(shè)置CSS變換屬性transform來應(yīng)用Y軸偏移和縮放。在定時器中使用delay延遲時間執(zhí)行動畫。
setTimeout(() => {
el.style.transform = `translateY(${translateY}px) scale(${scale})`;
}, delay);
火狐瀏覽器執(zhí)行動畫函數(shù)。
let isFirefox = typeof InstallTrigger !== 'undefined';
if(isFirefox){
animation();
}
最后
通過結(jié)合 JavaScript 和 CSS,我們成功實現(xiàn)了一個動態(tài)的螺旋文字滾動特效。該特效不僅展示了字符的動態(tài)變化,還通過延遲時間結(jié)合動畫效果增強(qiáng)了視覺吸引力。本質(zhì)實現(xiàn)這個效果是不需要 JavaScript,為了兼容火狐和動態(tài)創(chuàng)建文案DOM才使用了相關(guān) JavaScript。有興趣的可以嘗試使用純CSS實現(xiàn)這個炫酷的螺旋文字滾動特效。