【问题标题】:Canvas image behaviour normal in Safari, but not other browsers画布图像行为在 Safari 中正常,但在其他浏览器中不正常
【发布时间】:2014-10-23 04:43:53
【问题描述】:

我已成功在 Safari 中将图像加载到我的画布元素中。它表现正常,我可以按预期在画布上移动它。但是,在 Firefox、Chrome 或 IE 中进行测试时,图像会加载,但只要我按下一个键移动它,图像就会消失。

我查看了Image drawn on canvas not displayed in Google Chrome,并认为加速 2D 功能也可能导致它无法正确绘制,但这已被禁用。我真的不确定是什么导致了这个问题?

编辑:我也从控制台收到以下错误: “未捕获的安全错误:无法在‘CanvasRenderingContext2D’上执行‘getImageData’:画布已被跨域数据污染。checkForCollision drawFrame”

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title> My title </title>
  </head>
  <h2>Your current time:</h2>
  <h1>
    <label class="timer" id="minutes">00</label>:<label id="seconds">00
     </label>
  </h1>

<body>
  <section>
    <canvas id="canvas"> </canvas>
    <img id="sprite" src="http://i.imgur.com/dudnUyL.png"> 
    <div>
       <h3><button id="resetme" onclick="loadHard()">Reload Maze</button></h3>
    </div>
    <script type="text/javascript">
    var canvas;
    var context;
    var x = 0;
    var y = 0; //positioning of the sprite
    var dx = 0;
    var dy = 0; //momentum of the sprite at start

    window.onload = function() {
     canvas = document.getElementById("canvas");
     context = canvas.getContext("2d");
     //ctx.save();
     drawMaze("http://i.imgur.com/Fbhw8NT.png", 268, 225);
     window.onkeydown = processKey;
   };

   var timer;

   function drawMaze(mazeFile, Xstart, Ystart) {
     clearTimeout(timer);
     dx = 0;
     dy = 0; //if the sprite is already moving, stop it
     var imgMaze = new Image();
     imgMaze.onload = function() {
       canvas.width = imgMaze.width;
       canvas.height = imgMaze.height;
       context.drawImage(imgMaze, 0,0);
       x = Xstart;
       y = Ystart;

      var imgSprite = document.getElementById("sprite");
      context.drawImage(imgSprite, x, y);
      context.stroke();
      timer = setTimeout(drawFrame, 10); 
    };
    imgMaze.src = mazeFile;
  }

  function processKey(e) { //e needs to be used for event handling
    dx = 0;
    dy = 0;

    //condition for the Up arrow being pressed
    if (e.keyCode == 38) {
      dy = -1;
    }

    //condition for the Left arrow being pressed
    if (e.keyCode == 37) {
      dx = -1;
    }

    //condition for the Down arrow being pressed
    if (e.keyCode == 40) {
      dy = 1;
    }

    //condition for the Right arrow being pressed
    if (e.keyCode == 39) {
       dx = 1;
    }
//all of the above numbers from 37-40 are representative of ASCII values
}

function checkForCollision() {
  var imgData = context.getImageData(x-1, y-1, 15+2, 15+2);
  var pixels = imgData.data;

  for (var i = 0; n = pixels.length, i < n; i += 4) {
    var red = pixels[i];
    var green = pixels[i+1];
    var blue = pixels[i+2];
    var alpha = pixels[i+3];
    //now check for the black pixels for a wall
    if (red == 0 && green == 0 && blue == 0) {
      return true;
    } //checks for a greyish colour - possibly the edge of a wall
    if (red == 169 && green == 169 && blue == 169) {
      return true;
    }
  }
  return false; //there was no collision 
}

function drawFrame() { 
  if (dx != 0 || dy != 0) {
    context.beginPath();
    context.fillStyle = "rgb(254,244,207)";
    context.rect(x, y, 15, 15);
    context.fill() 

    x += dx;
    y += dy;

   if (checkForCollision()) { 
      x -= dx;
      y -= dy;
      dx = 0;
      dy = 0;
   }


   var imgSprite = document.getElementById("sprite");
   context.drawImage(imgSprite, x, y);


   if (y > (canvas.height - 17)) {
     alert("You succeeded - hooray! That, or Pi's done..");
     clearInterval(timeout);
     minutesLabel.innerHTML = secondsLabel.innerHTML = "00";
     location.reload();
     return;
   }
 }

  timer = setTimeout(drawFrame, 10);
  }

  function loadHard() {
    drawMaze('http://i.imgur.com/Fbhw8NT.png', 268, 225);
    console.log('idle');
    totalSeconds = -1;
    setTime();
  }

 //just some more JS code about a timer 

</script>
</section>
</body>
</html>

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    这实际上似乎是大多数浏览器检查的安全问题。 How to fix getImageData() error The canvas has been tainted by cross-origin data?

    这会导致阻止页面工作的 JavaScript 错误。在将所有图像加载到画布之前,我可以通过将所有图像转换为 DataURL 来实现此功能,但您可能想尝试上面链接中的其他一些建议。

    【讨论】:

    • 谢谢!使用数据 URL 似乎确实有效,如果在其中包含所有 base 64 有点不方便。
    猜你喜欢
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    相关资源
    最近更新 更多