HTML画笔移出画布停止,javascript-HTML5画布与requestAnimationFrame一起撕裂

更新:整个问题最终导致系统图形驱动程序出现问题,而不是(貌似)浏览器/ API问题.撕破的帧归结为实际显示更新.再次感谢那些参与讨论并尝试提供帮助的人.

我有一个页面使用画布和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的情况下还能做些什么吗?

任何建议表示赞赏. TY全部: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;

}

}

其次,您的绘制函数是连续绘制的,至少从您发布的代码的第2行设置了cached_frame来说,所以它始终是真实的,并且总是在绘制.如果要以某种方式部分更新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);

来源:https://www.icode9.com/content-1-564351.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值