最近在水果公衆號上看到一段菊花綻開的動畫,絲般潤滑的感覺,吹彈可破的花瓣,讓我忍不住看了下究竟,將所得整理了下,做爲小技巧分享給你們。javascript
具體看下圖,視頻轉換成GIF質量降低,有興趣能夠去水果公號看。css
水果綻開動畫html
瞄了下源代碼,竟然是用SVG動畫拼成的序列幀。序列幀是什麼?水果前端爲何好好的GIF圖不用,要用序列幀?緣由聽我慢慢道來。前端
什麼是序列幀?java
序列幀就是一系列靜止圖像,將這些圖像按照必定的頻率播放,就造成了連續的動畫,通常認爲到達到每秒24幀的速率,人們纔會看到平滑動畫,你們平時看到的視頻和動圖本質都是由序列幀組成的。web
電影畫面中序列幀chrome
翻頁動畫dom
使用序列幀有什麼好處?svg
怎樣使用序列幀?工具
在日常的web開發中,咱們能夠很容易地用js或者css實現相似的幀動畫,因爲公衆號圖文環境的限制,咱們只能用SVG來實現這個效果,水果公號裏用animate標籤巧妙的解決這個問題。
經過把每一幀的圖片單獨放在一層裏,並使每一層重疊在一塊兒。使用透明度動畫來控制每一個圖片幀的出現時間,產生連續播放的動畫效果。
綻開動畫的序列幀疊加演示
<div style="height:0;"> <svg opacity="0" viewBox="0 0 828 828" style="width:100%;background-image:url('img/02.png');background-size:100% auto;background-repeat:none;transform:rotateZ(0deg);"> <animate attributename="opacity" begin="1.3125s" dur="6.25s" values="1; 1; 0; 0;" keytimes="0; 0.010; 0.012; 1" fill="freeze"></animate> </svg> </div> <div style="height:0;"> <svg opacity="0" viewBox="0 0 828 828" style="width:100%;background-image:url('img/01.png');background-size:100% auto;background-repeat:none;transform:rotateZ(0deg);"> <animate attributename="opacity" begin="1.25s" dur="6.25s" values="1; 1; 0; 0;" keytimes="0; 0.010; 0.012; 1" fill="freeze"></animate> </svg> </div>
原理懂了,但是動畫整整有70多幀,複製黏貼顯然不適合我這樣(lan)機智的前端,因而拿出了看家本領javascript大法。
const generateFrames = () => { const container = document.querySelector('#container') const totalFrames = 72 let html = '' for(let i = totalFrames; i > 0; i--) { const inter = 0.0625 const height = i == 1 ? 'auto' : '0px' const opacity = i == 1 ? 1 : 0; const begin = (1.5 + inter * i) + 's' const dom = ` <div token interpolation" >${height};"> <svg opacity="${opacity}" viewBox="0 0 828 828" token interpolation" >${i}.png');background-size:100% auto;background-repeat:none;transform:rotateZ(0deg);"> <animate attributename="opacity" begin="${begin}" dur="6.25s" values="1; 1; 0; 0;" keytimes="0; 0.010; 0.012; 1" fill="freeze"></animate> </svg> </div> ` html += dom } container.innerHTML = html } generateFrames()
將生成的代碼,在開發者工具中複製黏貼。
chrome開發者工具中複製黏貼
搞定,收工!