Canvas chrome扩展画布未在循环内绘制图像

Canvas chrome扩展画布未在循环内绘制图像,canvas,google-chrome-extension,html5-canvas,Canvas,Google Chrome Extension,Html5 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);

我试图做一个屏幕截图扩展,通过滚动窗口移动整个页面的屏幕截图,并在弹出窗口的画布上将图像缝合在一起。然而,我的问题是,我得到的所有图像都没有被绘制/没有显示在画布上

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);
  });
});
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);
  });
});
manifest.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"
  }]
}

您的代码有两个重要问题

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

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


顺便说一下,这个值也是错误的。您一直循环到
y尝试
document.createElement('img')而不是
新图像()。在映像构造函数的实现中有一个bug-请参见“否”,它没有解决问题。当我使用activeTabs时,如何发送没有选项卡id的消息?将null用于tabid在@Raptrex时不起作用。事件接收到一个
Tab
类型的参数,该参数将ID提供为
ID
属性。无法使用browserAction.onClicked,因为:
在单击浏览器操作图标时激发。如果浏览器操作有弹出窗口,则不会触发此事件。
@Raptrex我根据您的评论更新了我的帖子-从captureVisibleTab返回的图像返回未定义
{
  "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"
  }]
}
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);
  });
});
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();
    }
  });
// 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();
// 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();
    }
});