簡單的SVG線條動畫

[TOC]css

Demo項目下載html

看到網頁中那種有如寫字般的動畫,以爲挺好玩的,就找了下製做方法,也比較簡單,在此記錄一下; 先上幾張圖看看:git

簡單的線條動畫

ps4

用到的屬性

stroke 定義邊框顏色值; stroke-width 定義描邊寬度; stroke-dashoarray 前一個數值表示dash,後一個數字表示gap長度(只寫單個值表示dash/gap尺寸一致),往復循環; stroke-dashoffset 虛線開始時的偏移長度,正數則從路徑起始點向前偏移,負數則向後偏移;github

原理

  1. 定義 stroke-dashoarray 屬性,使svg圖案的 dash 和 gap 長度大於等於最終圖案長度值(記爲len);
  2. 將其往前偏移len,使dash部分初始隱藏,只顯示 gap , gap 又是空白的,因此初始時頁面無任何東西;
  3. 定義動畫,不斷改變 stroke-dashoffset 的值直至爲0,就出現了動畫;

繪製svg圖案

主要使用到 path 標籤,具體能夠看 這裏 ; 複雜點的圖案就不建議手動書寫,可採用第三方軟件,導出成svg文件,刪除無用代碼便可,如: Inkscape 在線編輯markdown

動畫實現

可經過css或js來控制動畫的實現,css比較簡單,但圖案的長度等參數不易掌控;svg

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降低嚴重,則可能出現較嚴重卡頓現象wordpress

最終效果

參考

W3C SVG MDN-SVG Painting: Filling, Stroking and Marker Symbols Animated line drawing in SVG 用css定義svg的樣式和動畫 SVG SMIL animation動畫詳解oop

相關文章
相關標籤/搜索