我在这里做的是我覆盖了加载了画布层的整个网页。现在,在该画布上,用户单击并单击该按钮创建一个点。此时调用createDot()
函数。
在createDot()
内,点被绘制到画布上,然后屏幕截图请求被发送到后台脚本。
现在的问题是,当我点击画布并拍摄截图时,屏幕截图中不会出现点。
现在奇怪的是,当我在同一个画布上点击第二个点并且屏幕截图到来时,它现在是我点击的第一个点而不是第二个点。
所以发生的事情是屏幕截图不捕获当前点,而只捕获前面的点。
我检查了画布绘图功能是否全部阻塞,因此在绘图完成之前无法将请求发送到后台脚本。我也通过登录控制台确认了相同的内容。
内容脚本:
function createDot(canvas) {
var context = canvas.getContext("2d");
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var pointX , pointY;
var point_X,point_Y;
function handleMouseDown(e) {
//coordinates of the click in dom.
pointX = parseInt(e.pageX - offsetX);
pointY = parseInt(e.pageY - offsetY);
//making the dot
var radius = 10;
context.beginPath();
context.arc(pointX, pointY, radius, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 2;
context.strokeStyle = '#003300';
context.stroke();
console.log("drawn everything");
takeDotScreenshot(); //gets called when the canvas has finished its job of drawing.
}
$("#canvas").mousedown(function (e) {
handleMouseDown(e);
});
}
function takeDotScreenshot() {
console.log("sending request to Background script");
chrome.runtime.sendMessage({"capture":true},function(response) {
var img_src=response.screenshot;
});
//logic for using that screenshot and appending it on to the content page...
}
后台脚本:
chrome.runtime.onMessage.addListener(function(request,sender,sendResponse) {
if(request.capture) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.captureVisibleTab(null, {}, function(dataUrl) {
if(dataUrl) {
sendResponse({"screenshot":dataUrl});
}
});
});
}
return true;
});
更新
如果我使用1ms的setTimeout来调用takeDotScreenshot函数,一切正常。为什么!
setTimeout(takeDotScreenshot, 1);
答案 0 :(得分:0)
屏幕截图是用户可以看到的快照。在渲染函数内部时,在执行堆栈为空(从函数中一直返回)之前,画布不会显示以供显示。
根据渲染方式(使用requestAnimationFrame或直接从鼠标,键盘,计时器事件),画布仍然需要时间呈现给显示器。
当您将超时设置为零时,您可以在将画布呈现给显示之前运行的调用堆栈上添加一个调用。您运行的任何代码都将阻止页面,从而阻止显示画布,因此无法进行屏幕截图。
我会将渲染时的超时设置为至少17ms(超过60fps)。没有人会注意到这种延迟,但是有足够的时间将画布呈现给显示器
答案 1 :(得分:0)
有一个非常详细的好答案,为什么setTimeout在这里有帮助: https://stackoverflow.com/a/4575011/10574621
画布的DOM更新事件(实际上使点可见)可能在拍摄屏幕事件的后面,即使画布从stroke()事件中接收了所有需要的数据。