Javascript 如何在HTML5画布上移动绘制的图像?

Javascript 如何在HTML5画布上移动绘制的图像?,javascript,html,image,canvas,Javascript,Html,Image,Canvas,假设我有一个HTML5画布,我已经在上面绘制了多个图像,但我没有最终生成的图像“在手”,现在我想将画布中的整个图像向上移动?(就像用户选择“向下滚动”图像一样) 如果我有最终的图像,我可以清除画布,然后在负的y坐标中再次绘制,这样就行了。 问题是调用toDataUrl()以获取最终图像非常耗费CPU 还有其他方法可以做到这一点吗? 为什么我不能告诉画布将所有东西向上/向下移动x像素 谢谢 您可以使用ctx.getImageData()获取图像数据,并使用ctx.putImageData()将图像

假设我有一个HTML5画布,我已经在上面绘制了多个图像,但我没有最终生成的图像“在手”,现在我想将画布中的整个图像向上移动?(就像用户选择“向下滚动”图像一样)

如果我有最终的图像,我可以清除画布,然后在负的y坐标中再次绘制,这样就行了。 问题是调用toDataUrl()以获取最终图像非常耗费CPU

还有其他方法可以做到这一点吗? 为什么我不能告诉画布将所有东西向上/向下移动x像素


谢谢

您可以使用
ctx.getImageData
()获取图像数据,并使用
ctx.putImageData
()将图像数据放在所需的位置

编辑

不过,Kaido的解决方案是更好的选择

参考


您可以使用
ctx.getImageData
()获取图像数据,并使用
ctx.putImageData
()将图像数据放在所需的位置

编辑

不过,Kaido的解决方案是更好的选择

参考

Canvas
drawImage()
方法接受其他画布作为源。
您也可以在画布本身上绘制画布,但在每次迭代中,您的图像将 已经改变了

因此,最简单的方法是创建另一个画布,它将保留您的实际画布图像,并将此新画布绘制到文档中的画布:

var canvas=document.querySelector('canvas'),
ctx=canvas.getContext('2d'),
img=新图像(),
//将保留原始图像的鬼画布
gCanvas=document.createElement('canvas'),
gCtx=gCanvas.getContext('2d');
gCanvas.width=canvas.width;
gCanvas.height=canvas.height;
img.onload=函数(){
ctx.drawImage(img,0,0,canvas.width,canvas.height);
gCtx.drawImage(画布,0,0,canvas.width,canvas.height);
请求动画帧(向上移动);
}
img.src=”http://lorempixel.com/200/200";
var y=0;
函数moveUp(){
如果(--y<(画布高度*-0.5))返回;
clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(gCanvas,0,y,canvas.width,canvas.height);
requestAnimationFrame(向上移动)
}
Canvas
drawImage()
方法接受其他画布作为源。
您也可以在画布本身上绘制画布,但在每次迭代中,您的图像将 已经改变了

因此,最简单的方法是创建另一个画布,它将保留您的实际画布图像,并将此新画布绘制到文档中的画布:

var canvas=document.querySelector('canvas'),
ctx=canvas.getContext('2d'),
img=新图像(),
//将保留原始图像的鬼画布
gCanvas=document.createElement('canvas'),
gCtx=gCanvas.getContext('2d');
gCanvas.width=canvas.width;
gCanvas.height=canvas.height;
img.onload=函数(){
ctx.drawImage(img,0,0,canvas.width,canvas.height);
gCtx.drawImage(画布,0,0,canvas.width,canvas.height);
请求动画帧(向上移动);
}
img.src=”http://lorempixel.com/200/200";
var y=0;
函数moveUp(){
如果(--y<(画布高度*-0.5))返回;
clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(gCanvas,0,y,canvas.width,canvas.height);
requestAnimationFrame(向上移动)
}

我认为它至少和toDataURL一样消耗资源,不是吗?toDataURL将其转换为字符串。这个没有。好的方面是,一旦你有了第一步的数据,你就可以重复使用它多次,而无需再次执行getImageData。。。它会将其转换为数组,然后遍历该数组以重新绘制。。。没有GPU加速。对不起,我对GPU加速部分了解不够。但是我运行了一个快速测试,getImageData比toDataURL稍有优势。虽然很轻微…明白了-你所做的是最好的,我认为它至少和toDataURL一样消耗,不是吗?toDataURL将它转换为字符串。这个没有。好的方面是,一旦你有了第一步的数据,你就可以重复使用它多次,而无需再次执行getImageData。。。它会将其转换为数组,然后遍历该数组以重新绘制。。。没有GPU加速。对不起,我对GPU加速部分了解不够。但是我运行了一个快速测试,getImageData比toDataURL稍有优势。虽然很轻微…明白了-你所做的最好是不知道draw可以接受画布本身作为参数。这就成功了!!非常感谢!是的,它可以,但这样就很难得到你正在绘制的东西,因为每次你这样做,绘制的图像都会用最后绘制的图像更新。。。保留另一张画布更容易,上面画着我们想要的状态。@AmitKanfer如果它解决了您的问题,请记住“接受答案”,这要感谢左边的复选框,这样,其他回答者就不会在他们的“应该回答”列表中看到这个问题,他们不知道draw可以接受画布本身作为论点。这就成功了!!非常感谢!是的,它可以,但这样就很难得到你正在绘制的东西,因为每次你这样做,绘制的图像都会用最后绘制的图像更新。。。保留另一张画布更容易,上面画着我们的通缉状态。@AmitKanfer如果它解决了您的问题,请记住“接受答案”,这要感谢左边的复选框,这样,其他回答者就不会在他们的“应该回答”列表中看到这个问题