当我在画布上绘制图像时,为什么toDataURL()不起作用?

时间:2015-07-27 22:29:04

标签: html5 canvas

我的页面中有画布和<img>元素,我只是尝试克隆/复制画布上绘制的img元素。我没有问题,只要我单独使用绘图命令并克隆图像,但是当我绘制图像时,它不会克隆任何东西。

HTML

<canvas id="canvas" width="600" height="400">Default Text (No JS)</canvas>

<img id="img" alt="This is dynamic image" src="https://www.gravatar.com/avatar/c585e7964ff782b11a41d19679e43e9d?s=48&d=identicon&r=PG&f=1" style="position:fixed;top:0;right:400px">

一个简单的HTML页面,左侧是画布,右侧是image元素。

JS

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var todo = 0;

drawImage(); //commenting this would clone the canvas
drawCloud(); 
checkAllDone();

function checkAllDone(){

  if (this.todo ==0) copyCanvas();

}
function drawImage(){
  this.todo++;
  var img = new Image();
  img.onload = function(){ 
                  context.drawImage(img,0,0,200,200);
                  this.todo--;
                  checkAllDone();
                };
  img.src = 'http://i.stack.imgur.com/RxFwQ.png?s=64&g=1';

}

function drawCloud(){
      context.beginPath();
      context.moveTo(170, 80);
      context.bezierCurveTo(130, 100, 130, 150, 230, 150);
      context.bezierCurveTo(250, 180, 320, 180, 340, 150);
      context.bezierCurveTo(420, 150, 420, 120, 390, 100);
      context.bezierCurveTo(430, 40, 370, 30, 340, 50);
      context.bezierCurveTo(320, 5, 250, 20, 250, 50);
      context.bezierCurveTo(200, 5, 150, 20, 170, 80);
      context.closePath();
      context.lineWidth = 5;
      context.fillStyle = '#8ED6FF';
      context.fill();
      context.strokeStyle = '#0000ff';
      context.stroke();
      checkAllDone();
}

function copyCanvas(){
  var img = document.getElementById('img');
  img.src = canvas.toDataURL();
  //img.src = context.getImageData();


}

现在这是一个非常简单的脚本,其中主要有三个函数

drawImage():这会将图像绘制到上下文中 drawCloud():使用看起来像云的绘图命令绘制形状 copyCanvas():这个衬垫应该克隆图像,画布上绘制的光栅图纸将作为图像放置,并作为<img>元素的源。

Twist是当我同时绘制Image和Cloud时,copyCanvas将无法按预期工作。 image元素不会复制画布内容。好像我注释掉了drawImage,然后它正确地复制了画布内容。那是为什么?

1 个答案:

答案 0 :(得分:0)

关于您的代码,这两个 this 实际上是window

function checkAllDone(){
  if (this.todo ==0) copyCanvas();
}


function drawImage(){
  this.todo++;
  // ......

虽然img.onload内的img确实是img.onload = function(){ context.drawImage(img,0,0,200,200); this.todo--; checkAllDone(); };

window.todo

todo运行时,1(您在第3行中声明的checkAllDone)总是todo,而且显然会失败。

  

详细了解this,注意功能背景变体之间的区别。

由于您已声明全局todo指标,因此最简单的解决方法是使用this.todo代替p <- ggplot(df, aes(x, y)) p <- p + xlab("xlabel") p <- p + ylab("ylabel") p <- p + ggtitle("ylabel vs xlabel") p <- p + geom_bar(stat="identity", aes(fill=MaskID)) p <- p + theme(axis.text.x = element_text(angle=90, vjust=-0.005)) p <- p + geom_text(aes(label = ifelse(y != 0, as.character(MaskID), ''), angle=90))

但是,修复后你会遇到另一个问题:

  

Uncaught SecurityError:无法执行&#39; toDataURL&#39; on&#39; HTMLCanvasElement&#39;:可能无法导出受污染的画布。

您可以找到答案here