原文:fanmingfei.com/posts/Why_T…

背景

过年的项目中遇到一个问题让我百思不得其解,明明我的帧率保持在60帧,为何我的动画却一直抖动?

我的场景是一个匀速直线运动的小姐姐。

先上一个 Demo

在这个 Demo 中,小姐姐是按照 x 轴 10px/s,y 轴 30 px/s 进行移动的,不过她的移动是明显伴随着抖动的。

这到底是怎么了呢?

解决

如果小姐姐的y轴速度是 10px/s,我们的帧率是 60f/s,计算一下:

10 / 60 = 1/6 (px/f)
复制代码

实际上,的实际速度是每 6 帧才会移动 1px,这当然会有抖动,小姐姐走一步停一会,总感觉怪怪的~

我索性把小姐姐的移动速度调快,调成 100px/s,发现,还是会抖动,以为高高兴兴能解决了这个问题,发现还是没那么简单。

既然我们能算,那我们就算一算

100 / 60 = 10/6 (px/f) = 1.666666....(px/f)
复制代码

写了个for循环,看看一秒中每一帧小姐姐都在什么位置

for(let i = 0; i < 60; i ++) {console.log(i*10/6)
}
复制代码

输出结果取小数点后两位是这样的:

0.00 1.67 3.33 5.00 6.67 8.33 10.00 11.67 13.33 15.00 16.67 18.33 20.00 21.67 23.33 25.00 26.67 28.33 30.00 31.67
33.33 35.00 36.67 38.33 40.00 41.67 43.33 45.00 46.67 48.33 50.00 51.67 53.33 55.00 56.67 58.33 60.00 61.67 63.33
65.00 66.67 68.33 70.00 71.67 73.33 75.00 76.67 78.33 80.00 81.67 83.33 85.00 86.67 88.33 90.00 91.67 93.33 95.00 96.67 98.33
复制代码

那么作为浮点数,Canvas 将如何定位呢?

我们来写一个 Demo

使用 Chrome 打开,作为一个像素眼,我发现,小姐姐定位在 50.6px 的时候,其实就已经被渲染到 51px 的位置。

所以在 Chrome 中,drawImage 中设置的位置最终会被四舍五入,这可能和 CSS Sub-pixel 有关 这里先不探究。

所以真正的位置其实是

 0 2 3 5 7 8 10 12 13 15 17 18 20 22 23 25 27 28 30 3233 35 37 38 40 42 43 45 47 48 50 52 53 55 57 58 60 62 63 6567 68 70 72 73 75 77 78 80 82 83 85 87 88 90 92 93 95 97 98
复制代码

从数值来看,每帧移动的距离可能是 1px 也可能是 2px,小姐姐可能是在边跳芭蕾边走路喽~

既然这样,60 帧的帧率下,设置 60px/s 就可以解决问题了,尝试了一下,真的可以!

总结

前端动画/游戏开发 requestAnimationFrame 之 锁帧 这篇文章介绍过,在项目中我们可能对动画进行锁帧,帧率可能是 60 或者 30,如果我们想保证渲染不抖动,在匀速直线运动中,我们尽量保证我们设置的速度要是帧率的倍数,或者保证平均每帧移动的像素点是一样的。

drawImage 中,不建议使用浮点数进行定位。

为何 Canvas 内元素动画总是在颤抖?相关推荐

  1. 前端实现图片快速反转替换_HTML5开发之canvas实现元素图片镜像翻转动画效果的方法...

    一.Canvas图片水平镜像翻转效果预览 您可以狠狠的点击这里:canvas图片水平镜像翻转动画demo demo页面中点击图片动画效果可见. 二.Canvas上实现图片镜像翻转的实现 CSS中要想实 ...

  2. react + canvas点线动画背景

    效果图 实现步骤 1.public文件夹中的index.html引入 2.将变量存起来 // 引入 <script src='./Dot.js'></script> // 变量 ...

  3. 前端必备的Canvas接口和动画效果的总结

    来源 | https://segmentfault.com/a/1190000021998875 概述 <canvas>元素用于生成图像.它本身就像一个画布,JavaScript 通过操作 ...

  4. 必备的Canvas接口和动画效果大全

    来源 | https://segmentfault.com/a/1190000021998875 1.概述 <canvas>元素用于生成图像.它本身就像一个画布,JavaScript 通过 ...

  5. html++鼠标跟随动画,5分钟实现Canvas鼠标跟随动画背景

    关于Canvas制作炫酷背景,我会在git上不定时去更新,并会附上详细的解析,如果有喜欢的话,可以到git上瞧瞧 前言 相信很多前端小白都看过这样的背景动画,也好奇如何去实现这种效果!将这种效果应用到 ...

  6. 090_块元素行内元素行内块元素空元素

    1. 块元素指的是占据全部可用宽度的元素, 并且在其前后都会换行(display: block). 1.1. 定义整个文档(非常重要): <html></html> 1.2. ...

  7. css变换transform 以及 行内元素的一些说明

    变换transform的用法比较简单:[变换其实和普通的css属性,如color等没什么区别,可以为变换应用过渡或动画,就像其他普通css属性一样] #test { transform: transl ...

  8. [css] img标签是行内元素,为什么却能设置宽高

    [css] img标签是行内元素,为什么却能设置宽高 原来CSS中还有一个概念:可替换元素MDN上是这么解释的:在 CSS 中,可替换元素(replaced element)的展现效果不是由 CSS ...

  9. 行内元素和块级元素的区别,为何img、input等行内元素可以设置宽高??(夯实基础)

    我们习惯将html中元素分类为行内元素和块级元素,如下: ·常见块级元素有:html.body.div.header.footer.nav.section.aside.article.p.hr.h1~ ...

最新文章

  1. python 二叉树中所有距离为k的节点_leetcode 二叉树中所有距离为 K 的结点
  2. 深入入门正则表达式(java) - 匹配原理 - 1 - 引擎分类与普适原则
  3. 正则表达式(中文表达:检查表达式符)
  4. 如何快速切换静态和动态ip
  5. 安装mysql显示有5.0_安装MySQL5.0时到如图这一步提示出错了,~
  6. 拉力测试软件界面,电脑拉力机/电脑控制拉力试验机软件操作界面与功能
  7. 技巧:在Silverlight中如何访问外部xap文件中UserControl
  8. 阳黎盛:4.11美联储预计加息,脱欧被顺延!
  9. 64位Win8企业版出现“Unknown Hard Error”系统警告的一个解决方法
  10. 关于解决Windows server系统用户无法远程的问题
  11. 前大嗅万万没想到系列之520奇葩礼物大盘点,活着不好吗?
  12. 电脑连不上wifi的三种处理办法。
  13. FabFilter Pro-R 混响效果器
  14. 【懒人版】labview 软件加密+试用期限制+绑定硬件
  15. MIMO-OFDM学习笔记(传播与衰落)
  16. 小马的白痴日常2019.12.20
  17. scala spark sql 获得分组后的分位点
  18. HMM模型 forward backward viterbi算法
  19. poi导入数据工具类,直接复制使用,有详细注释
  20. python绘制热图

热门文章

  1. php程序设计简明教程
  2. 开发辅助工具Kalman Studio2.0发布,内置基于T4的代码生成器
  3. Oracle10g数据库的树立
  4. 【JS】逻辑运算符 非! 与 或||(处理对象时注意)
  5. 解决LSP问题导致无法上网
  6. keras保存模型_TF2 8.模型保存与加载
  7. vue取通过key取value_彻底理解Vue中的Watcher、Observer、Dep
  8. 计算机结构介绍,计算机系统结构介绍.pdf
  9. html中的分页条怎么写,如何写分页(含HTML)
  10. python修饰器原理_Python修饰器的函数式编程