svg 动画_SVG帧动画在公众号图文中的应用

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:21   1009   0

8ee28068c980306434d163d95cefe444.png

最近在水果公众号上看到一段菊花绽放的动画,丝般润滑的感受,吹弹可破的花瓣,让我忍不住看了下究竟,将所得整理了下,作为小技巧分享给大家。

具体看下图,视频转换成GIF质量下降,有兴趣可以去水果公号看。

60f02d00ac36e22c04333128efce7e28.png
水果公众号的绽放动画

瞄了下源代码,居然是用SVG动画拼成的序列帧。序列帧是什么?水果前端为什么好好的GIF图不用,要用序列帧?原因听我慢慢道来。

什么是序列帧?

序列帧就是一系列静止图像,将这些图像按照一定的频率播放,就形成了连续的动画,一般认为到达到每秒24帧的速率,人们才会看到平滑动画,大家平时看到的视频和动图本质都是由序列帧组成的。

65cb093770bed1cb9e562bbf33d0be8e.png
电影画面中的序列帧

b4bcb80dc0209e18cc98125c548d892c.png
翻页帧动画

使用序列帧有什么好处?

  1. 可以保证图片质量 因为公众号后台会主动压缩上传的GIF图片,对图像质量要求较高的场景就不合适了。而使用序列帧,我们可以使用无损的PNG图片,保证动画高清显示。
  2. 动画更平滑 相对于GIF动画,程序控制的动画用户体验更加平滑流畅。

怎样使用序列帧?

在平常的web开发中,我们可以很容易地用js或者css实现类似的帧动画,由于公众号图文环境的限制,我们只能用SVG来实现这个效果,水果公号里用animate标签巧妙的解决这个问题。

通过把每一帧的图片单独放在一层里,并使每一层重叠在一起。使用透明度动画来控制每个图片帧的出现时间,产生连续播放的动画效果。

bd86c2038a506aa14369d349c8f90e69.png
花开动画帧演示
<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 style="height:${height};">
        <svg opacity="${opacity}" viewBox="0 0 828 828" style="width:100%;background-image:url('img/${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()

将生成的代码,在开发者工具中复制黏贴。

f913ad701be71801a0392b939390b72a.png

搞定,收工!

源码: https://dev.xingway.com/tutorials/svg/flowers.zip

594f39d5c8e0833255c7b2575a3feac5.png
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP