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

Javascript 调用context.translate()后,context.drawImage()如何记住原始[0,0]画布坐标?,javascript,html5-canvas,Javascript,Html5 Canvas,使用translate后调用drawImage时,如果两个调用都在绘图循环中,则drawImage的x,y坐标将基于canvas元素的原始x,y坐标。但是,如果我在循环外连续执行它们,drawImage将根据新的[0,0]坐标值确定其绘图位置。为什么会这样?我一定是忽略了什么。谢谢你对这件事的解释 我的循环: function draw() { setTimeout(function() { requestAnimationFrame(draw); co

使用translate后调用drawImage时,如果两个调用都在绘图循环中,则drawImage的x,y坐标将基于canvas元素的原始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) };

小提琴:

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

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.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);

两种方法都有效-请检查下面的代码段

var myCanvas=document.getElementByIdmyCanvas; var context=myCanvas.getContext2d; var bgImg=新图像; bgImg.src=https://www.google.co.uk/images/srpr/logo11w.png; var fps=60; var offsetX=0; var offsetY=0; //手动调用 document.addEventListenerkeydown, 功能{ 如果e.keyCode==81{ offsetX++; }否则,如果e.keyCode==65{ offsetY++; }否则,如果e.keyCode==87{ 抵销x-; }否则,如果e.keyCode==83{ 偏位-; } },假; var=true; //绘图循环 函数图{ setTimeoutfunction{ 请求动画框架绘制; 如果有用的话{ myCanvas.width=myCanvas.width; }否则{ context.save; context.clearRect0,0,myCanvas.width,myCanvas.height; } context.translateoffsetX,offsetY; context.drawImagebgImg,0,0; 如果!用诡计{ 语境恢复; } },1000/帧; }; 画 翻译 清楚的 画 关键点Q和A增加X、Y偏移值,W和S减少它们。
.translate命令是累积的。因此,如果您翻译10,0三次,那么您的原点将位于画布位置[30,0]。如果您希望在绘制后将原点重置为[0,0],可以使用translate-10,0撤消原始平移。这两种方法的工作方式与我预期的一样:当您按qwas键时,图像会移动。是的,但使用手动方法重新绘制图像时,图像不会显示在原始0,0坐标处,它会将10,0或20,0等视为0,0。但是,使用循环时,即使重新绘制,图像也不会将10,0或20,0视为其0,0位置。这就是让我困惑的地方。