怎樣做一個圓環(huán)放大的動畫
最近遇到一個問題,就是怎么做一個圓環(huán)放大的動畫,如果是用transform: scale放大的話,會導致圓環(huán)變粗,這樣看起來就不好看了,如下圖所示:
如果改成用width/height做動畫的話,動畫看起來會有點變形,如下圖所示:
這個圓圈是用border-radius: 50%畫出來的,所以width/height變大的時候,圓圈的半徑就會變大,但是在變化的過程中變形了。如果改成用padding做動畫,效果也一樣,那怎么辦呢?一個方法是把動畫時間調小一點,這樣看起來會減輕,但終究不是根本解決辦法。
我在網(wǎng)上搜羅一番,也沒有找到好的辦法,有的是用JS動態(tài)計算width/height,但其實是一樣的。
***我想到是不是可以用SVG來做動畫呢?試了一下,果然可以。
首先要用SVG來畫,之前是用html + css的方式,現(xiàn)在要改一下。如下代碼所示:
- <svg width="22px" height="22px">
- <circle r="8" cx="11" cy="11" fill="#fff" stroke="#2492fc"/>
- </svg>
circle表示畫一個圓,圓心在(11, 11),半徑為8px,填充白色,描邊為#2492fc,如果你設置fill=”none”,那么填充色就為透明色。相信很多人對SVG比較陌生,這里我簡單介紹一下。除了circle,其它常用的畫圖標簽元素如下圖所示:
還有一個畫路徑的path,如下圖所示:
這個是用一個在線SVG畫圖工具來出來的,畫完后會顯示SVG代碼。path里面可以使用貝塞爾曲線,它是一種很見的曲線,在CSS的animation也會用到,用來控制動畫的速度:
貝塞爾曲線(三階)是根據(jù)四個點畫出一條光滑的曲線,這種矢量繪制曲線的方法在圖形學具有重大的意義。
SVG的基本元素就介紹到這里,現(xiàn)在討論下怎么做動畫呢?我們應該要做半徑的動畫,如下圖所示,使用animate標簽:
其中begin指定動畫的開始時機,可以是indefinite表示***循環(huán),或者指定具體的秒數(shù),又或者是在某個動畫之后,還可以是事件如mouseover/click/mouseout等,上面使用mouseover,即hover的時候,半徑會從小變成到大,如果希望鼠標移開后能縮回去,那么可以再加一個amimate,如下代碼所示:
- <svg width="22px" height="22px">
- <circle r="8" cx="11" cy="11" fill="#fff" stroke="#2492fc">
- <animate attributeName="r" from="8" to="10" dur="0.3s" begin="mouseover" fill="freeze" class="magnify"/>
- <animate attributeName="r" from="10" to="8" dur="0.3s" begin="mouseout" fill="freeze" class="shrink"/>
- </circle>
- </svg>
如果是希望用JS控制的話,可以獲取到這個animate元素,然后用它的beginElement方法開始動畫,如下代碼所示:
- // 如果選中的話,就做放大的動畫
- if (checked) {
- $("animate.magnify").beginElement();
- }
- // 如果失去選中態(tài)的話就做縮小動畫
- else {
- $("animate.shrink").beginElement();
- }
這樣看起來動畫就會優(yōu)雅很多,如下圖所示:
另外還可以用CSS的animation等控制SVG做動畫。
上面只是介紹了最最簡單的SVG動畫,更多復雜的效果可以見CSS Tricks的教程。例如可以做形狀的動畫:
又如做一個沿著路徑運動的動畫:
本篇最主要還是想說一件事:當你發(fā)現(xiàn)用html不太好做動畫時,可以嘗試用svg做一下,幾行svg就能做出一個很順滑的動畫。例如這篇文章《Animating Border》介紹了幾種做border變粗的動畫的方法,筆者先后使用了border-width/outline/clip-path/linear-gradient/box-shadow等,***效果其實都不太好,還不如直接用svg做一下。
【本文是51CTO專欄作者“人人網(wǎng)FED”的原創(chuàng)稿件,轉載請通過51CTO聯(lián)系原作者獲取授權】