雅荷心语博客
雅荷心语
心之所向便是光
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 关注本站
    • 微信
    • 微博
    • 腾讯微博
    • Twitter
    • Facebook
    • RSS订阅
Hi, 请登录     我要注册     找回密码

关于对逐帧动画的一次研究

2022-06-28 分类:前端之旅 / 心路历程 阅读(530) 评论(0)

很早以前, 就想对芊云全景的语音讲解模块做个卡通人物做讲解, 第一次调研的时候, 是想使用 live2D, 也就是我博客主页这只小猫咪的实现方式, 但是这个做模型的方法特别 复杂, 而且没有现成的可用的客服类模型, 于是就搁置了, 但是近期发现某20 云居然上线了这个语音讲解功能, 并且命名: 元宇宙 xxx, 于是我又开始调研其他方案。

第一种方案, 就是去年调研过的 live2D 技术, 做模型太复杂了放弃了

第二种方案: 想使用建模的方式, 做一个 fbx 模型, 带动画那种, 然后设定几组动画重复播放即可, 但是去淘宝问了一圈, 淘宝店家报价 1w, 果断放弃

第三种方案: 既然 3D 的搞不成, 那弄 2D 的总可以了吧, 结果淘宝报价 3000 元, 放弃

作为一个动漫专业毕业的来说, 总不能东西就不做了吧~ 开始寻找能在网页上直接制作 2D 动画的网站, 看看能不能找到一些有用的

果然找到了2个网站可以做类似的2D 动画:  一个叫来画, 一个叫万彩动画大师

来画这个软件研究了下, 动画动作比较简单, VIP 相对便宜一些,

万彩动画这个, 动画场景比较多, 有我能使用的东西, 但是 VIP 一个月 900 快, 真实忍不了啊,

还是扒素材看看吧, 开始分析这个网站的动画生成方案, 看了看, 发现了一些端倪,

这个网站的动画, 都是用序列帧做的, 每个动画, 都有一个类似的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "1": {
    "png": "595a95c6a3a9c6cf11c8bb74a92aee94.png",
    "json": "8bdadf1036cf4a33912d3200c9cc009c.json",
    "time": 5.16
  },
  "2": {
    "png": "55c831370bdd776bbf7b275e842f865a.png",
    "json": "b2bfa00187daa2741336a34d8bd96111.json",
    "time": 5.16
  },
  "3": {
    "png": "42d45f6958f4c583b3c4ef58bc731045.png",
    "json": "3f651a72df83b5bc9937e4713a3e75a1.json",
    "time": 5.16
  },
....

其中,

png 就是动画的序列帧图片,

json 是配置文件

刚开始看到这个序列帧图片, 我以为直接拿图片去解析播放就可以了, 于是简单写了一段 css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@keyframes run {
      from {
       background-position-x: 0;
      }
      to{
        background-position-x: -9196px;
      }
    }
    .play {
      background-image: url("r1.webp");
      background-repeat: no-repeat;
      width: 23px;
      height: 62px;
      position: absolute;
      animation: run 12s steps(42);
    }

但是发现不对, 这个动画播不起来了, 跳来跳去, 研究完发现他们的序列帧图的位置是不固定的, 我这种方式就用不了了,

然后开始分析了一下他们的 json 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
{
  "frames": [
 
  {
    "filename": "25-129-1.png",
    "frame": {"x":6517,"y":1,"w":139,"h":406},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":141,"y":120,"w":139,"h":406},
    "sourceSize": {"w":409,"h":614}
  },
.....

发现其中有 w 和 h 这两个参数, 猜测应该就是宽高了吧, 于是使用配置文件播放一次看看

随手引入一个 jq, 加载配置文件播放动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.get('6500.json').then(res=>{
   const frames =  res.frames
   const dom = document.querySelector('.play');
   let i = 0;
   setInterval(_=>{
     i++;
     if (i >= frames.length){
       i = 10;
     }
     dom.style.width = frames[i].frame.w + 'px';
     dom.style.height = frames[i].frame.h + 'px';
     dom.style.backgroundPositionX = -1 * frames[i].frame.x + 'px';
     dom.style.backgroundPositionY = frames[i].frame.y + 'px';
    
   }, 42)
})

果然是这样, 动画播起来了, 还算流畅, 但是也有问题

播放期间这个人物会来回跳, 不是站这里不动, 而官方他们的是不动的, 于是继续分析 json 文件, 发现他们使用了定位, 于是我也加上定位,

并且发现 spriteSourceSize 这个参数里有个 x 和 y, 值和第一帧是一样的, 于是把这个也带进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
$.get('6500.json').then(res=>{
   const frames =  res.frames
   const dom = document.querySelector('.play');
   let i = 0;
   setInterval(_=>{
     i++;
     if (i >= frames.length){
       i = 10;
     }
     dom.style.width = frames[i].frame.w + 'px';
     dom.style.height = frames[i].frame.h + 'px';
     dom.style.backgroundPositionX = -1 * frames[i].frame.x + 'px';
     dom.style.backgroundPositionY = frames[i].frame.y + 'px';
     dom.style.left = frames[i].spriteSourceSize.x + 'px';
     dom.style.top = frames[i].spriteSourceSize.y + 'px';
   }, 42)
})
</script>

播放了一下, 果然没有问题了,

后面给逐帧动画的人物简单调整一下, 多拼接几组动作, 瞬间感觉省了不少钱!

贫穷使我快乐

逐帧原图: https://online.xiuzhan365.com/tjuu/Draft/kpxq/files/extfile/ffd9374822dfa728db105eeaa382af6a.png?x-oss-process=image/format,webp/quality,lossless

配置文件: https://online.xiuzhan365.com/tjuu/Draft/kpxq/files/extfile/a913543e87bc73ace983f5a17d81b1f9.json

Snipaste_2022-06-28_16-37-57

分享到:更多 ()

相关推荐

  • 网页端使用JS识别人脸并且自动打马赛克
  • tinygo 安装及编译 wasm 笔记
  • go 语言编译wasm 在浏览器端实现cbc模式加解密
  • Service Worker简介及用法介绍
  • npm依赖管理之peerDependencies理解
  • 创建全新的 react 项目
  • 教你在npm上发布自己的vue组件
  • 关于如何获取浏览器的设备指纹的调研

评论 抢沙发

取消

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
关于我

小天明 北京·朝阳 前端搬砖工程师

碎碎念):(来自公众号)

热门文章

  • 踩坑记录——iphone上safari开启隐身模式时localStorage变为只读-雅荷心语博客踩坑记录——iphone上safari开启隐身模式时localStorage变为只读2017-02-21评论(4)
  • 程序员是怎样一群人-雅荷心语博客程序员是怎样一群人2015-12-08评论(3)
  • vcard - 二维码名片的格式及扫码导入-雅荷心语博客vcard – 二维码名片的格式及扫码导入2016-05-05评论(2)
  • PHPStorm10 下载安装破解汉化-雅荷心语博客PHPStorm10 下载安装破解汉化2015-12-15评论(2)
  • call_user_func_array 这个函数什么时候用-雅荷心语博客call_user_func_array 这个函数什么时候用2016-09-02评论(2)
2023年3月
一 二 三 四 五 六 日
« 一    
 12345
6789101112
13141516171819
20212223242526
2728293031  

最新评论

  • 前端小武 6年前 (2017-04-06)说:
    我看到了layer
  • 丁艳平 6年前 (2017-03-03)说:
  • Dawn 7年前 (2016-09-16)说:
    call_user_func_array最后的例子是错哦,你用bc方法去调用类里 另外一个方法就知道问题所在了。情况1.调用非静态方法 第一个参数应该传[类的实例,调用方法] (既然有类实例了直接-&
  • Dawn 7年前 (2016-06-21)说:
    tp框架设置了全局捕获异常的,这也没什么。坑的是 他捕获了异常。然后全部返回404。。。不知道的 还以为自己网站被删除了
  • Dawn 7年前 (2016-05-17)说:
    构造函数里的判断 用异常机制可能更好一些

左邻右舍

  • Brian's Blog
  • 易水寒
  • 楼教主
  • 贤心
  • 阿米龙

雅荷心语博客 -心之所向便是光

联系我们关于我们

© 2023 雅荷心语博客   网站地图

emlogdux_heademlogdux_footer