webentwicklung-frage-antwort-db.com.de

Zeichne einen Pfeil auf dem Leinwand-Tag

Ich möchte einen Pfeil mit dem Canvas-Tag javascript zeichnen. Ich habe es mit der quadratischen Funktion gemacht, aber ich habe Probleme, den Drehwinkel des Pfeils zu berechnen ...

Hat jemand eine Ahnung davon?

Vielen Dank

So einfach wie ich es bekommen kann. Sie müssen context.beginPath () voranstellen und context.stroke () selbst anhängen:

function canvas_arrow(context, fromx, fromy, tox, toy){
    var headlen = 10;   // length of head in pixels
    var angle = Math.atan2(toy-fromy,tox-fromx);
    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));
}

Hier ist ein Beispiel: http://stuff.titus-c.ch/arrow.html

76

Ok, die erste Antwort auf dieser Seite hat mir sehr geholfen, als ich versuchte, dieses Problem selbst zu lösen, obwohl, wie bereits erwähnt, jemand eine andere Linienstärke als 1px hat, man lustige Formen bekommt. Das Update, das jemand anderes vorgeschlagen hatte, hat fast funktioniert, aber ich hatte immer noch Probleme, wenn ich einen dickeren Pfeil anstrebte. Nachdem ich einige Stunden damit herumgespielt hatte, war ich in der Lage, die obige Lösung mit einigen meiner eigenen Basteleien zu kombinieren, um den folgenden Code zu erstellen, der einen Pfeil in beliebiger Dicke zeichnet, ohne die Pfeilform zu verzerren.

function drawArrow(fromx, fromy, tox, toy){
                //variables to be used when creating the arrow
                var c = document.getElementById("myCanvas");
                var ctx = c.getContext("2d");
                var headlen = 10;

                var angle = Math.atan2(toy-fromy,tox-fromx);

                //starting path of the arrow from the start square to the end square and drawing the stroke
                ctx.beginPath();
                ctx.moveTo(fromx, fromy);
                ctx.lineTo(tox, toy);
                ctx.strokeStyle = "#cc0000";
                ctx.lineWidth = 22;
                ctx.stroke();

                //starting a new path from the head of the arrow to one of the sides of the point
                ctx.beginPath();
                ctx.moveTo(tox, toy);
                ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

                //path from the side point of the arrow, to the other side point
                ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));

                //path from the side point back to the tip of the arrow, and then again to the opposite side point
                ctx.lineTo(tox, toy);
                ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));

                //draws the paths created above
                ctx.strokeStyle = "#cc0000";
                ctx.lineWidth = 22;
                ctx.stroke();
                ctx.fillStyle = "#cc0000";
                ctx.fill();
            }

Dies ist jetzt der Code, den ich in meinem Programm verwende. Was für mich der Schlüssel bei der Beseitigung des Verzerrungsproblems war, bestand darin, den Strich von der Pfeilspitze zu einem Seitenpunkt, zum anderen Seitenpunkt, zurück zur Spitze und zurück zum ersten Seitenpunkt fortzusetzen, dann einen füllen. Dies hat die Form des Pfeils korrigiert.

Hoffe das hilft!

24
SteampunkWizard

Du kannst tun:

ctx.save();
ctx.translate(xOrigin, yOrigin);
ctx.rotate(angle);
 // draw your arrow, with its Origin at [0, 0]
ctx.restore();
7
Fabien Ménager

Hier ist eine weitere Methode zum Zeichnen von Pfeilen. Hier wird die Dreiecksmethode verwendet: https://stackoverflow.com/a/8937325/1828637

Eine kleine Helferfunktion.

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();
}

Und hier ist eine Demonstration davon, um Pfeile am Anfang und am Ende einer Linie zu zeichnen.

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>

4
Noitidart

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, canvas.width, canvas.height);	
arrow({x: 10, y: 10}, {x: 100, y: 170}, 10);
arrow({x: 40, y: 250}, {x: 10, y: 70}, 5);


function arrow (p1, p2, size) {
  var angle = Math.atan2((p2.y - p1.y) , (p2.x - p1.x));
  var hyp = Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));

  ctx.save();
  ctx.translate(p1.x, p1.y);
  ctx.rotate(angle);

  // line
  ctx.beginPath();	
  ctx.moveTo(0, 0);
  ctx.lineTo(hyp - size, 0);
  ctx.stroke();

  // triangle
  ctx.fillStyle = 'blue';
  ctx.beginPath();
  ctx.lineTo(hyp - size, size);
  ctx.lineTo(hyp, 0);
  ctx.lineTo(hyp - size, -size);
  ctx.fill();

  ctx.restore();
}
<canvas id = "canvas" width = "300" height = "400"></canvas>

2
Aikon Mogwai

Dieser Code ähnelt der Lösung von Titus Cieslewski, vielleicht ist der Pfeil etwas schöner:

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))));
}

das funktioniert gut mit lineWidth > 1. Es kann nützlich sein, wenn Sie die Achse x und y zeichnen

2
user3719454

Bei gegebener Größe und Startposition zeichnet der folgende Code den Pfeil für Sie.

<!DOCTYPE HTML> 
<html> 
    <head> 
        <style> 
            body { 
                margin: 0px; 
                padding: 0px; 
            } 

            #myCanvas { 
                border: 1px solid #9C9898; 
            } 
        </style> 
        <script> 
            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); 
            }; 
        </script> 
    </head> 
    <body onmousedown="return false;"> 
        <canvas id="myCanvas" width="578" height="200"> 
        </canvas> 

    </body> 
</html> 
2
nizam.sp
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);
  }
}
1
Ariel Mendoza

Hier ist die Arbeitslösung

function draw_arrow(ctx,fx,fy,tx,ty){ //ctx is the context
    var angle=Math.atan2(ty-fy,tx-fx);
    ctx.moveTo(fx,fy); ctx.lineTo(tx,ty);
    var w=3.5; //width of arrow to one side. 7 pixels wide arrow is pretty
    ctx.strokeStyle="#4d4d4d"; ctx.fillStyle="#4d4d4d";
    angle=angle+Math.PI/2; tx=tx+w*Math.cos(angle); ty=ty+w*Math.sin(angle);
    ctx.lineTo(tx,ty);
  //Drawing an isosceles triangle of sides proportional to 2:7:2
    angle=angle-1.849096; tx=tx+w*3.5*Math.cos(angle); ty=ty+w*3.5*Math.sin(angle);
    ctx.lineTo(tx,ty);
    angle=angle-2.584993; tx=tx+w*3.5*Math.cos(angle); ty=ty+w*3.5*Math.sin(angle);
    ctx.lineTo(tx,ty);
    angle=angle-1.849096; tx=tx+w*Math.cos(angle); ty=ty+w*Math.sin(angle);
    ctx.lineTo(tx,ty);
    ctx.stroke(); ctx.fill();
}
0
ajk

Sie können Ihre Matrix schieben, drehen, Ihren Pfeil zeichnen und dann die Matrix öffnen.

0
Clint

Ich habe seit geraumer Zeit damit zu kämpfen ... Ich musste dazu sowohl in Javascript als auch in c #. Für Javascript habe ich eine schöne Bibliothek jCanvas gefunden.

Mein Hauptproblem war das Zeichnen von gut aussehenden Pfeilspitzen, was jCanvas perfekt macht. Für mein C # -Projekt habe ich den jCanvas-Code zurückentwickelt.

Hoffentlich hilft das jemandem

0
hoeselvang