前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记GIF动画转CSS逐帧动画工具

记GIF动画转CSS逐帧动画工具

作者头像
GhostZhang
发布2022-08-22 08:45:26
1.3K0
发布2022-08-22 08:45:26
举报
文章被收录于专栏:CSS森林CSS森林

记GIF动画转CSS逐帧动画工具

Ghostzhang 发表于 2022-08-16 19:27

翻到了 2018 年左右团队支持的一个项目,当时看重构同学不断的在和设计师来回沟通调动画细节,就在想能不能提升下这里的效率,于是了解了下当时的实现过程,大概是这样的:

设计师用 PS 或其他工具输出 gif 动画图或视频给到前端开发,前端开发再对照着用 CSS 动画实现。开发会用用工具(如 PS)把 gif 图中每一帧的时间取出来,由于显示精度的问题,往往取到的时间会比较粗(秒),这就导致最终效果与设计师给出的还是会有差异,就感觉不对,因此还需要再进一步调整代码,于是就出现了需要反复沟通的现象。

CSS 动画,简单的说就是用 CSS3 的animation属性,设置@keyframes关键帧来实现的帧动画。(示例可以看这里 https://www.jianshu.com/p/05c5a9b302d2 )看完应该大概有了个概念。

现在进入主题,平时我们对帧动画的印象,大多是同一时间间隔的,像上面示例中的例子:

代码语言:javascript
复制
@keyframes run {
  0% {
    background-position: 0 0
  }
  10%{
    background-position: -100% 0
  }
  20%{
    background-position: -200% 0
  }
  30%{
    background-position: -300% 0
  }
  40%{
    background-position: -400% 0
  }
  50%{
    background-position: 0 -100%
  }
  60%{
    background-position: -100% -100%
  }
  70%{
    background-position: -200% -100%
  }
  80%{
    background-position: -300% -100%
  }
  90%{
    background-position: -400% -100%
  }
  100%{
    background-position: 0 0
  }
}

会发现每一帧的间隔都是一样的,大部分情况下效果也还不错。但如果遇到需要设置不同间隔的情况呢?

微信支付周末摇摇乐
微信支付周末摇摇乐

像周末摇摇乐这样的项目,界面上的动画是每一次活动运营的重点,对动画质量的要求会高很多,特别是在节假日时,会有专门的动画效果,为了让动画看起来更加的流畅,往往需要控制到每一帧的时长,这也让开发的实现难度有了增加。

那如何提高这个过程的效率呢?设想下,如果能读取 GIF 中每一帧的时间,是不是就能计算出来总的时长和每一帧所占的时间比。如果再自动给出相应的代码,嘿嘿……

GIF 图片解析

首先来找找 GIF 图中时间是在哪表示的,关于 GIF 图,在这里(What’s In A GIF)有很详细的说明

GIF图片格式
GIF图片格式

用支持十六进制的编辑器打开一张 GIF 图,就可以看到这样的一串数据。为方便分析,我用了一张 10*10 的小图,如下:

图片十六进制
图片十六进制

文件头

文件头
文件头

GIF 有两个版本,分别是 87a 和 89a,区别如下:

  • GIF87a:是在 1987 年年制定的版本。
  • GIF89a:是在 1989 年年制定的版本。在这个版本中,为图像互换格式⽂文档扩充 了了图形控制区块、备注、说明、应⽤用程序接⼝口等四个区块,并提供了了对透明⾊色 和多帧动画的⽀支持。

GIF87a

GIF89a

LZW 压缩

Y

Y

支持隔行扫描

Y

Y

支持透明度

N

Y

支持动画

N

Y

无限循环

N

Y

逻辑屏幕描述

逻辑屏幕描述
逻辑屏幕描述

全局调色板

全局调色板
全局调色板

图形控制扩展

图形控制扩展
图形控制扩展

可以看到图形控制扩展块的第五位、第六位字节表示就是当前帧的延时时间。注意这里是十六进制数,需要转成十进制才是我们需要的时间。

图像描述

图像描述
图像描述

图像数据

图像数据
图像数据

文件尾

文件尾
文件尾
GIF图十六进制字节解析
GIF图十六进制字节解析

工具化

知道了格式后,工具的思路就很简单了,查找到各图片帧的延时时间,通过数量就知道有多少帧,再计算各帧的时间与总时间的比例,转换成百分比,输出 CSS 就可以了。

实现出来的界面大概是这样

getGifDelayTime
getGifDelayTime

由于只是个临时工具,加上问题好像也很冷门,就没有对外开放了(差点源码都找不到了 😅 )。

更进一步的想法,就是读取 GIF 的每一帧图片,自动生成雪碧图1和 CSS 动画关键帧代码。不过这个功能用 air 不好实现,而且现有的前端工作流其实也支持类似的功能,像自动生成雪碧图等。搜了下,有个叫 ImageMagick 的图像处理库能很好解决这个问题,用法可以看这个《 「CSS3」ImageMagick - 从 gif 建立雪碧图动画 - Sprite Sheet Animation 》。至此,动画实现的效率有了明显提升,只希望项目能坚持得更长时间。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=uakteiz4tcry

  1. 雪碧图是根据 CSS sprite 音译过来的,就是将很多很多的小图标放在一张图片上,就称之为雪碧图。 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 记GIF动画转CSS逐帧动画工具
    • GIF 图片解析
      • 文件头
      • 逻辑屏幕描述
      • 全局调色板
      • 图形控制扩展
      • 图像描述
      • 图像数据
      • 文件尾
    • 工具化
    相关产品与服务
    图像处理
    图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档