无意中使用多个imgdata

时间:2018-03-25 16:44:31

标签: javascript image html5-canvas filereader

我有一个包含img标签和画布的div。当我将图像拖入div时,img.src会发生变化,新图片会出现,而在画布中,会使用img标签中的数据绘制一个点画化动画。

当我将imgA拖放到div中时,imgA出现在img标签中,并且画布使用imgA进行动画,这就是我想要的。

问题在于:

从这一点来说,如果我将imgB拖放到div中,imgB会出现在img标签中,但是,画布动画使用的是imgA + imgB数据。

我认为我所做的就是:

  1. 我将图片拖放到div中。
  2. img.src更改
  3. 加载imim后,我调整大小并清除画布
  4. 我在画布上绘制新的img
  5. 函数pointillize获取新的画布数据并将其用于绘制到画布上的动画
  6. 我认为它与clearRect()有关,我试着实施一些建议,但我不这么认为。我在文档中添加了一个click事件监听器,它确实清除了画布。

    它可能与setInterval有关吗?我现在想的是,当加载新图像时,它会触发setInterval以同时运行 以前的setInterval()?也许解决方案是在加载新的img后杀死所有以前的setInterval函数?

    编辑:它现在完美运作。我声明绘制一个全局变量,并在设置draw = setInterval()之前在函数pointillize()内部我使用clearInterval(draw)。这会在我开始一个新的之前擦除setInterval函数。

    HTML:

    <div id='container'>
      <img id='output' src='file.jpg'/>
    </div>
    

    的javascript

    var container, output;
    var c, ctx, draw; // draw is declared here as a global variable
    
    window.onload = function(e) {
    
      c = document.createElement('canvas');
      ctx = c.getContext('2d');
      document.getElementById('container').appendChild(c);
    
      output = document.getElementById('output');
      output.width = '400';
    
      container = document.getElementById('container');
      container.style.border = '2px dashed rgb(200, 200, 200)';
      container.style.padding = '6px';
    
      container.addEventListener('dragenter', function(e) {
        e.stopPropagation();
        e.preventDefault();
        this.style.border = '2px dashed rgb(50, 50, 50)';
      }, false);    
    
      container.addEventListener('dragover', function(e) {
        e.stopPropagation();
        e.preventDefault();
        this.style.border = '2px dashed rgb(50, 50, 50)';
      }, false);
    
      container.addEventListener('dragleave', function(e) {
        e.stopPropagation();
        e.preventDefault();
        this.style.border = '2px dashed rgb(200, 200, 200)';
      }, false);
    
      container.addEventListener('drop', function(e) {
        e.stopPropagation();
        e.preventDefault();
        this.style.border = '2px dashed rgb(200, 200, 200)';
    
        var reader = new FileReader();
        reader.addEventListener('load', function(e) {
          output.src = e.target.result;
    
          // once the new src img is loaded
          output.onload = function() {
    
            c.width = output.width;
            c.height = output.height;
            ctx.clearRect(0, 0, c.width, c.height);
            ctx.drawImage(output, 0, 0, output.width, output.height);
            pointillize(ctx);
    
          }     
    
        }, false);
    
        reader.readAsDataURL(e.dataTransfer.files[0]);  // this line!
    
      }, false);
    }
    
    function pointillize(context) {
    
      clearInterval(draw);  // before a new animation, clear setInterval
    
      // get new image data
      var imgData = context.getImageData(0, 0, c.width, c.height);
    
      // clear canvas
      ctx.beginPath();
      ctx.rect(0, 0, output.width, output.height);
      ctx.fillStyle = 'rgba(255, 255, 255, 1)';
      ctx.fill();
    
      // store the setInterval in a variable so it can be cleared
      var draw = setInterval(function() {  
    
        for (var i = 0; i < 100; i++) {
    
          // pick random integers x and y
          var y = Math.floor(Math.random()*output.height);
          var x = Math.floor(Math.random()*output.width);
    
          // get its position in the array
          var loc = (y*output.width + x)*4;
    
          // alpha in rgba goes from 0 to 1
          var r = imgData.data[loc];
          var g = imgData.data[loc+1];
          var b = imgData.data[loc+2];
          var a = 0.5;
    
          ctx.beginPath();
          ctx.arc(x, y, 2, 0, 2*Math.PI);
          ctx.fillStyle = 'rgb(' + r + ',' + g + ', ' + b + ',' + a + ')';
          ctx.fill()
        }
    
      }, 50);  // closing setInterval()
    }
    
    document.addEventListener('click', clearCanvas, false);
    
    function clearCanvas() {
      //interesting, so clearRect is working, for one frame...
      ctx.clearRect(0, 0, c.width, c.height);  
    }
    

0 个答案:

没有答案