I need to draw a stream dynamically based on the user's choices. In this flow I want to draw the chosen hypotheses (blue circles with numbers) and the direction between the choices (lines with arrows). For example: node 1 for node 2.
To draw the direction I draw the arrow at the end of the line but I can not make the arrow just rotate around its center, following the direction of the line.
JS code
$(document).ready(function () {
drawOnCanvas();
});
function drawOnCanvas() {
var canvas = document.getElementById('myCanvas');
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var circle1 = {
x: 75,
y: 75,
r: 15
};
var circle2 = {
x: 225,
y: 50,
r: 15
};
var arrow =
{
h: 5,
w: 10
};
drawCircle(ctx, circle1, "1");
drawCircle(ctx, circle2, "2");
var ptCircle1 = getPointOnCircle(circle1.r, circle1, circle2);
var ptCircle2 = getPointOnCircle(circle2.r, circle2, circle1);
var ptArrow = getPointOnCircle(circle2.r + arrow.w, circle2, circle1);
drawLine(ctx, ptCircle1, ptCircle2);
drawArrow(ctx, arrow, ptArrow, ptCircle2);
}
}
function drawArrow(canvasContext, arrow, ptArrow, endPt) {
var angleInDegrees = getAngleBetweenPoints(ptArrow, endPt);
canvasContext.beginPath();
// first save the untranslated/unrotated context
canvasContext.save();
// move the rotation point to the center of the rect
canvasContext.translate(ptArrow.x, ptArrow.y);
// rotate the rect
canvasContext.rotate(angleInDegrees);
canvasContext.moveTo(endPt.x, endPt.y);
canvasContext.lineTo(endPt.x - arrow.w, endPt.y + arrow.h);
canvasContext.lineTo(endPt.x - arrow.w, endPt.y - arrow.h);
canvasContext.closePath();
canvasContext.fillStyle = "rgb(72,72,72)";
canvasContext.stroke();
canvasContext.fill();
// restore the context to its untranslated/unrotated state
canvasContext.restore();
}
function drawCircle(canvasContext, circle, text) {
canvasContext.beginPath(); //começa ou reinicia o desenho de algo
canvasContext.fillStyle = "rgb(43,166,203)";
canvasContext.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI, false); //cria arcos
canvasContext.fill(); //atribui estilos
drawText(canvasContext, circle, text);
}
function drawText(canvasContext, circle, text) {
canvasContext.font = '8pt Calibri';
canvasContext.fillStyle = 'white';
canvasContext.textAlign = 'center';
canvasContext.fillText(text, circle.x, circle.y + 3);
}
function drawLine(canvasContext, startPt, endPt) {
canvasContext.moveTo(startPt.x, startPt.y);
canvasContext.lineTo(endPt.x, endPt.y);
canvasContext.stroke();
}
function getPointOnCircle(radius, originPt, endPt) {
var angleInDegrees = getAngleBetweenPoints(originPt, endPt);
// Convert from degrees to radians via multiplication by PI/180
var x = radius * Math.cos(angleInDegrees * Math.PI / 180) + originPt.x;
var y = radius * Math.sin(angleInDegrees * Math.PI / 180) + originPt.y;
return { x: x, y: y };
}
function getAngleBetweenPoints(originPt, endPt) {
var interPt = { x: endPt.x - originPt.x,
y: endPt.y - originPt.y
};
return Math.atan2(interPt.y, interPt.x) * 180 / Math.PI;
}
I think the problem is in the drawArrow()
nas method:
canvasContext.translate(ptArrow.x, ptArrow.y);
canvasContext.rotate(angleInDegrees);
I have tried all possible values for rotation and translation but the arrow continues to not rotate properly around itself. Can anyone help me?
Update
I've seen and maybe the best way to draw the triangle is JSFiddle Example
canvasContext.moveTo(ptArrow.x, ptArrow.y);
canvasContext.lineTo(ptArrow.x, ptArrow.y - arrow.h);
canvasContext.lineTo(ptArrow.x + arrow.w, ptArrow.y);
canvasContext.lineTo(ptArrow.x + arrow.w, ptArrow.y);
canvasContext.lineTo(ptArrow.x, ptArrow.y + arrow.h);
However I continue with the same problem ..