最近在水果公众号上看到一段菊花绽开的动画,丝般润滑的感觉,吹弹可破的花瓣,让我忍不住看了下究竟,将所得整理了下,做为小技巧分享给你们。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开发者工具中复制黏贴
搞定,收工!