Created
May 18, 2017 15:18
-
-
Save jwir3/d797037d2e1bf78a9b04838d73436197 to your computer and use it in GitHub Desktop.
Code to create an arrowhead on an html5 canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Draw an arrowhead on a line on an HTML5 canvas. | |
* | |
* Based almost entirely off of http://stackoverflow.com/a/36805543/281460 with some modifications | |
* for readability and ease of use. | |
* | |
* @param context The drawing context on which to put the arrowhead. | |
* @param from A point, specified as an object with 'x' and 'y' properties, where the arrow starts | |
* (not the arrowhead, the arrow itself). | |
* @param to A point, specified as an object with 'x' and 'y' properties, where the arrow ends | |
* (not the arrowhead, the arrow itself). | |
* @param radius The radius of the arrowhead. This controls how "thick" the arrowhead looks. | |
*/ | |
function drawArrowhead(context, from, to, radius) { | |
var x_center = to.x; | |
var y_center = to.y; | |
var angle; | |
var x; | |
var y; | |
context.beginPath(); | |
angle = Math.atan2(to.y - from.y, to.x - from.x) | |
x = radius * Math.cos(angle) + x_center; | |
y = radius * Math.sin(angle) + y_center; | |
context.moveTo(x, y); | |
angle += (1.0/3.0) * (2 * Math.PI) | |
x = radius * Math.cos(angle) + x_center; | |
y = radius * Math.sin(angle) + y_center; | |
context.lineTo(x, y); | |
angle += (1.0/3.0) * (2 * Math.PI) | |
x = radius *Math.cos(angle) + x_center; | |
y = radius *Math.sin(angle) + y_center; | |
context.lineTo(x, y); | |
context.closePath(); | |
context.fill(); | |
} |
Thanks so much
Thank you!
Great way to draw arrow. If my from is (100,100) and to is (450, 100) then arrow head is just more than 450. So, How to find the arrow head point?
@codingbyraj It's been a little while since I've looked at this code, so I'll have to take a look for you. I'll see if I can check it out and answer your question this week.
Thank you @jwir3. I am trying too and will wait for your response.
yay
const headSize = arrow.attrs.strokeWidth * 3;
if (arrowAtStart) {
const angle = Math.atan2(y2 - y1, x2 - x1);
let delta = Math.PI / 6;
for (let i = 0; i < 2; i++) {
doc.moveTo(x1, y1);
const x = x1 + headSize * Math.cos(angle + delta);
const y = y1 + headSize * Math.sin(angle + delta);
doc.lineTo(x, y);
delta *= -1;
}
}
if (arrowAtEnding) {
let delta = Math.PI / 6;
const angle = Math.atan2(y1 - y2, x1 - x2);
for (let i = 0; i < 2; i++) {
doc.moveTo(x2, y2);
const x = x2 + headSize * Math.cos(angle + delta);
const y = y2 + headSize * Math.sin(angle + delta);
doc.lineTo(x, y);
delta *= -1;
}
}
doc.fillStroke();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you!