在我的reactjs应用程序中,我使用了一个名为pidegon-maps的轻量级地图库来显示船只位置。在不尝试使用更大的库(传单、谷歌地图反应)的情况下,我尝试为船只所走的路线制作动画。
从这个问题中汲取灵感,我尝试创建一个类似的实现。
useEffect(() => {
let start = [0.108266, 52.202758];
let end = [0.11556, 52.201733];
const speedFactor = 500;
let diffX = parseFloat(end[0]) - parseFloat(start[0]);
let diffY = parseFloat(end[1]) - parseFloat(start[1]);
let sfX = diffX / speedFactor;
let sfY = diffY / speedFactor;
let i = 0;
let j = 0;
let lineCoordinates = [];
while (i < diffX || Math.abs(j) < Math.abs(diffY)) {
lineCoordinates.push([start[0] + i, start[0] + j]);
if (i < diffX) {
i += …Run Code Online (Sandbox Code Playgroud) 我正在研究一个资源匮乏的Web应用程序,该应用程序严重依赖Raphael.js大约50%的动画使用,其余的我已经推出了自己的动画方法,它使用webkitRequestAnimationFrame和Web Audio API的context.currentTime将动画与音频组件同步.
我目前正在经历相当糟糕的表现,并且通过Raphael的来源我看到它也使用了requestAnimationFrame.当我的动画和Raphael's同时运行时,我遇到的大部分延迟似乎都会发生.这是因为requestAnimationFrame基本上每个绘制周期被调用两次吗?
基本上我要问的是基本上我是否必须重新推出我自己的raphael对象动画实现并将其粘贴到我现有的requestAnimationFrame中?
我使用Box2D和WebGL.Box2D需要一个恒定的帧速率(它的"世界"更新的时间步长).
function update(time) {//update of box2d world
world.Step(
1/60 // 1 / frame-rate
, 3 //velocity iterations
, 8 //position iterations
);
Run Code Online (Sandbox Code Playgroud)
但我已经读过如下定义的requestAnimFrame是正确的方法.
requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000/60);
};
})();
Run Code Online (Sandbox Code Playgroud)
requestAnimFrame没有给我一个恒定的帧速率,所以我的Box2D的变量是不同步的.
有没有解决这个问题?
[编辑]
实施时John的(Cutch)解决方案如下所示:
function interpolate(dt) {
var t = dt/time_step;
body_coordinates = (1-t) * body_coordinates + t * next_body_coordinates;
}
var physicsDt = 0;
function tick() …Run Code Online (Sandbox Code Playgroud) 我正在构建一个具有视差滚动背景的网站,类似于spotify.com主页.我正在使用transform3d移动图像并认为我将动画包装在requestAnimationFrame中以提高性能.在Chrome中运行良好但在Firefox中我看到一些白色闪烁,其中图像正在重绘.实际上,当动画不在requestAnimationFrame中时,Firefox似乎工作得更好.有谁知道为什么会这样或我如何进一步优化?
这是源代码的链接:
http://codepen.io/fatlinesofcode/pen/xcnKh
和bug的截图.

我在JSFiddle中做了一个快速简单的解决方案,以便更好,更快地解释:
var Canvas = document.getElementById("canvas");
var ctx = Canvas.getContext("2d");
var startAngle = (2*Math.PI);
var endAngle = (Math.PI*1.5);
var currentAngle = 0;
var raf = window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
function Update(){
//Clears
ctx.clearRect(0,0,Canvas.width,Canvas.height);
//Drawing
ctx.beginPath();
ctx.arc(40, 40, 30, startAngle + currentAngle, endAngle + currentAngle, false);
ctx.strokeStyle = "orange";
ctx.lineWidth = 11.0;
ctx.stroke();
currentAngle += 0.02;
document.getElementById("angle").innerHTML=currentAngle;
raf(Update);
}
raf(Update);
Run Code Online (Sandbox Code Playgroud)
http://jsfiddle.net/YoungDeveloper/YVEhE/3/
当浏览器选择fps时,我如何独立于帧速旋转环.因为目前,如果速度是30fps,它将旋转得更慢,但如果速度提高60fps,因为它的旋转量是为每次调用添加的.
正如我从几个线程中了解到它与getTime有关,我真的尝试但无法完成它,我需要在10秒内旋转一次.
另一件事是,角度,它会越来越多,经过很长一段时间它会崩溃,因为可变的最大量将超过,所以我如何制作无缝旋转帽?
谢谢你的阅读!
识别: 我正在寻找所有可能的解决方案,用于检测由于浏览器优化性能而导致FPS下降或重新绘制/回流在浏览器中停止发生的时间,因为文档区域不在视野范围内.
观察: 到目前为止,我研究过的大多数原生HTML/JS解决方案都没有考虑到DOM的一部分,这部分被页面的其他部分所掩盖,或者是在首屏之下的DOM.有时内容将直接嵌入父文档中,有时可能在框架或iframe中.
测试结果: mozPaintCount是窗口dom回流的精确表示,当窗口或框架中的文档被遮挡时,它会正确响应.似乎Firefox正确识别dom的部分而不是在它们被遮挡时重新绘制它们,当某些东西不在视野时可以通过firefox检查器工具进行目视检查,但是检查员在绘制时可能不会考虑视图层次结构.重新粉刷区域的亮点.感谢你,Mozilla!
当屏幕关闭时,Flash也显示FPS减速,最新的Flash Player 11.2有一个专用事件,当出于优化原因被浏览器限制时会触发该事件.Flash也不是值得信赖的解决方案,因为它在许多浏览器中默认禁用.
页面可见性更改事件的当前浏览器实现能够在窗口已更改为另一个选项卡或窗口变为非活动时进行广播,但不考虑折叠下方的元素/窗口/文档的滚动位置或其他模糊DOM.然而,在本规范的第二稿中,已经建议浏览器考虑视口和DOM层次结构以提供更准确的结果.
参考文献:推荐页面可见性,2011年和草案页面可见性,2013年
当CSS元素被遮挡时,它们似乎不会被优化掉,因此无法正确测量它们.我尝试了许多不同的属性导致回流(高度,宽度,框阴影等),并且无法从中获得任何有意义的指标.
requestAnimationFrame似乎仅在更改选项卡并且浏览器窗口变得模糊时才限制动画,但不处理折叠以下的内容.此外,由于raf仅附加在窗口级别,因此无法绑定到特定的dom节点(在其实现中似乎是短视的).
我还没有完成对WebGL的测试,但是这仅限于少数现代浏览器(对于旧版浏览器,闪存解决方案可接受的结果).
我还没有完成测试画布,但这可能是一个很好的解决方案,因为它得到了比WebGL更广泛的浏览器支持.
我甚至没有开始考虑嵌入式对象以及它们可以提供的内容.
我没有查看ActiveX控件,看看是否有任何可能有帮助的东西.
我没有看过HTML5视频.
动画GIF似乎只在Firefox中进行了优化.再次感谢,Mozilla!
因此,每个浏览器供应商如何优化页面呈现的神秘和魔力继续扼杀我的进步.然而,单独的元素位置不能仅依赖于元素实际上是否可见的真实指示,因为页面可能具有使框架内容模糊的其他层,或者内容可能以排除任何有意义的可见渲染的方式显示(例如更改内容的三维旋转,使其不可见.)
任何关于浏览器如何实际优化显示内容或其他方向或该问题的实际答案的头脑风暴都受到欢迎.
同样,这是一个较旧的SO问题,也部分包含了这个问题.
我的目标是创建一个有效的游戏循环,该循环requestAnimationFrame用于更新显示画布和setTimeout更新游戏逻辑。我的问题是我应该将所有绘图操作放到requestAnimationFrame循环中还是仅将更新HTML画布的主绘图操作放到循环中?
我所说的“所有绘制操作”是所有缓冲。例如,我将所有的精灵绘制到缓冲区,然后将缓冲区绘制到主画布。一方面,如果我将所有缓冲放入其中,则requestAnimationFrame不会在每次逻辑更新时都浪费cpu绘图,另一方面,绘图会占用大量cpu并可能导致requestAniomationFrame等待所有这些操作完成...将逻辑更新与绘图分开的目的是requestAnimationFrame不会因非绘图处理而陷入困境。
有没有人对使用这种创建游戏循环的方法有任何经验?而且不要说“只把它全部放进去requestAnimationFrame”,因为这会减慢渲染速度。我坚信将逻辑与绘图分开是必经之路。这是我正在谈论的示例:
/* The drawing loop. */
function render(time_stamp_){//First parameter of RAF callback is timestamp.
window.requestAnimationFrame(render);
/* Draw all my sprites in the render function? */
/* Or should I move this to the logic loop? */
for (var i=sprites.length-1;i>-1;i--){
sprites[i].drawTo(buffer);
}
/* Update the on screen canvas. */
display.drawImage(buffer.canvas,0,0,100,100,0,0,100,100);
}
/* The logic loop. */
function update(){
window.setTimeout(update,20);
/* Update all my sprites. */ …Run Code Online (Sandbox Code Playgroud) 如果我强迫它继续使用25 FPS,是否值得使用请求动画帧.这就是我要问的原因:
正常的RAF行为:
a1000ms / 60 fps = 16.66a这是大多数监视器的标准刷新率.
将FPS降至30:
1000 / 30 = 33.33 这正是60的一半,这意味着每个其他RAF执行都会做一些逻辑和一致的事情
将FPS降至25:
1000 / 25 = 40 这是不可分的16.66(屏幕更新的通常RAF时间)
有了这个逻辑,我将不得不每隔40毫秒抽取一些东西到屏幕上,但这是不可能的,因为一帧是16.66.
我通过标准代码降低帧数:
fps = 25,
renderRate = 1000 / fps,
function animation(timestamp) {
draw.requestAnimationFrame = requestAnimationFrame(animation);
now = timestamp;
elapsed = now - then;
if (elapsed > renderRate) {
then = now - (elapsed % renderRate);
//Some code for execution goes here
}
}
Run Code Online (Sandbox Code Playgroud) 我一直在试验HTML5画布上复杂场景的无抖动渲染.我们的想法是将渲染分成多个批次,每个批次最多占用12毫秒,这样就不会中断同时运行的动画(非常便宜的执行).
从概念上讲,批量渲染的实现方式如下:
function draw(ctx) {
var deadline = window.performance.now() + 12; // inaccurate, but enough for the example
var i = 0;
requestAnimationFrame(function drawWithDeadline() {
for (; i < itemsToRender.length; i++) {
if (window.performance.now() >= deadline) {
requestAnimationFrame(drawWithDeadline);
return;
}
var item = itemsToDraw[i];
// Draw item
}
});
}
Run Code Online (Sandbox Code Playgroud)
完整的代码在这个JSFiddle中:https://jsfiddle.net/fkfnjrc2/5/ .代码执行以下操作:
不幸的是,在重新渲染画布内容的时候,我正好看到了可怕的janks.我似乎无法解释的是Chrome开发者工具时间轴的样子:
丢帧似乎是由于requestAnimationFrame在帧开始时没有调用,而是在理想的16ms周期结束时调用.如果在前一帧完成渲染之后立即开始回调,则代码很可能会及时完成.
渲染到离屏画布(https://jsfiddle.net/fkfnjrc2/6/),然后将完整的图像复制到屏幕画布有点帮助,但是janks仍然存在完全相同的特征(延迟执行rAF回调).
这段代码出了什么问题?或者我的浏览器/机器可能有问题?我在Windows 10和Mac OS上的Chrome(49.0.2623.112)上看到了相同的行为.
javascript performance animation canvas requestanimationframe
我有一个网页上运行,用画JavaScript客户端requestAnimationFrame到画布上,并通过沟通的WebSockets到我的NodeJS后端服务器(使用"WS"模块在服务器端).
使用Chrome DevTools进行分析,似乎每帧的脚本,渲染和绘制的总时间最多只有几毫秒.然而,仍有20至40毫秒的长时间帧.
时间线显示,在几乎所有这些情况下,都存在超过帧长度的"响应"和/或朝向末端发生的"复合层".
这基本上就是我使用requestAnimationFrame的方式:
function drawGame() {
// Drawing to gameCanvas from cacheCanvas
// cacheCanvas is updated whenever an update is received from the server
ctx.drawImage(cacheCanvas,
// source rectangle
0, 0,
gameCanvas.width*2, gameCanvas.height*2,
// destination
100, 100,
gameCanvas.width*2, gameCanvas.height*2
);
requestAnimationFrame(drawGame);
}
requestAnimationFrame(drawGame);
Run Code Online (Sandbox Code Playgroud)
服务器使用setInterval()以60hz发送更新.当从服务器收到消息时,客户端立即绘制它.我怀疑这个时间与requestAnimationFrame结合可能是不正确的,并且导致帧结尾处的复合层.
即使这样,我也很困惑为什么在每个帧的脚本和"复合层"之间有这么多空闲时间.所以...
有没有办法控制何时调用"复合层"?
我应该保存每个更新消息中的数据,只在下一个动画帧的开头绘制它吗?
什么是"回应"指的是什么?
谢谢!
javascript ×9
canvas ×3
html5 ×2
performance ×2
animation ×1
box2d ×1
css ×1
dom ×1
dom-events ×1
firefox ×1
game-loop ×1
maptiler ×1
node.js ×1
parallax ×1
raphael ×1
reactjs ×1
rotation ×1
settimeout ×1
webgl ×1