调用context.translate()后,context.drawImage()如何记住原始的[0,0]画布坐标

How does context.drawImage() remember the original [0,0] canvas coordinates after context.translate() has been called?

本文关键字:context 坐标 布坐标 何记住 translate drawImage 原始 调用      更新时间:2023-09-26

当我在使用translate()后调用drawImage()时,如果两个调用都在绘图循环中,则drawImage()将以画布元素的原始x,y坐标为基础。但是,如果我在循环外连续执行它们,drawImage()将以新的[0,0]坐标值为基础绘制位置。为什么会出现这种情况?我一定是忽略了什么。谢谢你给我的启示!

我的循环:

function draw() {
    setTimeout(function() {
        requestAnimationFrame(draw);
        context.clearRect(0, 0, myCanvas.width, myCanvas.height);
        context.translate(offsetX, offsetY);
        context.drawImage(bgImg, 0, 0);

    }, 1000 / fps);
};
draw();

手动调用:

document.getElementById("contextTranslate").onclick = function() { context.translate(offsetX, offsetY) };
document.getElementById("contextClear").onclick = function() { context.clearRect(0, 0, myCanvas.width, myCanvas.height) };
document.getElementById("contextDraw").onclick = function() { context.drawImage(bgImg, 0, 0) };

小提琴:http://jsfiddle.net/3Lrwbpb4/2/

您需要重置画布矩阵并清除上下文。

您可以通过在translate(..)之前的context.save()和绘制之后的context.restore()来设置上下文的状态。

function draw() {
    setTimeout(function() {
        requestAnimationFrame(draw);
        context.save();
        context.clearRect(0, 0, myCanvas.width, myCanvas.height);
        context.translate(offsetX, offsetY);
        context.drawImage(bgImg, 0, 0);
        context.restore();
    }, 1000 / fps);
};
draw();

或者通过设置画布的宽度/高度,以简单而棘手的方式进行操作。

所以只需更改这条线

context.clearRect(0, 0, myCanvas.width, myCanvas.height);

myCanvas.width = myCanvas.width;

两种方法都有效-检查下面的片段

var myCanvas = document.getElementById("myCanvas");
var context = myCanvas.getContext("2d");
var bgImg = new Image();
bgImg.src = "https://www.google.co.uk/images/srpr/logo11w.png";
var fps = 60;
var offsetX = 0;
var offsetY = 0;
// Manual invocation
document.addEventListener("keydown",
  function(e) {
    if (e.keyCode == 81) {
      offsetX++;
    } else if (e.keyCode == 65) {
      offsetY++;
    } else if (e.keyCode == 87) {
      offsetX--;
    } else if (e.keyCode == 83) {
      offsetY--;
    }
  }, false);
var useTricky = true;
// Drawing loop
function draw() {
  setTimeout(function() {
    requestAnimationFrame(draw);
    if (useTricky) {
      myCanvas.width = myCanvas.width;
    } else {
      context.save();
      context.clearRect(0, 0, myCanvas.width, myCanvas.height);
    }
    context.translate(offsetX, offsetY);
    context.drawImage(bgImg, 0, 0);
    if (!useTricky) {
      context.restore();
    }
  }, 1000 / fps);
};
draw();
<canvas id="myCanvas" width="426px" height="240px"></canvas>
<div id="tools">
  <button type="button" id="contextTranslate">Translate</button>
  <button type="button" id="contextClear">Clear</button>
  <button type="button" id="contextDraw">Draw</button>
  Keys Q and A increase X,Y offset value, W and S decrease them.
</div>