问题行在handleLineEnd
函数中。我撕掉了所有不需要显示问题的行。
没有线条:我可以在ctx上画多个矩形。
使用线:每个矩形都被下一个矩形覆盖。
代码在较旧的Chrome(118.0.5993.71)中运行良好,而在版本119.0.6045.106中无法运行
function handleLineEnd(evt) {
{
startDrawing = false;
var dummy = ctx.getImageData(3, 3, 5, 5); // problem line
ctx.drawImage(canvaslayer, 0, 0);
ctxlayer.clearRect(0, 0, el.width, el.height);
}
}
字符串
var el = document.getElementById("canvasID");
var elcontainer = document.getElementById("containerID");
var ctx = el.getContext('2d');
var startpuntX, startpuntY, eindpuntX, eindpuntY;
var startDrawing = false;
var container = el.parentNode; // Add the temporary canvas.
var containerHandletje = document.getElementById('containerID');
var ongoingTouches = new Array();
var huidigeKleur = 'black';
var huidigeDikte = 2;
var selectie = document.getElementById('drawingtoolID');
elcontainer.setAttribute("style", 'width: ' + (window.innerWidth - 12) + 'px; height: ' + (window.innerHeight - 80) + 'px; overflow: auto;');
el.height = window.innerHeight - 90;
el.width = window.innerWidth - 42;
canvaslayer = document.createElement('canvas');
canvaslayer.id = 'imageTemp';
canvaslayer.width = el.width;
canvaslayer.height = el.height;
canvaslayer.style = 'touch-action:none;';
container.appendChild(canvaslayer);
ctxlayer = canvaslayer.getContext('2d');
ctxlayer.lineCap = 'round';
ctx.lineWidth = 1;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.fillStyle = 'white'
ctx.fillRect(0, 0, el.width, el.height);
ctx.lineWidth = huidigeDikte;
canvaslayer.addEventListener('pointerdown', handleLineStart, false);
canvaslayer.addEventListener('pointerup', handleLineEnd, false);
canvaslayer.addEventListener('pointermove', handleLineMove, false);
function handleLineStart(evt) {
startpuntX = evt.clientX - el.offsetLeft + pageXOffset + containerHandletje.scrollLeft;
startpuntY = evt.clientY - container.offsetTop + pageYOffset + containerHandletje.scrollTop;
ctxlayer.lineWidth = huidigeDikte;
ctxlayer.strokeStyle = huidigeKleur;
ctxlayer.fillStyle = huidigeKleur;
startDrawing = true;
ctxlayer.stroke();
ctxlayer.beginPath();
handleLineMove(evt);
}
function handleLineMove(evt) {
var x, y, w, h, hokDx, xi, yi, asX, asY, asXeind, asYeind, fontsize, dzx, dzy, situatie;
if (startDrawing) {
eindpuntX = evt.clientX - el.offsetLeft + pageXOffset + containerHandletje.scrollLeft;
eindpuntY = evt.clientY - container.offsetTop + pageYOffset + containerHandletje.scrollTop;
ctxlayer.clearRect(0, 0, el.width, el.height);
ctxlayer.beginPath();
ctxlayer.moveTo(startpuntX, startpuntY);
x = Math.min(startpuntX, eindpuntX);
y = Math.min(startpuntY, eindpuntY);
w = Math.abs(startpuntX - eindpuntX);
h = Math.abs(startpuntY - eindpuntY);
ctxlayer.strokeRect(x, y, w, h);
ctxlayer.stroke();
ctxlayer.beginPath();
}
}
function handleLineEnd(evt) {
{
startDrawing = false;
var dummy = ctx.getImageData(3, 3, 5, 5); // problem line
ctx.drawImage(canvaslayer, 0, 0);
ctxlayer.clearRect(0, 0, el.width, el.height);
}
}
#containerID {
position: relative;
}
#canvasID {
border: 1px solid #000;
}
#imageTemp {
position: absolute;
top: 1px;
left: 11px;
}
<div id="containerID" style="touch-action:none; width: 100px; height: 500px; overflow: auto;">
<canvas id='canvasID' width='80' height='80' style='margin-left:10px;background:white;border:solid black 1px; touch-action:none; '>
Your browser does not support canvas element.
</canvas>
</div>
2条答案
按热度按时间watbbzwu1#
这是一个已知且已修复的Chrome错误(CRBUG 1500272和CRBUG 1499539),由this CL引起。基本上,他们正在重写画布层逻辑,当这些被刷新时,这会搞砸。粗略地说,调用
getImageData()
确实会将层从GPU移动到CPU,这种更改使桥接器无法正确处理这种移动,使GPU端没有资源提供者。请注意,我们可以将bug repro减少到:
个字符
可能的变通方法:
不要使用加速画布。通过使用
willReadFrequently
选项请求2D上下文,可以避免画布被移动。如果您要在画布上执行多次回读,您可能真的需要考虑此选项,即使没有bug。移动画布非常慢,你可能通过硬件加速赢得了一点(这可能甚至不太取决于你画的是什么),将在这些调用中丢失。的字符串
如果你真的认为你必须使用一个加速画布,那么你可以使用一个
OffscreenCanvas
而不是canvaslayer
<canvas>
元素。OffscreenCanvas
不会导致这个bug(无论出于什么原因)。的字符串
但是从代码中,由于需要
layercanvas
可见,因此应该使用layercanvas.transferControlToOffscreen()
而不是构造函数,这样<canvas>
元素就变成了一个占位符画布,并且仍然将其内容绘制到屏幕上。但这是一个丑陋的黑客周围,一个错误,已经被修复,并应消失在下一个Chrome版本(目前的Chrome测试版已经修复)。
z9smfwbn2#
有一些库可以做到这一切,甚至更多,你的代码看起来会简单得多,例如http://fabricjs.com/,它允许你添加形状,并给予用户控制位置,旋转和尺寸,你也可以对形状进行分组或使其不可选。
看看我下面的示例,我添加了3个矩形到一个组,并添加了一个事件侦听器,双击将添加一个新的矩形,用户可以稍后修改。
的数据
个字符