キャンバスタグのjavascriptを使って矢印を描きたいです。二次関数を使って作ったのですが、矢印の回転角度を計算するのに苦労しています...
誰でもこれについて手がかりを持っていますか?
ありがとうございました
キャンバスタグのjavascriptを使って矢印を描きたいです。二次関数を使って作ったのですが、矢印の回転角度を計算するのに苦労しています...
誰でもこれについて手がかりを持っていますか?
ありがとうございました
私が得ることができるのと同じくらい簡単です。context.beginPath() を先頭に追加し、 context.stroke() を自分で追加する必要があります。
ctx = document.getElementById("c").getContext("2d");
ctx.beginPath();
canvas_arrow(ctx, 10, 30, 200, 150);
canvas_arrow(ctx, 100, 200, 400, 50);
canvas_arrow(ctx, 200, 30, 10, 150);
canvas_arrow(ctx, 400, 200, 100, 50);
ctx.stroke();
function canvas_arrow(context, fromx, fromy, tox, toy) {
  var headlen = 10; // length of head in pixels
  var dx = tox - fromx;
  var dy = toy - fromy;
  var angle = Math.atan2(dy, dx);
  context.moveTo(fromx, fromy);
  context.lineTo(tox, toy);
  context.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
  context.moveTo(tox, toy);
  context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
}<html>
<body>
  <canvas id="c" width="500" height="500"></canvas>
</body>矢印を描画する別の方法を次に示します。ここから三角形の方法を使用します: https://stackoverflow.com/a/8937325/1828637
ちょっとしたヘルパー関数。
function canvas_arrow(context, fromx, fromy, tox, toy, r){
    var x_center = tox;
    var y_center = toy;
    var angle;
    var x;
    var y;
    context.beginPath();
    angle = Math.atan2(toy-fromy,tox-fromx)
    x = r*Math.cos(angle) + x_center;
    y = r*Math.sin(angle) + y_center;
    context.moveTo(x, y);
    angle += (1/3)*(2*Math.PI)
    x = r*Math.cos(angle) + x_center;
    y = r*Math.sin(angle) + y_center;
    context.lineTo(x, y);
    angle += (1/3)*(2*Math.PI)
    x = r*Math.cos(angle) + x_center;
    y = r*Math.sin(angle) + y_center;
    context.lineTo(x, y);
    context.closePath();
    context.fill();
}
そして、これは線の始点と終点に矢印を描くデモです。
var can = document.getElementById('c');
var ctx = can.getContext('2d');
ctx.lineWidth = 10;
ctx.strokeStyle = 'steelblue';
ctx.fillStyle = 'steelbllue'; // for the triangle fill
ctx.lineJoin = 'butt';
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(150, 150);
ctx.stroke();
canvas_arrow(ctx, 50, 50, 150, 150, 10);
canvas_arrow(ctx, 150, 150, 50, 50, 10);
function canvas_arrow(context, fromx, fromy, tox, toy, r){
	var x_center = tox;
	var y_center = toy;
	
	var angle;
	var x;
	var y;
	
	context.beginPath();
	
	angle = Math.atan2(toy-fromy,tox-fromx)
	x = r*Math.cos(angle) + x_center;
	y = r*Math.sin(angle) + y_center;
	context.moveTo(x, y);
	
	angle += (1/3)*(2*Math.PI)
	x = r*Math.cos(angle) + x_center;
	y = r*Math.sin(angle) + y_center;
	
	context.lineTo(x, y);
	
	angle += (1/3)*(2*Math.PI)
	x = r*Math.cos(angle) + x_center;
	y = r*Math.sin(angle) + y_center;
	
	context.lineTo(x, y);
	
	context.closePath();
	
	context.fill();
}<canvas id="c" width=300 height=300></canvas>Typescript バージョン、線幅 >> 1 の場合の固定矢印の先端
function canvas_arrow( context, fromx, fromy, tox, toy ) {
    const dx = tox - fromx;
    const dy = toy - fromy;
    const headlen = Math.sqrt( dx * dx + dy * dy ) * 0.3; // length of head in pixels
    const angle = Math.atan2( dy, dx );
    context.beginPath();
    context.moveTo( fromx, fromy );
    context.lineTo( tox, toy );
    context.stroke();
    context.beginPath();
    context.moveTo( tox - headlen * Math.cos( angle - Math.PI / 6 ), toy - headlen * Math.sin( angle - Math.PI / 6 ) );
    context.lineTo( tox, toy );
    context.lineTo( tox - headlen * Math.cos( angle + Math.PI / 6 ), toy - headlen * Math.sin( angle + Math.PI / 6 ) );
    context.stroke();
}
サイズと開始位置を指定すると、次のコードが矢印を描画します。
function draw_arrow(context, startX, startY, size) {
  var arrowX = startX + 0.75 * size;
  var arrowTopY = startY - 0.707 * (0.25 * size);
  var arrowBottomY = startY + 0.707 * (0.25 * size);
  context.moveTo(startX, startY);
  context.lineTo(startX + size, startX);
  context.lineTo(arrowX, arrowTopY);
  context.moveTo(startX + size, startX);
  context.lineTo(arrowX, arrowBottomY);
  context.stroke();
}
window.onload = function() {
  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");
  var startX = 50;
  var startY = 50;
  var size = 100;
  context.lineWidth = 2;
  draw_arrow(context, startX, startY, size);
};body {
  margin: 0px;
  padding: 0px;
}
#myCanvas {
  border: 1px solid #9C9898;
}<!DOCTYPE HTML>
<html>
<body onmousedown="return false;">
  <canvas id="myCanvas" width="578" height="200"></canvas>
</body>
</html>このコードは Titus Cieslewski のソリューションに似ていますが、矢印の方が少し良いかもしれません。
function canvasDrawArrow(context, fromx, fromy, tox, toy) {
    var headlen = 10.0;
    var back = 4.0;
    var angle1 = Math.PI / 13.0;
    var angle2 = Math.atan2(toy - fromy, tox - fromx);
    var diff1 = angle2 - angle1;
    var diff2 = angle2 + angle1;
    var xx = getBack(back, fromx, fromy, tox, toy);
    var yy = getBack(back, fromy, fromx, toy, tox);
    context.moveTo(fromx, fromy);
    context.lineTo(tox, toy);
    context.moveTo(xx, yy);
    context.lineTo(xx - headlen * Math.cos(diff1), yy - headlen * Math.sin(diff1));
    context.moveTo(xx, yy);
    context.lineTo(xx - headlen * Math.cos(diff2), yy - headlen * Math.sin(diff2));
}
function getBack(len, x1, y1, x2, y2) {
    return x2 - (len * (x2 - x1) / (Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2))));
}
これは でうまく機能しlineWidth > 1ます。描画xやy軸のときに便利です
function RTEShape()
{   
    this.x = 50;
  this.y = 50;
  this.w = 100; // default width and height?
  this.h = 100;
  this.fill = '#444444';
  this.text = "Test String";
  this.type;
  this.color;
  this.size = 6;    
    // The selection color and width. Right now we have a red selection with a small width
    this.mySelColor = '#CC0000';
    this.mySelWidth = 2;
    this.mySelBoxColor = 'darkred';// New for selection boxes
    this.mySelBoxSize = 6;
}
RTEShape.prototype.buildArrow = function(canvas)
{
    this.type = "arrow";
  // Make sure we don't execute when canvas isn't supported
  if (canvas.getContext){
    // use getContext to use the canvas for drawing
    var ctx = canvas.getContext('2d');           
    var oneThirdX = this.x + (this.w/3);             
    var twoThirdX = this.x + ((this.w*2)/3);
    var oneFifthY = this.y - (this.y/5);    
    var twoFifthY = this.y - ((this.y*3)/5);
    /**/
    //ctx.beginPath();
    ctx.moveTo(oneThirdX,this.y); // 125,125
    ctx.lineTo(oneThirdX,oneFifthY); // 125,105
    ctx.lineTo(this.x*2,oneFifthY); // 225,105      
    ctx.lineTo(this.x*2,twoFifthY); // 225,65
    ctx.lineTo(oneThirdX,twoFifthY); // 125,65      
    ctx.lineTo(oneThirdX,(this.y/5)); // 125,45
    ctx.lineTo(this.x,(this.y+(this.y/5))/2); // 45,85
        ctx.fillStyle = "green";
    ctx.fill();
    ctx.fillStyle = "yellow";
    ctx.fillRect(this.x,this.y,this.w,this.h);
  } else {
    alert('Error on buildArrow!\n'+err.description);
  }
}
マトリックスを押して回転させ、矢印を描いてから、マトリックスをポップできます。