【问题标题】:Why toDataURL() not working when I draw image on canvas?为什么我在画布上绘制图像时 toDataURL() 不起作用?
【发布时间】:2015-10-18 07:21:24
【问题描述】:

我的页面中有画布和 <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 页面,左侧是画布,右侧是图像元素。

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():预计这一衬里将克隆图像,并且在画布上绘制的任何光栅绘图都作为图像放置并用作&lt;img&gt; 元素的源。

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

【问题讨论】:

    标签: html canvas


    【解决方案1】:

    关于你的代码,这两个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();
    };
    

    所以当checkAllDone 运行时,window.todo(您在第 3 行中声明的todo)总是1,它显然会失败。

    详细了解this,注意函数上下文变体之间的区别。

    由于您已经声明了一个全局todo 指标,最简单的解决方法是使用todo 而不是this.todo

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

    未捕获的安全错误:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布。

    你可以找到答案here

    【讨论】:

      猜你喜欢
      • 2019-10-18
      • 2018-10-20
      • 2011-08-07
      • 2020-09-27
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      相关资源
      最近更新 更多