自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用 SVG 描邊動(dòng)畫(huà)送一份平安夜祝福

開(kāi)發(fā) 前端
SVG 是網(wǎng)頁(yè)里畫(huà)矢量圖的技術(shù),可以用 rect、circle、line 等畫(huà)一些具體的圖形,也可以用 path 來(lái)畫(huà)更復(fù)雜的圖形。

[[441892]]

今晚是平安夜,提前給大家送份祝福。

SVG 是用 Illustrator 畫(huà)的,蘋(píng)果是手繪的(雖然是畫(huà)的丑了點(diǎn) 0.0)。

按照慣例,看完效果之后我們來(lái)學(xué)習(xí)下它的實(shí)現(xiàn)原理。

思路分析

SVG 是網(wǎng)頁(yè)上畫(huà)矢量圖的技術(shù),有 line(線)、polyline(折線)、polygon(多邊形)、react(矩形)、circle(圓形)、ellipsis(橢圓)等圖形,也可以通過(guò) path 來(lái)描述任意的形狀。

  1. <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg"
  2.  
  3.     <rect width="300" height="100"/> 
  4.     <path d="M250 150 L150 350 L350 350 Z" /> 
  5.  
  6. </svg> 

其中 M 是 moveTo,移動(dòng)到某個(gè)位置開(kāi)始畫(huà),L 是 lineTo,畫(huà)一條直線,Z 是 closePath,完成繪制。當(dāng)然,還可以繪制曲線等,api 和 canvas 里畫(huà)圖形的 api 差不多。

那我們需要用代碼手畫(huà)蘋(píng)果和文字的 path 么?

不用,可以用 Illastrator 這種矢量繪圖軟件,它有鋼筆、文字等各種繪圖工具,用這些工具繪制完然后導(dǎo)出 SVG 就行。

SVG 可以設(shè)置兩個(gè)方面的屬性,一個(gè)是線條相關(guān)的,主要是 stroke,一個(gè)是填充相關(guān)的,主要是 fill。

stroke 相關(guān)的樣式有 stroke-dasharray 來(lái)指定用虛線畫(huà)。

比如 stroke-dasharray:10 20; 是虛線長(zhǎng)度 10px,間隔 20px。

也可以用 stroke-dasharray 指定虛線的 offset,也就是偏移位置,往左偏移是正,往右是負(fù)。

比如 stroke-dashoffset: 1 就是往左偏移 1px。

注意這個(gè) stroke-dashoffset,我們往左偏移全部的長(zhǎng)度,然后再慢慢移動(dòng)回原來(lái)位置,也就是 offset 由正數(shù)到 0,不就是描邊的效果的呢?

這就是 SVG 描邊動(dòng)畫(huà)的原理。

知道了這種動(dòng)畫(huà)要改變什么屬性,那我們要用定時(shí)器自己去改變么?不用,可以用一些動(dòng)畫(huà)框架來(lái)修改屬性值,比如 anime.js,它還支持設(shè)置時(shí)間函數(shù),比如勻速、加速等。

理清了大概的原理,那我們來(lái)動(dòng)手實(shí)現(xiàn)下吧。

代碼實(shí)現(xiàn)

首先先把 SVG 準(zhǔn)備好,我們用 Illastrator 來(lái)畫(huà):

使用文字工具寫(xiě)祝福的文字,然后選擇“創(chuàng)建輪廓”,就會(huì)變成一個(gè)輪廓數(shù)據(jù),然后選擇導(dǎo)出 SVG 就行了。

蘋(píng)果可以用鋼筆手畫(huà),畫(huà)完后點(diǎn)擊“創(chuàng)建復(fù)合路徑”,變成 path 的形式,然后導(dǎo)出 SVG:

畫(huà)好了 SVG 之后,我們?cè)賹?shí)現(xiàn)動(dòng)畫(huà)效果:

  • 最開(kāi)始把 stroke-dashoffset 設(shè)置為 SVG 的長(zhǎng)度,然后用動(dòng)畫(huà)的方式慢慢變?yōu)?0。
  • 每一個(gè) path 畫(huà)完之后就用 fill 屬性來(lái)填充顏色。

我們給每個(gè) path 加上一個(gè) class,然后來(lái)做動(dòng)畫(huà)。

使用 anime.js 來(lái)改變 stroke-dashoffset 實(shí)現(xiàn)描邊的動(dòng)畫(huà)效果。

需要傳入這些參數(shù):

  • 指定 targets,也就是添加動(dòng)畫(huà)效果的元素
  • 指定 strokeDashOffset 屬性值從 SVG 的長(zhǎng)度慢慢變到 0。
  • 指定 easing 時(shí)間函數(shù),linear 是勻速
  • 指定 duration 時(shí)間間隔
  • 指定每個(gè)元素的執(zhí)行動(dòng)畫(huà)的 delay 時(shí)間
  • 還可以指定每個(gè)元素動(dòng)畫(huà)結(jié)束之后修改一些屬性值
  1. const duration = 800; 
  2.  
  3. anime({ 
  4.     targets: ".svg-path"
  5.     strokeDashoffset: function(item) {  
  6.         const svgLength = anime.setDashoffset(item);  
  7.         return [svgLength, 0];  
  8.     }, 
  9.     easing: "linear"
  10.     duration, 
  11.     delay: function (item, index) { 
  12.         return duration * index
  13.     }, 
  14.     updatefunction (anim) { 
  15.         const color = ['red''pink''purple','skyblue''blue','red''green','green']; 
  16.         for(let i = 1; i <= color.length; i++) { 
  17.             if (anim.currentTime >= duration * i) { 
  18.                 document.querySelector(".path" + i).style.fill = color[i-1]; 
  19.             } 
  20.         } 
  21.     }, 
  22.     autoplay: true 
  23. }); 

我們給每個(gè)元素設(shè)置了不同的動(dòng)畫(huà) delay 時(shí)間,就是一個(gè)個(gè)做動(dòng)畫(huà)的效果。

每個(gè)元素執(zhí)行結(jié)束之后,判斷了下時(shí)間,如果是已經(jīng)執(zhí)行完動(dòng)畫(huà)的元素,就 fill 上顏色。

stokeDashOffset 的初始值是 SVG 的長(zhǎng)度(向左偏移),然后慢慢變?yōu)?0(回到原點(diǎn))。

這樣,我們就實(shí)現(xiàn)了想要的描邊動(dòng)畫(huà)的效果。

全部代碼:

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3.  
  4. <head> 
  5.     <meta charset="UTF-8"
  6.     <meta http-equiv="X-UA-Compatible" content="IE=edge"
  7.     <meta name="viewport" content="width=device-width, initial-scale=1.0"
  8.     <title>平安夜快樂(lè)</title> 
  9.     <script src="https://unpkg.com/animejs@3.2.1/lib/anime.min.js"></script> 
  10.     <style> 
  11.         body { 
  12.             background-color: #000; 
  13.         } 
  14.  
  15.         .box { 
  16.             width: 600px; 
  17.             height: 300px; 
  18.             text-align: center; 
  19.             margin: 0 auto; 
  20.         } 
  21.  
  22.         svg { 
  23.             width: 600px; 
  24.             height: 300px; 
  25.             padding-top: 30px; 
  26.         } 
  27.         .svg-path { 
  28.             fill: #000; 
  29.             stroke: #fff; 
  30.         } 
  31.     </style> 
  32. </head> 
  33.  
  34. <body> 
  35.     <div class="box"
  36.         <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50.34 333.9"
  37.             <path class="svg-path path1" 
  38.                 d="M289.75,295.3v1.8a8.37,8.37,0,0,1-.24,2.1c-16.68,0-29.94-.36-39.78-1.2a7.41,7.41,0,0,1-.17-2,6.49,6.49,0,0,1,.29-2Q269.92,293.92,289.75,295.3Zm-29.58,22.92a9.45,9.45,0,0,1-3.54,2.22,50.86,50.86,0,0,1-5.82-8.58,9.62,9.62,0,0,1,3.61-2.16A98.3,98.3,0,0,1,260.17,318.22Zm26.76,8.7a6.52,6.52,0,0,1,.18,1.86,6,6,0,0,1-.18,1.86c-.6.24-3.78.36-9.48.36h-4.86c-.12,2.76-.3,5.22-.48,7.5a6.22,6.22,0,0,1-2,.24,4.7,4.7,0,0,1-1.68-.24c-.18-2.4-.3-4.86-.36-7.5-9.54,0-14.88-.12-15.95-.36a5.88,5.88,0,0,1-.25-2,5.49,5.49,0,0,1,.3-2c4.92-.12,10.2-.18,15.78-.18v-3.42q0-5.85.36-12.24a10.57,10.57,0,0,1,2-.24,9.05,9.05,0,0,1,2,.24q.36,6.48.36,11.88v3.72h4.74A79,79,0,0,1,286.93,326.92Zm5-15.12a49.35,49.35,0,0,1-6.66,9.54,4.71,4.71,0,0,1-3.06-1.8,46.39,46.39,0,0,1,6.18-9.84A6.85,6.85,0,0,1,291.91,311.8Z" 
  39.                 transform="translate(-245.6 -293.92)" /> 
  40.             <path class="svg-path path2" 
  41.                 d="M254.11,372.4a129.35,129.35,0,0,1-.71,13,6.56,6.56,0,0,1-2.11.24,2.82,2.82,0,0,1-2-.48,88.15,88.15,0,0,1,.67-13,20.77,20.77,0,0,1,2.1-.12A5.79,5.79,0,0,1,254.11,372.4Zm34.68,16.86v2c-7.2.6-14.34,1-21.54,1.32-.9,2.52-1.74,5.1-2.58,7.62,4.08,1,8.16,1.8,12.3,2.64,1-2.52,1.92-4.92,2.88-7.08q1.8.54,3.78,1.26c-.66,2.28-1.38,4.56-2.22,6.72l5.46,1.08a16.5,16.5,0,0,1-1.08,3.66c-2-.36-4-.66-5.94-1-.6,1.26-1.14,2.52-1.74,3.78a8.53,8.53,0,0,1-3.54-1.74c.3-1,.6-2,1-2.88-5.76-1.14-11.46-2.46-17.16-4,1.14-3.42,2.28-6.66,3.48-9.78-3,.18-6,.3-8.87.36a21.4,21.4,0,0,1-.37-4c3.66-.24,7.32-.42,10.92-.66q1.62-4.23,3.42-8.1a31.59,31.59,0,0,1,4,1.32c-.78,2.16-1.56,4.32-2.28,6.48.6,0,1.2-.06,1.8-.12,5.88-.3,11.94-.54,18.06-.72A9.87,9.87,0,0,1,288.79,389.26ZM270.25,372.4c-.18-2-.24-4.08-.24-6.18.72-.06,1.5-.12,2.4-.24a19.25,19.25,0,0,1,2.16.12c0,2.16.06,4.26.06,6.42q8.64.18,17.1.54.36,5.4.36,10.26a4.82,4.82,0,0,1-1.8.24,14.21,14.21,0,0,1-2.1-.12c-.24-1.38-.48-3.66-.72-6.78-9.24,0-18.6-.24-28-.72a6.39,6.39,0,0,1-.24-2,8.5,8.5,0,0,1,.12-1.68C263,372.28,266.65,372.34,270.25,372.4Z" 
  42.                 transform="translate(-245.6 -293.92)" /> 
  43.             <path class="svg-path path3" 
  44.                 d="M263.41,455.92c-5.46,2.88-10.74,5.46-15.89,7.68a6.9,6.9,0,0,1-1.92-3.18,175.82,175.82,0,0,1,15.83-8.34A16.66,16.66,0,0,1,263.41,455.92Zm9.66-15.9h7.38a87,87,0,0,1,9,.42,6.32,6.32,0,0,1,.18,1.8,5.26,5.26,0,0,1-.18,1.8c-.6.24-3.6.3-9,.3-18.06,0-27.9-.06-29.51-.3a5.28,5.28,0,0,1-.25-1.92,4.33,4.33,0,0,1,.31-1.86l17.75-.18a30.6,30.6,0,0,1-.48-4q1.8-.27,4-.54C272.59,437,272.83,438.52,273.07,440Zm-13.26,35.34a9.85,9.85,0,0,1-3.66.66,56.49,56.49,0,0,1-3-13,16.28,16.28,0,0,1,3.48-.72A65.47,65.47,0,0,1,259.81,475.36Zm8.1-10.32a8.29,8.29,0,0,1-3.18-2.22,65.29,65.29,0,0,1,11.4-13.26,11.4,11.4,0,0,1,2.7,2.1c-.48.72-1,1.5-1.56,2.22,4.5,1.32,9.3,2.82,14.46,4.5-1.68,4.8-3.54,9.42-5.46,13.86-.78,1.86-1.5,3.48-2.1,4.86,2.52,1,5,2,7.38,3a20.4,20.4,0,0,1-1.38,3.42c-2.64-.78-5.16-1.62-7.68-2.52a26.33,26.33,0,0,1-2,3.9,10.66,10.66,0,0,1-3.84-1.74c.48-1.26,1-2.52,1.56-3.72-3.48-1.26-7-2.64-10.38-4.2a13.37,13.37,0,0,1,1.38-3.78c3.6,1.32,7.2,2.64,10.74,4,2.1-4.92,4.14-9.78,6.18-14.58-4.08-1.14-7.86-2.34-11.34-3.66C272.77,459.58,270.49,462.22,267.91,465Zm12.54,1.14a14.75,14.75,0,0,1-1.5,3.3,19,19,0,0,1-6.3-2.76,17.21,17.21,0,0,1,1.56-3.48C276.31,464.14,278.41,465.1,280.45,466.18Z" 
  45.                 transform="translate(-245.6 -293.92)" /> 
  46.             <path class="svg-path path4" 
  47.                 d="M251.71,539a21.77,21.77,0,0,1-3.9.36c-.77-5.52-1.25-11-1.49-16.62a22,22,0,0,1,4.08-.36C250.94,528,251.35,533.62,251.71,539Zm7.8-14a64.55,64.55,0,0,1,6.54,1.08,20.77,20.77,0,0,1-.42,3.6,22.77,22.77,0,0,1-5.82-.66c.36,5.64.6,11.1.66,16.38a4.87,4.87,0,0,1-1.74.24,6.14,6.14,0,0,1-1.68-.12A261.61,261.61,0,0,1,255,515.8a11,11,0,0,1,1.92-.24h1.79C259,518.8,259.27,521.92,259.51,525Zm21.18-13.5a9.67,9.67,0,0,1,3.84,1.26c-.54,1.86-1.26,4.44-2.16,7.68,3,.06,6.18.18,9.66.36.36,3.24.72,7.5,1.14,12.9a13.74,13.74,0,0,1-4,.54c-.6-3.84-1-7.08-1.38-9.84-2.4,0-4.62-.06-6.6-.06-1,3.24-2,7-3.18,11.28h9.42a73.75,73.75,0,0,1,8.28.42,5.65,5.65,0,0,1,.18,1.68,4.47,4.47,0,0,1-.18,1.62c-.54.24-3.3.3-8.28.3H276.91c-1.08,3.84-2.28,8-3.48,12.42a11.64,11.64,0,0,1-3.6-1.26c.66-3.54,1.5-7.26,2.46-11.22a77,77,0,0,1-7.92-.24,7,7,0,0,1-.18-1.74,4.26,4.26,0,0,1,.3-1.74l8.76-.18c1-3.6,2.1-7.44,3.3-11.46-3-.06-5.52-.18-7.68-.3a14.37,14.37,0,0,1-.3-3.3c3.24-.12,6.3-.18,9.18-.24C278.65,517.48,279.61,514.48,280.69,511.48Zm11.22,36.06a9.05,9.05,0,0,1-.9,1.68,11.09,11.09,0,0,1-1.14,1.62,28.41,28.41,0,0,1-9.18-4.5,9.93,9.93,0,0,1,2.1-3.42C285.73,544.3,288.79,545.86,291.91,547.54Z" 
  48.                 transform="translate(-245.6 -293.92)" /> 
  49.             <path class="svg-path path5" 
  50.                 d="M255.19,591.4a66.44,66.44,0,0,1-.72,9.42c2.1.6,6.18,1,12.3,1.08-.42-3.72-.84-7.38-1.2-11.1a18.16,18.16,0,0,1,4.2-.6c.6,4,1.14,7.86,1.62,11.76,9.12,0,15.36-.3,18.6-.9a17.86,17.86,0,0,1,.48,4c-2.88,1.08-9,1.62-18.48,1.74q1.08,9.72,1.62,19.62a31.7,31.7,0,0,1-10.44,1.44,7.53,7.53,0,0,1-.84-3.42,44.52,44.52,0,0,1,6.84-.9c-.66-5.58-1.26-11.16-1.86-16.74-8.64-.12-14.52-.66-17.69-1.62a94.48,94.48,0,0,1,1-13.86,19.81,19.81,0,0,1,2.35-.12C254.42,591.34,255.19,591.4,255.19,591.4Zm32-7.92a14.29,14.29,0,0,1,.12,2q-18.54,2.61-36.77,3.9a4.47,4.47,0,0,1-.48-2.1v-1.8c12.35-1.56,24.59-2.76,36.83-3.72A6.24,6.24,0,0,1,287.17,583.48Zm-28.08,31c-1,3.12-2,6.6-3.36,10.38a8.26,8.26,0,0,1-4.14-1.32A55.78,55.78,0,0,1,255,613,20.2,20.2,0,0,1,259.09,614.5Zm29.16,2.28c.72,1.44,1.38,2.82,1.86,4.08a9.78,9.78,0,0,1-4,1.74,39.45,39.45,0,0,1-4.38-8.7,22.14,22.14,0,0,1,4.08-1.62C286.69,613.84,287.53,615.34,288.25,616.78Z" 
  51.                 transform="translate(-245.6 -293.92)" /> 
  52.         </svg> 
  53.         <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 219.1 246.81"
  54.             <path class="svg-path path6" 
  55.                 d="M326.34,316.17h32.53l27.71,25.3,10.84,36.14V421l-9.64,37.35L376,486.05l-31.54,14.46-28.92-6-15.66-10.84-5.37,4.7-13.91,12.17H262.48l-30.12-10.85L201,471.59,186.58,433l-7.23-51.81,34.94-39.76,85.54,9.64Z" 
  56.                 transform="translate(-178.82 -254.22)" /> 
  57.             <path class="svg-path path7" 
  58.                 d="M243.2,296.89l-4.81-14.46L248,254.72h14.46l23.5,12,23.49,18.07v24.1l-9.64,42.17L262.48,321Z" 
  59.                 transform="translate(-178.82 -254.22)" /> 
  60.             <path class="svg-path path8" d="M248,254.72l18.29,24.63,23.87,40.7,9.65,31.06" 
  61.                 transform="translate(-178.82 -254.22)" /> 
  62.         </svg> 
  63.     </div> 
  64.  
  65.     <script> 
  66.         const duration = 800; 
  67.  
  68.         anime({ 
  69.             targets: ".svg-path"
  70.             strokeDashoffset: function(item) {  
  71.                 const svgLength = anime.setDashoffset(item);  
  72.                 return [svgLength, 0];  
  73.             }, 
  74.             easing: "linear"
  75.             duration, 
  76.             delay: function (item, index) { 
  77.                 return duration * index
  78.             }, 
  79.             updatefunction (anim) { 
  80.                 const color = ['red''pink''purple','skyblue''blue','red''green','green']; 
  81.                 for(let i = 1; i <= color.length; i++) { 
  82.                     if (anim.currentTime >= duration * i) { 
  83.                         document.querySelector(".path" + i).style.fill = color[i-1]; 
  84.                     } 
  85.                 } 
  86.             }, 
  87.             autoplay: true 
  88.         }); 
  89.     </script> 
  90.  
  91. </body> 
  92.  
  93. </html> 

總結(jié)

SVG 是網(wǎng)頁(yè)里畫(huà)矢量圖的技術(shù),可以用 rect、circle、line 等畫(huà)一些具體的圖形,也可以用 path 來(lái)畫(huà)更復(fù)雜的圖形。

SVG path 的 api 和 canvas 里的 path 差不多,比如 M 是 moveTo,L 是 lineTo,Z 是 closePath。

復(fù)雜圖形可以用矢量圖繪制軟件 Illuastrator 來(lái)繪制,之后導(dǎo)出為 SVG。

SVG 可以設(shè)置的屬性主要有 stroke 指定線條樣式,fill 指定填充樣式。

其中 stroke-dasharray 是指定虛線長(zhǎng)度,stroke-dashoffset 是指定虛線偏移,正數(shù)向左,負(fù)數(shù)向右。

通過(guò) stroke-dashoffset 的值的變化,就能實(shí)現(xiàn)描邊的效果,從 SVG 的整體長(zhǎng)度慢慢變化到 0。

屬性值的修改可以用動(dòng)畫(huà)框架 anime.js,它支持定時(shí)修改元素的屬性值來(lái)做動(dòng)畫(huà),并且支持勻速、加速等時(shí)間函數(shù)。

文中的那個(gè)動(dòng)畫(huà),我們指定每個(gè) path 的 delay 時(shí)間,每個(gè) path 繪制完之后設(shè)置 fill 屬性即可。

SVG 的描邊動(dòng)畫(huà)還是挺不錯(cuò)的效果,可以用在很多地方。實(shí)現(xiàn)原理也不難,就是一個(gè) offset 屬性值的修改。大家很快就能學(xué)會(huì)。

最后,再次祝大家平安夜快樂(lè)呀,加上今天是周五,double 的快樂(lè)~

 

責(zé)任編輯:姜華 來(lái)源: 神光的編程秘籍
相關(guān)推薦

2013-01-04 17:42:37

亞馬遜宕機(jī)負(fù)載均衡

2009-12-25 17:50:04

2011-12-20 12:19:11

2010-12-24 18:12:02

系統(tǒng)升級(jí)

2014-12-25 17:07:00

2009-12-24 13:51:54

熱門(mén)服務(wù)器

2019-03-24 14:14:40

代碼閱讀源代碼

2021-02-21 08:12:24

SVG線條動(dòng)畫(huà)Web動(dòng)畫(huà)

2012-12-26 10:05:06

亞馬遜云計(jì)算Netflix

2020-07-15 15:38:15

人臉識(shí)別照片活化手機(jī)

2018-03-09 10:28:30

生態(tài)報(bào)告簽收

2022-04-29 08:48:25

開(kāi)源

2021-12-15 18:32:33

Log4Shell漏洞攻擊

2021-02-21 07:49:40

Web動(dòng)畫(huà)SVG線條動(dòng)畫(huà)

2009-03-11 13:32:12

簡(jiǎn)歷求職應(yīng)聘

2019-03-15 15:15:12

硬盤(pán)SSD閃存

2023-09-29 22:41:26

Kubernetes云原生

2018-07-29 15:33:04

2018-05-03 07:06:21

開(kāi)發(fā)規(guī)范iOS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)