gpt4 book ai didi

canvas - chrome扩展 Canvas 不在循环内绘制图像

转载 作者:行者123 更新时间:2023-12-02 09:37:11 26 4
gpt4 key购买 nike

我正在尝试制作一个屏幕截图扩展,通过使用scrollTo移动窗口并在弹出窗口中将 Canvas 上的图像拼接在一起来截取整个页面的屏幕截图。然而,我的问题是,我返回的所有图像都没有被绘制/没有显示在 Canvas 上。

popup.js

function draw(ctx, image, x ,y) {
console.log(image);
var img = new Image();
img.src = image;
img.onload = function() {
ctx.drawImage(img, x, y);
console.log('x',x);
console.log('y',y);
};
}

function screenshot(response) {
console.log('screenshot');
var canvas = document.getElementById('imagecanvas'),
fullHeight = response.height,
fullWidth = response.width,
visibleHeight = response.visibleHeight,
visibleWidth = response.visibleWidth,
x = 0,
y = 0;

canvas.height = fullHeight;
canvas.width = fullWidth;

var ctx = canvas.getContext('2d');
// console.log('canvas', canvas);
// console.log('context', ctx);
//start at the top
window.scrollTo(0, 0);

while (y <= fullHeight) {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function (image) {
draw(ctx, image, x, y);
});

// console.log('x',x);
// console.log('y',y);

y += visibleHeight;
window.scrollTo(x, y);
}
}

chrome.tabs.query({
'active': true,
'currentWindow':true
}, function(tab){
console.log('sending message');
chrome.tabs.sendMessage(tab[0].id, {
message: 'dom'
}, function(response){
console.log('response', response);
screenshot(response);
});
});

popup.html

<!doctype html>
<html>
<head>
<title>Chrome Snapshot</title>
<style>
#imagecanvas {
z-index: 100;
}
</style>
<script src="jquery-2.0.2.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<canvas id="imagecanvas"> </canvas>
</body>
</html>

内容.js

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.message === 'dom') {
sendResponse({
height: document.height,
width: document.width,
visibleHeight: window.innerHeight,
visibleWidth: window.innerWidth
});
}
});

list .json

{
"manifest_version": 2,
"name": "test",
"description": "Save images and screenshots of sites to Dropbox.",
"version": "1.0",
"permissions": [
"<all_urls>",
"tabs"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": [
"jquery-2.0.2.min.js"
],
"persistent": false
},
"content_scripts" : [{
"all_frames": true,
"matches" : ["*://*/*"],
"js" : ["content.js"],
"run_at": "document_end"
}]
}

编辑以回应 Rob 的评论

这是我到目前为止所得到的:我可以看到页面正在滚动,但是现在,captureVisibleTab 中的图像返回为未定义。

popup.js

var ctx,
fullHeight,
fullWidth,
x,
y,
visibleHeight,
visibleWidth;

function draw(ctx, image, x ,y) {
console.log(image);
var img = new Image();
img.src = image;

img.onload = function() {
ctx.drawImage(img, x, y);
// console.log('x',x);
// console.log('y',y);
};
}

function next(tabID) {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function(image) {
console.log(image);
draw(ctx, image, x, y);
y += visibleHeight;

if (y < fullHeight) {
chrome.tabs.sendMessage(tabID, {
message: 'scroll',
x: x,
y: y
}, function() {
next(tabID);
});
}
});
}

function screenshot(response, tabID) {
console.log('screenshot');
var canvas = document.getElementById('imagecanvas');

fullHeight = response.height;
fullWidth = response.width;

visibleHeight = response.visibleHeight,
visibleWidth = response.visibleWidth;

x = 0,
y = 0;

canvas.height = fullHeight;
canvas.width = fullWidth;

ctx = canvas.getContext('2d');

chrome.tabs.sendMessage(tabID, {
message: 'scroll',
x: x,
y: y
}, function() {
next(tabID);
});
}

chrome.tabs.query({
active:true,
lastFocusedWindow:true
}, function(tab){
var tabID = tab[0].id;
console.log('sending message', tabID);
chrome.tabs.sendMessage(tabID, {
message: 'dom'
}, function(response){
console.log('dom info', response);
screenshot(response, tabID);
});
});

内容.js

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.message === 'dom') {
sendResponse({
height: document.height,
width: document.width,
visibleHeight: window.innerHeight,
visibleWidth: window.innerWidth
});
} else if (request.message == 'scroll') {
window.scrollTo(request.x, request.y);
sendResponse();
}
});

最佳答案

您的代码有两个重大问题。

第一个问题是您假设 window.scrollTo(0, 0);滚动选项卡的内容。这不是真的,它会滚动弹出窗口的文档。

第二个问题是您在循环中调用异步方法,该方法会更改 y每次迭代的变量。在这个captureVisibleTab的回调中,您正在阅读y再次变量,但由于循环结束时调用所有回调,因此它始终是相同的值。

顺便说一句,这个值也是错误的。您将循环直到 y <= fullHeight 。这实际上应该是 y < fullHeight ,因为一旦到达页面底部,就无需再进行屏幕截图。

至少,您需要将循环更改为一组(递归)回调。

// popup.js
function next() {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function (image) {
draw(ctx, image, x, y);
y += visibleHeight;

window.scrollTo(x, y); // TODO
next();
});
}
// Initialize recursion
next();

这个方法稍微好一点,至少你看到 Canvas 上正在画东西。但这仍然不正确,因为您仍在调用 window.scrollTo在弹出脚本中。解决此问题的正确方法是委托(delegate) scrollTo方法到内容脚本,并使用 message passing调用卷轴。例如:

// popup.js
//window.scrollTo(x, y); // TODO
//next();
chrome.tabs.sendMessage(null, {
request: 'scroll',
x: x,
y: y
}, next);

// contentscript.js
chrome.runtime.onMessage.addListener(function(message, sender,sendResponse) {
if (message.request == 'scroll') {
window.scrollTo(message.x, message.y);
sendResponse();
}
});

最后一个建议:我建议使用activeTab permission,而不是在所有选项卡中插入内容脚本。和 chrome.tabs.executeScript 在需要时插入内容脚本。这可以减轻您的扩展的重量,并且无需 <all_urls>许可。

关于canvas - chrome扩展 Canvas 不在循环内绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17519325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com