我想知道在画布中更改形状位置的最佳方法是什么。
以下是我所拥有的:
'use strict';
(function() {
const canvas = document.getElementsByClassName('canvas')[0],
c = canvas.getContext('2d');
//
c.beginPath();
c.moveTo(0, 50);
c.quadraticCurveTo(0, 0, 50, 0);
c.quadraticCurveTo(100, 0, 100, 50);
c.quadraticCurveTo(100, 100, 50, 100);
c.quadraticCurveTo(0, 100, 0, 50);
c.stroke();
})();

<canvas class="canvas" width="500" height="500"></canvas>
&#13;
现在,形状位于0,0。如果我想沿X方向移动它,理论上我可以这样做:
c.beginPath();
c.moveTo(x+0,50);
c.quadraticCurveTo(x+0,0,x+50,0);
c.quadraticCurveTo(x+100,0,x+100,50);
c.quadraticCurveTo(x+100,100,x+50,100);
c.quadraticCurveTo(x+0,100,x+0,50);
c.stroke();
实现这一目标的正确方法是什么?
答案 0 :(得分:2)
当你问 时“我想知道在画布中更改形状位置的最佳方法是什么。”
答案是 使用转换矩阵
使用坐标的直接操作是非常低效的。
2D API提供了一整套用于转换(移动)渲染任何内容的方法。
这些方法是;
(每个链接到MDN)
除了ctx.putPixelData
之外,它们会将您呈现的任何内容移动到画布因此,通过x和y移动对象,您可以使用
c.translate(x,y); // move the following coordinates by x, and y;
c.beginPath();
c.moveTo(0, 50);
c.quadraticCurveTo(0, 0, 50, 0);
c.quadraticCurveTo(100, 0, 100, 50);
c.quadraticCurveTo(100, 100, 50, 100);
c.quadraticCurveTo(0, 100, 0, 50);
c.stroke();
或者直接用
设置变换 c.setTransform(1, 0, 0, 1, x, y);
c.beginPath();
c.moveTo(0, 50);
c.quadraticCurveTo(0, 0, 50, 0);
c.quadraticCurveTo(100, 0, 100, 50);
c.quadraticCurveTo(100, 100, 50, 100);
c.quadraticCurveTo(0, 100, 0, 50);
c.stroke();
如果您不熟悉矩阵操作,这些可能很难理解,因为上面列表中的方法2,3,4,5是现有矩阵的乘法。方法1只是替换现有的矩阵,而不受先前转换的影响。
这是一个非常简单的函数,它将移动一个对象并包括缩放和旋转。
// rotation is in radians and rotates the x and y axis
// scaleX scales along the new xAxis
// scaleY scales along the new yAxis
// x and y translate to the desired screen coordinates
function position(ctx, x, y, scaleX, scaleY, rotation){
var scaleRatio = scaleY / scaleX;
var rx = Math.cos(rotation) * scaleX;
var ry = Math.sin(rotation) * scaleX;
ctx.setTransform(rx, ry, -ry * scaleRatio, rx * scaleRatio, x, y);
}
致电
position(ctx,100,100,2,0.5, Math.PI/4)
移动在调用100,100像素后绘制的任何内容,使其宽度增加一倍,高一半,并顺时针旋转45度
恢复为默认值
position(ctx, 0, 0, 1, 1, 0);
或更快
ctx.setTransform(1, 0, 0, 1, 0, 0);
有关更详细的说明
如何使用setTransform以及为什么它优先于其他方法,请参阅this answer
答案 1 :(得分:1)
你有正确的想法。只需确保您在绘制之间清除画布,以确保您不会覆盖画布上当前的内容。然后你可以只更新一些x
值,你可以在任何地方绘制它。您可以将此扩展为使用某个y
值,以便您也可以垂直移动它。
'use strict';
(function() {
const canvas = document.getElementsByClassName('canvas')[0],
c = canvas.getContext('2d');
var x = 0;
function render() {
c.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
c.beginPath();
// Adjust path based on x position
c.moveTo(x, 50);
c.quadraticCurveTo(x, 0, x + 50, 0);
c.quadraticCurveTo(x + 100, 0, x + 100, 50);
c.quadraticCurveTo(x + 100, 100, x + 50, 100);
c.quadraticCurveTo(x, 100, x, 50);
c.stroke();
// Doing this for animation
x += 5;
if (x > canvas.width) {
x = -100;
}
requestAnimationFrame(render);
}
render();
})();
&#13;
<canvas class="canvas" width="500" height="500"></canvas>
&#13;