動畫效果
在工業監控系統、生產看板等場景中,經常需要模擬生產線的動態運行效果。本文將基于 Vue3 和 requestAnimationFrame 實現一個高性能的橫向循環滾動效果,完美模擬生產線傳輸帶的視覺體驗。我們將從代碼實現到原理分析,全面講解如何打造流暢、高效的滾動動畫。
一、效果展示與應用場景
先來看下最終實現的效果:一系列生產物料圖標將沿著橫向軌道從左向右連續滾動,到達終點后自動循環,形成無限滾動的生產線效果。這種效果非常適合:
- 工業監控大屏中的生產線模擬
- 生產進度可視化展示
- 物流傳輸過程動態演示
- 數據看板中的動態元素展示
相比傳統的輪播組件,這種實現方式具有更高的性能和更自然的動畫效果,尤其適合長時間運行的監控場景。
二、核心實現方案
我們將使用以下技術棧和方案:
- Vue3 + TypeScript:提供組件化開發和類型安全
- requestAnimationFrame:實現高性能動畫,替代傳統的 setInterval
- CSS 滾動優化:隱藏滾動條并優化滾動容器樣式
- 循環邏輯設計:通過重置 scrollLeft 實現無縫循環
下面是完整的實現代碼:
1. 模板結構(Template)
<template><!-- 生產線滾動容器 --><div class="ktscx-box" ref="scrollDom"><div class="ktscx"><!-- 生產線上的物品,這里循環生成40個 --><divclass="ktscx-item"v-for="(item, index) in 40":key="index"></div></div></div>
</template>
模板結構非常簡潔,主要包含兩個層級:
- 外層?
ktscx-box
:作為滾動容器,通過 ref 綁定到組件實例 - 內層?
ktscx
:包含所有滾動項的容器,設置為 200% 寬度確保能產生滾動效果 - 循環生成的?
ktscx-item
:生產線中的物品元素,共 40 個
2. 腳本邏輯(Script)
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';// 定義滾動容器的ref,指向DOM元素
const scrollDom = ref<HTMLDivElement | null>(null);
let timer: number | null = null; // 動畫幀ID,用于控制動畫// 開始橫向滾動(從左向右視覺效果)
const startScroll = () => {if (!scrollDom.value) return;// 啟動動畫幀,開始滾動timer = requestAnimationFrame(scrollStep);
};// 停止滾動
const stopScroll = () => {if (timer) {cancelAnimationFrame(timer);timer = null;}
};// 動畫幀執行的滾動邏輯
const scrollStep = () => {const moveDom = scrollDom.value;if (!moveDom) {stopScroll();return;}// 每次滾動的步長(負值表示向右滾動)const step = -1; moveDom.scrollLeft += step;// 計算最大可滾動距離 = 內容總寬度 - 容器可視寬度const maxScrollLeft = moveDom.scrollWidth - moveDom.clientWidth;// 當滾動到最左側時,重置到最右側(形成循環)if (moveDom.scrollLeft <= 0) {moveDom.scrollLeft = maxScrollLeft; }// 繼續請求下一幀動畫,形成連續滾動timer = requestAnimationFrame(scrollStep);
};// 組件掛載時啟動滾動
onMounted(() => {startScroll();
});// 組件卸載時停止滾動,防止內存泄漏
onUnmounted(() => {stopScroll();
});
</script>
腳本邏輯解析:
核心變量:
scrollDom
:通過 ref 綁定到滾動容器 DOM 元素timer
:存儲動畫幀 ID,用于控制動畫的啟動和停止
動畫控制函數:
startScroll()
:啟動滾動動畫,通過 requestAnimationFrame 觸發第一幀stopScroll()
:停止滾動動畫,通過 cancelAnimationFrame 取消動畫幀scrollStep()
:每幀執行的滾動邏輯,是實現動畫的核心
滾動原理:
- 通過修改容器的?
scrollLeft
?屬性實現滾動 - 負的步長值(
step = -1
)使內容從左向右滾動 - 當滾動到最左側(
scrollLeft <= 0
)時,重置到最大滾動位置,實現循環
- 通過修改容器的?
3. 樣式設計(Style)
<style scoped lang="scss">
.ktscx-box {width: 83%;height: 20px;overflow-x: auto; // 允許橫向滾動position: absolute;top: 256px;margin-left: 3%;// 隱藏滾動條,提升視覺體驗&::-webkit-scrollbar {display: none;}.ktscx {width: 200%; // 寬度設為200%,確保內容超出容器寬度產生滾動height: 20px;display: flex;justify-content: space-around; // 物品均勻分布align-items: center;.ktscx-item {width: 20px;height: 10px;// 使用背景圖作為生產線物品background-image: url('@/assets/images/yundong4.png');background-size: 100% 100%;background-repeat: no-repeat;flex-shrink: 0; // 防止物品被壓縮變形}}
}
</style>
樣式設計要點:
滾動容器樣式:
- 設置?
overflow-x: auto
?允許橫向滾動 - 使用?
::-webkit-scrollbar { display: none }
?隱藏滾動條 - 固定高度和寬度,確保滾動區域可控
- 設置?
內容容器樣式:
- 寬度設為 200%,確保內容寬度超過容器寬度,產生滾動空間
- 使用 flex 布局使物品均勻分布
滾動項樣式:
- 固定寬高,使用背景圖展示物品
flex-shrink: 0
?確保物品不會被壓縮變形
三、核心技術點解析
1. requestAnimationFrame 為什么比 setInterval 更好?
本實現使用 requestAnimationFrame 而非傳統的 setInterval 來驅動動畫,原因如下:
- 與瀏覽器刷新同步:requestAnimationFrame 會在瀏覽器每次重繪前執行,與顯示器刷新率(通常 60Hz)保持同步,避免動畫卡頓
- 自動性能調整:在性能較低的設備上,瀏覽器會自動降低執行頻率,保證動畫的流暢度
- 后臺暫停:當頁面處于后臺或隱藏標簽頁時,動畫會自動暫停,減少不必要的性能消耗
- 精確計時:基于系統時間計算幀間隔,避免 setInterval 可能產生的累積誤差
對于生產線這種需要長時間運行的動畫,這些優勢尤為重要。
2. 循環滾動的實現原理
循環滾動的核心在于巧妙利用?scrollLeft
?屬性和內容寬度:
scrollLeft
?屬性表示元素內容向左滾動的像素數:- 增大?
scrollLeft
?→ 內容向左移動 - 減小?
scrollLeft
?→ 內容向右移動
- 增大?
循環邏輯:
- 當內容滾動到最左側(
scrollLeft <= 0
)時 - 立即將?
scrollLeft
?重置為最大可滾動距離(maxScrollLeft
) - 由于內容容器寬度是 200%,重置后視覺上看不出跳躍,形成無縫循環
- 當內容滾動到最左側(
最大可滾動距離計算:
const maxScrollLeft = moveDom.scrollWidth - moveDom.clientWidth;
其中?
scrollWidth
?是內容總寬度,clientWidth
?是容器可視寬度。
四、功能擴展與優化
基于以上實現,我們可以進行一些實用的擴展:
1. 添加入交互控制
<!-- 在模板中添加控制按鈕 -->
<div class="controls"><button @click="startScroll">啟動</button><button @click="stopScroll">停止</button>
</div>
2. 滾動速度調節
// 添加速度控制變量
const speed = ref(1);// 在scrollStep中使用speed
const step = -speed.value;
3. 鼠標懸停暫停
<!-- 修改滾動容器 -->
<div class="ktscx-box" ref="scrollDom" @mouseenter="stopScroll" @mouseleave="startScroll">
4. 性能優化建議
- 對于大量滾動項(超過 100 個),考慮使用虛擬列表技術
- 添加?
will-change: scroll-position
?提示瀏覽器優化滾動性能 - 避免在?
scrollStep
?中執行復雜計算或 DOM 操作 - 滾動項使用相同尺寸,減少布局重排
五、總結
本文基于 Vue3 實現了一個高性能的橫向循環滾動效果,完美模擬生產線傳輸帶。核心要點包括:
使用 requestAnimationFrame 實現流暢動畫,替代傳統的 setInterval 通過控制 scrollLeft 屬性值實現滾動效果,負步長產生從左到右的視覺體驗 利用內容寬度和容器寬度的關系,實現無縫循環滾動 隱藏滾動條并優化樣式,提升視覺體驗
這種實現方式性能優異、代碼簡潔,非常適合工業監控、生產看板等場景。根據實際需求,你可以進一步擴展功能,如添加速度控制、方向切換、交互暫停等特性。
寶子們加加關注,會持續更新前端學習內容。