這是個人一個關於SVG的應用的技術分享網站svgtrick.com,會同步一些文章到這裏來,更多關於SVG技術應用能夠去網站看看。javascript
最近從Dribbble shot 看到@thorstenbeeck發佈的一個設計效果圖獲得靈感。根據這個設計,使用GreenSock這個動畫平臺實現了一個SVG的動畫效果,下面就來聊聊我是怎麼實現這個動畫效果的。html
GreenSock是一個無需多介紹了,是一個專門用來開發動效的平臺,而且提供了javascript版本。更多關於GreenSock的一個入門介紹能夠去我整理的簡明教程看看,這裏就再也不介紹它的基本知識。java
GreenSock在製做SVG動畫方面也很是強悍,而且還專門提供了用於增強SVG動畫製做的相關插件,好比Greensock DrawSVG plugin。它能夠實現任何SVG圖形的繪製,也能夠操做諸如stroke-dashoffset和stroke-dasharray等CSS屬性來製做一些描邊的動畫效果,下面來一個簡單的實例:express
詳細代碼地址canvas
這一步將使用SVG來實現Dribble shot上的效果圖。從效果圖能夠看到整個圖形都是由簡單的一些幾何圖形組成的,而繪製圖形正是SVG所擅長的,使用SVG來實現這樣的形狀很是簡單。app
首先來爲整個圖形建立一個畫布。建立一個SVG元素。而後建立一個跟畫布同樣大的矩形元素 rect 而後使用一個圓形的 clipPath 元素來遮住整個畫布使其內容只顯示在圓形的遮罩內。代碼以下所示:svg
<svg viewBox="0 0 500 500"> <g class="canvas"> <defs> <clipPath id="circle"> <circle class="mask" cx="250" cy="250" r="100" /> </clipPath> </defs> <g clip-path="url(#circle)"> <rect class="bg" x="0" y="0" width="500" height="500" /> </g> </g> </svg>
一個基本的佈局就完成了。下面是來添加一些樣式。固然你可使用行內樣式或者是內聯樣式也能夠是外鏈樣式。工具
<circle class="mask" cx="250" cy="250" r="100" fill="red" /> <circle class="mask" cx="250" cy="250" r="100" style="fill: red;" />
通常樣式建議使用外鏈的方式來引入樣式,這樣能夠保證html的整潔以及可維護性。固然也可使用諸如SASS等預編譯語言來編寫CSS,能夠利用預編譯語言提供的變量功能來管理顏色或者是字號等全局樣式,很是方便。佈局
因爲我使用的是SASS,我把顏色都在SASS中定義好對應顏色名稱的變量裏面:學習
// Color palette $red: #E9214F; $burnt-sienna: #F06B4B; $goldenrod: #F6DA71; $scooter: #349597; $midnight-express: #20283B; $marzipan: #FCDC9F; $fruit-salad: #49934E; $goblin: #3D7C42; $chambray: #44557E; $port-gore: #384668; $white: #ffffff; $silver-sand: #BBBBBB; // Set background color body { background-color: $midnight-express; } // Center the svg horizontally and vertically svg { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 500px; height: 500px; backface-visibility: hidden; } // Color styles .canvas { .bg { fill: $scooter; } .ground { fill: $marzipan; } .sky1 { fill: $goldenrod; } .sky2 { fill: $burnt-sienna; } .sky3 { fill: $red; } .tree-left { fill: $fruit-salad; } .tree-right { fill: $goblin; } .mountain-left { fill: $chambray; } .mountain-right { fill: $port-gore; } .mountain-top-left { fill: $white; } .mountain-top-right { fill: $silver-sand; }
如今整個是靜態的,咱們使用一點點GreenSock代碼來實現一個從小到大縮放動畫效果:
// 定義好要操做相關元素的變量 const svg = document.querySelector('svg') const canvas = { wrapper: svg.querySelector('.canvas'), mask: svg.querySelector('.canvas .mask') } // 建立一個新的GASP的時間軸 const tl = new TimelineMax({ repeat: -1 }) // 使用 GASP的from方法來定義mask元素半徑從0到1的縮放動畫效果 tl.from(canvas.mask, 1, { attr: { r: 0 }, ease: Elastic.easeOut.config(3, 1) })
幾行代碼,一個縮放的動畫效果就完成了:
接下來是繪製天空和地面元素。使用SVG中的矩形元素 rect 來繪製,三個用來繪製天空一個用來繪製地面:
<svg viewBox="0 0 500 500"> <g class="canvas"> <defs> <clipPath id="circle"> <circle class="mask" cx="250" cy="250" r="100" /> </clipPath> <clipPath id="ground"> <rect x="50" y="50" width="400" height="260" /> </clipPath> </defs> <g clip-path="url(#circle)"> <rect class="bg" x="0" y="0" width="500" height="500" /> <g clip-path="url(#ground)"> <rect class="sky3" x="50" y="130" width="350" height="70" /> <rect class="sky2" x="50" y="200" width="350" height="50" /> <rect class="sky1" x="50" y="250" width="350" height="50" /> </g> <rect class="ground" x="100" y="300" width="350" height="10" /> </g> </g> </svg>
一樣這裏也須要爲它們增長一點動效,首先是地面的動效,地面的動效是從下往上冒出的。
tl.from(canvas.ground, 0.5, { autoAlpha: 0, attr: { y: '+=200' }, ease: Power4.easeOut }, 0.1)
天空的動效跟地面同樣的。因爲天空有3個元素,而且是依次出現而不是同從下往上冒出來,可使用GreenSock中的 stagger 方法來實現:
tl.staggerFrom([canvas.sky1, canvas.sky2, canvas.sky3], 0.5, { autoAlpha: 0, skewY: 0, attr: { y: '+=90' }, ease: Elastic.easeOut.config(1, 3) }, 0.075, 0.25)
爲了使動畫更加細膩,作完動畫後還須要調整下動畫的運動曲線,可使用GreenSock提供的一個可視化動畫曲線調整工具來選擇合適的動畫曲線 ease visualizer。
下面添加地面上的樹,樹由兩個三角形組成。由於數是一個一個挨着排列的,因此使用 g 元素來包裹樹元素編成一個組,這樣方便來佈局:
<g class="tree tree1" transform="translate(150 255)"> <polygon class="tree-left" points="15,0 15,50 0,50" /> <polygon class="tree-right" points="15,0 15,50 30,50" /> </g>
重複複製七份一樣的代碼,而且使用transform來改變樹的位置,從而使之依次排列。而後是使用GreenSock來編寫樹的動畫效果,樹的動畫效果是從45度旋轉到0度旋轉的效果而且同時從0到1的縮放效果:
tl.staggerFrom([canvas.tree1, canvas.tree2, canvas.tree3, canvas.tree4, canvas.tree5, canvas.tree6, canvas.tree7], 0.5, { rotation: 45, scale: 0, transformOrigin: 'bottom center', ease: Back.easeOut.config(2, 1.55) }, 0.05, 0.4)
效果以下所示:
最後是後面的大山以及大山的動畫效果。
大山由四個三角形元素組成,代碼以下:
<g class="mountain" transform="translate(150 185)"> <polygon class="mountain-left" points="100,0 100,120 0,120" /> <polygon class="mountain-right" points="100,0 200,120 100,120" /> <polygon class="mountain-top-left" points="100,0 100,30 75,30" /> <polygon class="mountain-top-right" points="99,0 125,30 99,30" /> </g>
它的動畫效果和樹的效果差很少,只不過是把旋轉的動效變成翻轉的效果。
tl.staggerFrom([canvas.mountain], 0.75, { y: '+=50', skewX: -200, scale: 0, transformOrigin: 'bottom center', ease: Back.easeOut.config(1, .2) }, 0.0125, 0.5)
一個有趣的SVG的動畫效果就完成了,代碼地址使用GreenSock 配合 SVG 來製做動畫效果如此簡單。
原文地址,根據本身理解整理了下這個教程,主要是來學習下使用GreenSock來製做SVG動畫效果的思路和方法。