- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
更新:这整个问题最终成为系统图形驱动程序的问题,而不是(看似)浏览器/API 问题。撕裂的框架归结为实际的显示更新。再次感谢那些参与讨论并试图提供帮助的人。
我的页面使用 Canvas 和 2d 上下文以 720p 显示预渲染帧。我正在单独渲染帧并使用新的 ImageData 更新变量。然后,在 requestAnimationFrame 中,我只需执行 context.putImageData(cached_image_data);
。尽管提前完全渲染了帧并有效地进行了双缓冲,但我仍然经常撕裂。我在 SO 上发现了沿着这些思路的其他一些问题,但它们都以“使用 RAF”结尾。代码归结为:
var canvas = document.getElementById("canvas");
var cached_frame = new ImageData(new Uint8ClampedArray(canvas.width * canvas.height * 4), canvas.width, canvas.height);
var context = canvas.getContext("2d");
var framerate = 30;
function draw() {
if (cached_frame)
context.putImageData(cached_frame, 0, 0);
requestAnimationFrame(draw);
}
setInterval(function() {
var frame = context.getImageData(0, 0, canvas.width, canvas.height);
// Do things to manipulate frame.data.
// Save the resultant pixel data for the cached_frame.
cached_frame.data = frame.data;
}, 1000 / framerate);
draw();
如果不求助于 webgl,我还能做些什么吗?
任何建议表示赞赏。全部 :D
最佳答案
我不认为代码在做你认为它在做的事情
首先,据我所知,您不能将新数据分配给 ImageData,所以这一行
cached_frame.data = frame.data;
什么都不做。我们可以测试显示它不起作用的东西
var ctx = document.createElement("canvas").getContext("2d");
document.body.appendChild(ctx.canvas);
var imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
var data = new Uint8ClampedArray(imageData.length);
// fill imageData.data with red
fillWithColor(255, 0, 0, 255, imageData.data);
// fill data with green
fillWithColor(0, 255, 0, 255, data);
// assign imageData.data to data
imageData.data = data;
// Draw. If assigning imageData.data works result will
// be green, if not result will be red
ctx.putImageData(imageData, 0, 0);
function fillWithColor(r, g, b, a, dst) {
for (ii = 0; ii < dst.length; ii += 4) {
dst[ii + 0] = r;
dst[ii + 1] = g;
dst[ii + 2] = b;
dst[ii + 3] = a;
}
}
其次,您的 draw
函数正在连续绘制,至少从您发布的代码来看 cached_frame
设置在第 2 行,因此它始终为真并且始终为正在画画。如果您以某种方式部分更新 cached_frame
中的实际数据,那么它将在只有部分结果时绘制。
我想你想要这样的东西
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var frame;
var framerate = 30;
function draw() {
context.putImageData(frame, 0, 0);
}
setInterval(function() {
frame = context.getImageData(0, 0, canvas.width, canvas.height);
// Do things to manipulate frame.data
// frame is ready, draw it at next rAF
requestAnimationFrame(draw);
}, 1000 / framerate);
如果您认为解码比 raf 更快,您可能想检查抽奖是否已经排队。不过,我认为在这种情况下您实际上不需要 rAF。我很确定您可以在 setInterval 结束时绘制,它会显示下一帧,不会撕裂。
这是一个测试,它对我来说不是撕裂。
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var frame;
var framerate = 30;
var frameCount = 0;
setInterval(function() {
++frameCount;
frame = context.getImageData(0, 0, canvas.width, canvas.height);
var data = frame.data;
var width = frame.width;
var height = frame.height;
// Do things to manipulate frame.data
for (var yy = 0; yy < height; ++yy) {
for (var xx = 0; xx < width; ++xx) {
var offset = (yy * width + xx) * 4;
data[offset + 0] = ((xx >> 2 & 0x1) ^ frameCount & 0x1) ? 255 : 0;
data[offset + 3] = 255;
}
}
// frame is ready, draw it at next rAF
context.putImageData(frame, 0, 0);
}, 1000 / framerate);
<canvas id="canvas" width="1280" height="720"></canvas>
关于javascript - HTML5 Canvas 与 requestAnimationFrame 撕裂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35645278/
假设我们有一个功能/模块,可以增强网站。所以这并不是真正必要的,它使用 requestAnimationFrame,即 not supported in older browsers比如IE8/9。我
“requestAnimationFrame”方法在以下示例中不起作用。控制台不显示任何错误消息。那么这段代码的错误是什么?HTML:
我有以下 JavaScript: function animate() { // call other function offset += 3; if (offset > 15) offset =
我有一些基本脚本可以将文本左右滚动,我尝试将其从 timeout 转换为 requestAnimationFrame,但是,我无法制作它有效。 function slideHorizontal(e,
我遇到了这个奇怪的问题,我递增了 1,但是,弹出 javascript 窗口时出现的增量显示我已递增了 9 或 13,这两者都来自于我是否分别增加 1 或 -1。这是怎么回事? 这是 requestA
我试图了解有关 requestAnimationFrame 的一件事。 在下面的示例代码中,我运行了 60 次,这应该与您通常获得的典型每秒 60 帧相匹配,因此它应该持续 1 秒。然而我故意通过调用
有人可以分享一下在动画循环中应该在哪里进行 RequestAnimationFrame 调用吗?它应该在循环的开头还是循环的结尾?我已经多次看到它在循环开始时使用它,但是位于循环底部不是更好吗?这样在
我尝试为很多 svg 路径设置动画,但功能不起作用 错误: Uncaught RangeError: Maximum call stack size exceeded function dashOf
我有一张滑动图片沿着屏幕缓慢移动。一旦它们离开屏幕,它们就会背靠背靠在丝带上。因此,当您在网页上时一切正常,但当您离开并且其中一张图像超出范围时。它会被放回错误的地方。我认为这可能与 requestA
我在使用 requestAnimationFrame() 时遇到了性能问题。 考虑以下代码。这是一个简单的循环,每次时间增量大于 20 毫秒时,都会打印自上一帧以来的时间。 const glob_ti
根据我的阅读,requestAnimationFrame 可以判断浏览器何时失去焦点。发生这种情况时是否会触发某种事件?我正在寻找暂停和恢复与 requestAnimationFrame 相关的代码。
let pf = document.querySelectorAll('.pf'); for (let i of pf) { Object.assign(i.style, { left:
我最近看了 Jake Archibald 的演讲。他在演讲中举了一个例子,他说使用 requestAnimationFrame 两次来延迟应用 CSS 样式来执行 CSS 动画。 参见https://
我正在使用 requestAnimationFrame 为视频流设置动画,我知道请求动画在后台不起作用,所以有什么方法可以让它在后台运行。 我知道我们也可以使用 setInterval 或 setTi
我是编程新手,面对这个功能: function update(time = 0) { console.log(time); requestAnimationFrame(update);
我正在尝试使用 JavaScript 和 requestAnimationFrame 制作一个简单的计时器(从 0 开始计数)。单击某些内容时,我想从 0 开始计时。目前我的代码在单击按钮时显示计时器
如果我有以下代码: window.requestAnimationFrame(animation1); //animation1 takes more than 16.67ms, misses the
我有一个带有 requesetAnimationFrame 的动画,当我重播它时,它变得越来越快,直到它变得不可见。 function tirer(){ var missile=documen
我有一个问题: document.querySelector('div').addEventListener('mousedown', function(){ hello = true
我有一种情况,我想在 1 秒内将 600px 宽的 div 的宽度设置为 0px。为此,我可以使用 requestAnimationFrame()。但我真的不能 100% 确定动画是否需要 1 秒。
我是一名优秀的程序员,十分优秀!