話很少說,咱先上效果圖:css
是否是很酷炫,這個效果是用SVG+CSS實現的,如今咱們就來一塊兒解構一下這個動畫的實現。html
<path>git
指令 | 參數 | 說明 |
---|---|---|
M | x y | 將畫筆移動到點(x,y) |
L | x y | 畫筆從當前的點繪製線段到點(x,y) |
H | x | 畫筆從當前的點繪製水平線段到點(x,y0) |
V | y | 畫筆從當前的點繪製豎直線段到點(x0,y) |
A | rx ry x-axis-rotation large-arc-flag sweep-flag x y | 畫筆從當前的點繪製一段圓弧到點(x,y) |
C | x1 y1, x2 y2, x y | 畫筆從當前的點繪製一段三次貝塞爾曲線到點(x,y) |
S | x2 y2, x y | 特殊版本的三次貝塞爾曲線(省略第一個控制點) |
Q | x1 y1, x y | 繪製二次貝塞爾曲線到點(x,y) |
T | x y | 特殊版本的二次貝塞爾曲線(省略控制點) |
Z | 無參數 | 繪製閉合圖形,若是d屬性不指定Z命令,則繪製線段,而不是封閉圖形。 |
path的指令一共有9種,但實現咱們的動畫咱們只運用了其中兩個:A和Z,因此咱們這裏着重討論一下A指令!github
繪製圓弧指令:A rx ry x-axis-rotation large-arc-flag sweep-flag x ybash
對於給定兩個點(一個起點一個終點)和一個半徑,能夠畫4條弧線。這四條弧線能夠按照兩種分法:svg
- 按角度分
- 大於180°的
- 小於180°的
- 按畫筆方向分
- 順時針方向
- 逆時針方向
rx,ry 是弧的半長軸、半短軸長度學習
x-axis-rotation 是圓弧旋轉角度,是此段弧所在的半長軸與水平方向的夾角。正數表明順時針轉動的角度。動畫
large-arc-flag 爲1 表示大角度弧線,0 表明小角度弧線。ui
sweep-flag 爲1表明從起點到終點弧線繞中心順時針方向,0 表明逆時針方向。url
x,y 是弧終端座標。
<defs>
SVG 容許咱們定義之後須要重複使用的圖形元素。 建議把全部須要再次使用的引用元素定義在
defs
元素裏面。這樣作能夠增長SVG內容的易讀性和可訪問性。 在defs
元素中定義的圖形元素不會直接呈現。 你能夠在你的視口的任意地方利用 ``元素呈現這些元素。——MDN
這個標籤的用意簡單地說就是定義一個繪圖模板,以供咱們能夠在別處直接使用。
在這裏咱們能夠定義咱們的漸變元素:linearGradient。
<linearGradient>
linearGradient元素用來定義線性漸變,用於圖形元素的填充或描邊。——MDN
一個漸變上的顏色坡度,是用stop元素定義的。
例如:
<stop offset="5%" stop-color="#F60" />
複製代碼
這行代碼的意思是:在距離起點位置偏移5%的地方顏色爲 #F60。
咱們在引用本身定義的漸變進行填充顏色設置或畫筆顏色設置時,僅須要用 url()的方式鏈入漸變的ID便可,具體以下:
stroke="url(#linear)"
複製代碼
這裏咱們將畫筆的顏色設置爲了ID爲linear的漸變。
stroke-dasharray
用於建立虛線:
stroke-dasharray = '10'
stroke-dasharray = '10, 10'
stroke-dasharray = '10, 10, 5, 5'
複製代碼
繪製虛線: 一個參數時: 表示一段虛線長度和每段虛線之間的間距 。
兩個參數或者多個參數時:一個表示長度,一個表示間距
stroke-dashoffset
stroke-dashoffset 屬性指定了dash模式到路徑開始的距離
若是使用了一個 百分比值, 那麼這個值就表明了當前viewport的一個百分比。
值能夠取爲負值。——MDN
簡單的講,stroke-dashoffset設置的是畫筆起點的偏移量,正值向左偏移。
筆者經過描點,將網上下載下來的一張蘋果圖描出了SVG,可能不大精確,可是應該夠用。這裏放一下我描點的圖:
<path
stroke-linecap="round"
fill="none"
stroke-width="10"
stroke="url(#linear)"
d=" M 197,148 A 87,87,0,0,0,79,214 A 282,282,0,0,0,148,438 A 54,54,0,0,0,212,448 A 87,87,0,0,1,288,448 A 54,54,0,0,0,352,438 A 282,282,0,0,0,407,350 A 87,87,0,0,1,413,189 A 87,87,0,0,0,303,148 A 141,141,0,0,1,197,148 Z "
/>
<path
stroke-linecap="round"
fill="none"
stroke="url(#linear)"
stroke-width="10"
d=" M 237,141 A 87,87,0,0,0,314,64 A 87,87,0,0,0,237,141 Z "
/>
複製代碼
而且我將個人畫筆顏色設置爲即將編寫的漸變id。
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="rgb(98, 180, 76)" />
<stop offset="20%" stop-color="rgb(242, 179, 61)" />
<stop offset="40%" stop-color="rgb(238, 125, 55)" />
<stop offset="60%" stop-color="rgb(205, 58, 71)" />
<stop offset="80%" stop-color="rgb(142, 61, 140)" />
<stop offset="100%" stop-color="rgb(39, 155, 213)" />
</linearGradient>
</defs>
複製代碼
爲了顯示爲彩色,我設置了六個漸變顏色節點。
值得注意的是:漸變顏色的即使應用在畫筆上,他的填色仍是按照面的顏色填充來填充的。就拿這個例子來講,我在linearGradient上定義了x1="0%" y1="0%" x2="100%" y2="100%",使頁面從左上角到右下角顏色顯示爲漸變,而不是路徑的起點到終點的漸變,因此咱們定義漸變在0%和100%的顏色並不須要同樣。(實際上咱們也不能定義從路徑的起點到終點的漸變)
let pathLength = document.querySelectorAll('path');
pathLength.forEach((item, index) => {
let itemLength = Math.ceil(item.getTotalLength());
console.log(itemLength);
});
複製代碼
這裏咱們運用到了一個JavaScript API:getTotalLength(),用於獲取路徑長度,方便咱們設置偏移量。
path {
animation: dash 5s linear forwards;
}
path:nth-child(2) {
stroke-dasharray: 1162;
stroke-dashoffset: -1162;
}
path:nth-child(3){
stroke-dasharray: 236;
stroke-dashoffset: -236;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
複製代碼
咱們的動畫使從無到有的一個過程,因此咱們將虛線長度和每段虛線之間的間距*都設置爲路徑的長度。
在這種狀況下咱們顯示的應該是完整的蘋果logo。
當咱們設置stroke-dashoffset爲路徑長度的時候,那麼咱們就將畫面的虛線部分徹底隱藏在了畫筆起點以前。整個畫面將是空空如也!
這時候咱們爲兩個path添加動畫,讓其在5s以內勻速的改變stroke-dashoffset至0,那麼呈如今咱們眼前的就是如前面的動圖所示,一個動態繪製logo的過程。
先上效果圖:
實現代碼以下:
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="164.50px" class="icon" version="1.1" viewBox="0 0 1245 1024" id="logo-pic" >
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#05a" />
<stop offset="100%" stop-color="#0a5" />
</linearGradient>
</defs>
<path fill="url(#linear)" d="M870.953514 333.768649c-209.781622 0-374.867027 145.020541-374.867028 322.836756s165.223784 322.836757 374.867028 322.836757a548.116757 548.116757 0 0 0 132.289729-22.417297L1124.185946 1024l-33.210811-110.702703C1179.537297 845.768649 1245.405405 756.92973 1245.405405 656.605405c0-177.816216-176.294054-322.836757-374.451891-322.836756z m-121.496217 267.208648A47.463784 47.463784 0 0 1 705.72973 556.419459 47.740541 47.740541 0 0 1 749.457297 512c33.349189 0 55.351351 22.278919 55.351352 44.557838s-22.002162 44.419459-55.351352 44.419459z m242.438919 0a47.325405 47.325405 0 0 1-43.727567-44.557838A47.602162 47.602162 0 0 1 991.896216 512c33.072432 0 55.351351 22.278919 55.351352 44.557838s-22.278919 44.419459-55.351352 44.419459z" />
<path fill="url(#linear)" d="M440.735135 0C198.434595 0 0 166.054054 0 378.326486c0 122.188108 66.006486 222.512432 176.432432 300.41946l-44.142702 133.811892 154.153513-77.907027c55.351351 10.931892 99.355676 22.278919 154.430271 22.278919 13.837838 0 27.675676 0 41.513513-1.798919a334.045405 334.045405 0 0 1-13.837838-93.267027c0-193.72973 166.054054-352.034595 374.728649-352.034595a378.88 378.88 0 0 1 42.482162 2.629189C847.429189 133.12 657.574054 0 440.735135 0zM294.192432 296.683243a53.137297 53.137297 0 1 1 52.722163-53.137297 52.860541 52.860541 0 0 1-52.722163 53.137297z m314.395676 0a53.137297 53.137297 0 1 1 52.722162-53.137297A52.860541 52.860541 0 0 1 608.864865 296.683243z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="2rem" id="logo-name" >
<text text-anchor="middle" x="50%" y="50%" class="logo logo-name-text-1" >
WeChat
</text>
<text text-anchor="middle" x="50%" y="50%" class="logo logo-name-text-2" >
WeChat
</text>
<text text-anchor="middle" x="50%" y="50%" class="logo logo-name-text-3" >
WeChat
</text>
</svg>
複製代碼
值得注意的是,在SVG中文字也能夠將邊框和填充分開來填色。因此這裏咱們將文字的邊框設爲最開始定義的漸變色,而填充設置爲none。
#logo-pic {
width: 75px;
height: 75px;
}
.logo {
font-size: 1.25rem;
font-weight: bold;
fill: none;
stroke-width: 1px;
stroke-dasharray: 30% 70%;
animation: stroke 4.5s infinite linear;
}
.logo-name-text-1 {
stroke: rgb(0, 169, 86);
}
.logo-name-text-2 {
stroke: rgb(0, 127, 129);
animation-delay: -1.5s;
}
.logo-name-text-3 {
stroke: rgb(0, 86, 168);
animation-delay: -3s;
}
@keyframes stroke {
to {
stroke-dashoffset: -100%;
}
}
複製代碼
筆者專門在 github 上建立了一個倉庫,用於記錄平時學習全棧開發中的技巧、難點、易錯點,歡迎你們點擊下方連接瀏覽。若是以爲還不錯,就請給個小星星吧!👍
2019/04/02