【问题标题】:Smooth javascript animation流畅的javascript动画
【发布时间】:2009-08-24 12:54:15
【问题描述】:

这里有一些代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
body { margin:0; padding:0; }
#a {
    position:absolute;
    background:#0FF;
    left:0;
    height:300px;
    width:120px;
}
input, #a {
    margin:10px;
}
</style>
<script>
function foo() {
    box = document.getElementById('a');
    var computedStyle = box.currentStyle || window.getComputedStyle(box, null);
    box.style.left = parseInt(computedStyle.left) + 10 + 'px';
    setTimeout("foo()",20);
}
</script>
</head>

<body>
<input type="button" value="RUN, FORREST, RUN!" onClick="setTimeout('foo()',20)">
<div id="a"></div>
</body>
</html>

如您所见,它在页面上对 DIV 进行了动画处理,但动画并不清晰流畅—— DIV 的边框实际上发生了变形。 有人知道我怎样才能让它正常工作吗?

【问题讨论】:

  • 您能否定义“变形”...它在我的机器上的行为符合预期。
  • 在 3D 游戏中看起来像“VSync 已关闭”

标签: javascript animation


【解决方案1】:

同上 JustLoren:它在我的机器上运行良好。我不确定你所说的边界“变形”是什么意思......也许你在谈论tearing?如果是这样,恐怕您无能为力。

传统的撕裂解决方案是等待 vsync 绘制下一帧,但这种能力在 JavaScript 中不可用。没有框架可以修复它。 (框架爱好者:请不要再向你不懂的 JavaScript 问题建议“使用 my_favourite_framework!它解决所有问题!”。)

正如 mck89 所建议的那样,您当然可以通过绘制更多帧来使动画更平滑(这也可以减少撕裂的影响),但代价是占用更多 CPU 资源来执行。您可能还希望保留一个变量来存储您的 x 值,而不是每次都从 currentStyle 解析它。它会更简单,浏览器支持更广泛。

ETA 重新评论:在 JS 中没有具体的最小超时时间(有时我可以将其降低到 1 毫秒),但是你可以从动画中获得多少 fps 高度取决于浏览器和机器的能力,这就是为什么通常最好将位置/帧基于自动画开始以来经过的时间量(使用 new Date().getTime()),而不是每帧移动/更改固定量。

在任何情况下,您实际上可以做到的最快速度大约是使用 16 毫秒的间隔,这对应于 60Hz 显示器上的一帧(通常的纯平默认设置)。

【讨论】:

  • 提高 FPS 是一种简单而好方法,但似乎浏览器不支持它(看:function foo() { box = document.getElementById('a'); var computedStyle = box.currentStyle | | window.getComputedStyle(box, null); box.style.left = parseInt(computedStyle.left) + 1 + 'px'; setTimeout("foo()",10); } 它看起来很流畅。但是移动很慢,因为JS 中的最小间隔为 10 毫秒 |=> 最大速度为每秒 100 像素。((
  • 我知道这个话题很老了,但是当我读到:“在 JS 中没有具体的最小超时时间”之后,在阅读“停止向你不理解的 JavaScript 问题提出 [解决方案]”之后,我只有说些什么。请阅读ejohn.org/blog/analyzing-timer-performance
【解决方案2】:

您应该将左坐标增加 1 px 并为间隔设置一个较低的时间。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
body { margin:0; padding:0; }
#a {
    position:absolute;
    background:#0FF;
    left:0;
    height:300px;
    width:120px;
}
input, #a {
    margin:10px;
}
</style>
<script>
function foo() {
    box = document.getElementById('a');
    var computedStyle = box.currentStyle || window.getComputedStyle(box, null);
    box.style.left = parseInt(computedStyle.left) + 1 + 'px';
    setTimeout("foo()",1);
}
</script>
</head>

<body>
<input type="button" value="RUN, FORREST, RUN!" onClick="setTimeout('foo()',20)">
<div id="a"></div>
</body>
</html>

【讨论】:

  • 是的。我试过了。使用 1px 步长看起来不错,但移动速度很慢。在大多数浏览器中似乎是 10 毫秒内的最小超时,这就是对象移动不太快的原因
【解决方案3】:

JQuery 和 YUI 以及几乎所有其他 js 库都提供动画实用程序,也许您应该研究一下。

【讨论】:

  • 我喜欢不加评论的反对票。如果你问我,不是很有建设性。
  • 你是对的,不是很有建设性。我的观点:jQuery 和 YUI 也没有解决“平滑”问题。它们更容易编码,但也有同样的问题。我正在寻找解决方案,但仍然没有找到任何解决方案。干杯。
【解决方案4】:

根据我的经验,mootools (http://mootools.net) 提供了最流畅的动画。

【讨论】:

  • 人们学习演奏乐器的原因是一样的。世界上有很多伟大的专辑,但人们仍在重新发明轮子。他们正在学习演奏自己的音乐:)
猜你喜欢
  • 1970-01-01
  • 2019-03-21
  • 2012-02-04
  • 2012-01-13
  • 2013-05-12
  • 2014-10-30
  • 2010-11-07
  • 2017-07-01
  • 1970-01-01
相关资源
最近更新 更多