繁体   English   中英

在画布上移动形状

[英]Moving shape on canvas

我想知道更改画布中形状位置的最佳方法是什么。

这是我所拥有的:

 '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> 

因此,现在该形状位于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();

实现此目标的正确方法是什么?

当您问到“我想知道在画布中更改形状位置的最佳方法是什么时”。

答案是通过使用变换矩阵

使用坐标的直接操作效率很低。

2D API提供了用于转换(移动)任何呈现内容的全套方法。

这些方法是:

  1. ctx.setTransform(axisX_X,axisX_Y,axisY_X,axisY_Y,originX,originY)
  2. ctx.transform(axisX_X,axisX_Y,axisY_X,axisY_Y,originX,originY)
  3. ctx.scale(scaleX,scaleY)
  4. ctx.rotate(弧度)
  5. ctx.translate(originX,originY)

(每个链接到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的使用方法以及为什么它比其他方法更受欢迎的原因,请参见此答案

您有正确的主意。 只需确保在绘制之间清除画布,以确保没有绘制画布上当前的内容。 然后,您只需更新一些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(); })(); 
 <canvas class="canvas" width="500" height="500"></canvas> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM