[TOC]
看到網頁中那種有如寫字般的動畫,覺得挺好玩的,就找了下製作方法,也比較簡單,在此記錄一下; 先上幾張圖看看:
用到的屬性
stroke 定義邊框顏色值; stroke-width 定義描邊寬度; stroke-dashoarray 前一個數值表示dash,後一個數字表示gap長度(只寫單個值表示dash/gap尺寸一致),往復迴圈; stroke-dashoffset 虛線開始時的偏移長度,正數則從路徑起始點向前偏移,負數則向後偏移;
原理
- 定義
stroke-dashoarray
屬性,使svg圖案的 dash 和 gap 長度大於等於最終圖案長度值(記為len); - 將其往前偏移len,使dash部分初始隱藏,只顯示 gap , gap 又是空白的,所以初始時頁面無任何東西;
- 定義動畫,不斷改變
stroke-dashoffset
的值直至為0,就出現了動畫;
繪製svg圖案
主要使用到 path 標籤,具體可以看 這裡 ; 複雜點的圖案就不建議手動書寫,可採用第三方軟體,匯出成svg檔案,刪除無用程式碼即可,如: Inkscape 線上編輯
動畫實現
可通過css或js來控制動畫的實現,css比較簡單,但圖案的長度等引數不易掌控;
CSS實現
<style>
path {
stroke-dasharray: 610;//實線-間隔長度都是610(大於所畫長度)
stroke-dashoffset: 610;//往前偏移610(超過圖形長度),則初始顯示為空白
animation: dash 5s linear;//新增動畫,使偏移逐漸變為0,以顯示完整圖案
animation-fill-mode: forwards;//動畫完成後保持不變
}
// 定義css動畫,@keyframes yourName
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
</style>
複製程式碼
js控制動畫
初始化相關屬性
//程式碼獲取長度並設定動畫相關屬性
var path = document.querySelector('path');
var len = path.getTotalLength();
console.log("總長度 : " + len);
//定義實線和空白區域長度
path.style.strokeDasharray = len + 10;
//定義初始dash部分相對起始點的偏移量,正數表示往前便宜
path.style.strokeDashoffset = len + 10;
複製程式碼
方式1:使用transition
// 方式1:參考文章: https://jakearchibald.com/2013/animated-line-drawing-svg/
path.style.transition = path.style.WebkitTransition =
'none';
// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
path.getBoundingClientRect();
path.style.transition = path.style.WebkitTransition =
'stroke-dashoffset 5s ease-in-out';
path.style.strokeDashoffset = '0';
複製程式碼
方式2:定時重新整理重繪
var initial_ts = new Date().getTime();
var duration = 5000;
var draw = function () {
var progress = (Date.now() - initial_ts) / duration;
if (progress < 1) {
path.style.strokeDashoffset = Math.floor(len * (1 - progress));
setTimeout(draw, 50);
}
};
draw();
複製程式碼
方式3:使用requestAnimationFrame
var initial_ts = new Date().getTime();
var duration = 5000;
var handle = 0;
var animate = function () {
var progress = (Date.now() - initial_ts) / duration;
if (progress >= 1) {
window.cancelAnimationFrame(handle);
} else {
path.style.strokeDashoffset = Math.floor(len * (1 - progress));
handle = window.requestAnimationFrame(animate);
}
};
animate();
複製程式碼
方式3比較依賴系統重新整理率,若硬體效能問題導致fps下降嚴重,則可能出現較嚴重卡頓現象
參考
W3C SVG MDN-SVG Painting: Filling, Stroking and Marker Symbols Animated line drawing in SVG 用css定義svg的樣式和動畫 SVG SMIL animation動畫詳解