使用绘制的画布元素的多个副本

时间:2016-05-27 07:44:17

标签: javascript html canvas

我想和canvan一起画这样的想法

enter image description here

为此,我尝试绘制一个画布箭头,并希望多次使用它,但具有不同的位置和文本。如何将其创建为Object以多次使用它?

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>

<script>

var canvas = document.getElementById("myCanvas");
var arrow = canvas.getContext("2d");
arrow.moveTo(0,0);
arrow.lineTo(175,0);
arrow.lineTo(200,50);
arrow.lineTo(175,100);
arrow.lineTo(0,100);
arrow.lineTo(25,50);
arrow.lineTo(0,0);
arrow.stroke();
arrow.fillStyle = "#333";
arrow.fill();

arrow.style.left = "100px";
arrow.style.top = "100px";
arrow.style.position = "absolute";

</script>

有没有人理解如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

enter image description here

x和y位置在顶部

function drawArrow(ctx, x, y, w, h) {
    w = w || 200;
  h = h || 100;

  ctx.moveTo(x, y);
  ctx.lineTo(x + w * 0.8, y);
  ctx.lineTo(x + w, y + (h/2));
  ctx.lineTo(x + w * 0.8, y + h);
  ctx.lineTo(x, y + h);
  ctx.lineTo(x + w * 0.2, y + (h/2));
  ctx.lineTo(x, y);
  ctx.stroke();
  ctx.fillStyle = "#333";
  ctx.fill();``
}

这是fiddle

答案 1 :(得分:1)

只需将代码嵌入到函数中,就可以将不同的值作为参数传递。可以使用与矩形组合的倾斜变换绘制箭头本身:

ctx.setTransform(1, 0, 1, 1, x, y);       // skew angle 1 (radians)
ctx.fillRect(0, 0, w, h * 0.5);           // draw half arrow
ctx.setTransform(1, 0, -1, 1, x + h, y);  // skew opposite way, compensate for x
ctx.fillRect(0, h * 0.5, w, h * 0.5);     // second half

如果我们将所有内容都包装成一个函数,你可以这样使用它:

result

&#13;
&#13;
var ctx = c.getContext("2d");
ctx.fillStyle = "#1F487C";

for(var i = 0; i < 3; i++)
  drawArrow(20 + i * 130, 50, 110, 50);  // draw arrow in a loop

function drawArrow(x, y, w, h) {
  ctx.setTransform(1,0,1,1,x,y);
  ctx.fillRect(0, 0, w, h * 0.5);
  ctx.setTransform(1,0,-1,1,x + h,y);
  ctx.fillRect(0, h * 0.5, w, h * 0.5);
  ctx.setTransform(1,0,0,1,0,0);         // resets transformations
}
&#13;
<canvas id=c width=600></canvas>
&#13;
&#13;
&#13;

提示:如果您需要提高性能,只需将fillRect()替换为rect(),并在循环后使用fill()(在循环前记住beginPath())。这将调用单个填充操作而不是多个。但是,它们在任何情况下都可以在单帧的时间内很好地绘制,所以这里确实没有多少增益,首先将这个或缓存作为图像(除非你打算一次绘制数百+这些)。

答案 2 :(得分:0)

是的,你可以做K3N所说的,但我会在性能方面做得很少并且预呈现一个形象:

const arrow = document.createElement('canvas');
arrow.width: 100;
arrow.height: 100;

preRender();
function preRender() {
  const w = arrow.width;
  const h = arrow.height;
  ctx = arrow.getContext('2d');

  ctx.setTransform(1,0,1,1,0,0);
  ctx.fillRect(0, 0, w, h * 0.5);
  ctx.setTransform(1,0,-1,1,h,0);
  ctx.fillRect(0, h * 0.5, w, h * 0.5);
  ctx.setTransform(1,0,0,1,0,0);         // resets transformations
}

然后你可以将它用作图像

ctx.drawImage(arrow,0,0,150,150);