Skip to content

Instantly share code, notes, and snippets.

@armollica
Last active December 5, 2015 13:22
Show Gist options
  • Save armollica/41d62fdffa9c4172662c to your computer and use it in GitHub Desktop.
Save armollica/41d62fdffa9c4172662c to your computer and use it in GitHub Desktop.
Line Arrow

Drawing an arrowhead on a line in canvas. Move mouse to move line. Similar to a marker tag in SVG.

<html>
<head>
<title>Line Arrow</title>
</head>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var width = 960,
height = 500,
arrowLength = 10;
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
var origin = {x: width/2, y: height/2};
draw(width/4, height/4);
canvas
.on("mousemove", function() {
var mouse = d3.mouse(this);
var d = truncateVector([origin, {x: mouse[0], y: mouse[1]}], .8)[1];
draw(d.x, d.y);
});
function draw(x, y) {
var endPoint = {x, y},
arrowData = getArrowData([origin, endPoint]);
context.clearRect(0, 0, width, height);
path(context, [origin, endPoint]);
path(context, [endPoint, arrowData.left]);
path(context, [endPoint, arrowData.right]);
}
function path(context, data) {
context.beginPath();
context.moveTo(data[0].x, data[0].y);
data.slice(1).forEach(function(d) {
context.lineTo(d.x, d.y);
});
context.stroke();
context.closePath();
}
function truncateVector(data, c) {
var x0 = data[0].x, y0 = data[0].y,
x1 = data[1].x, y1 = data[1].y,
endPoint = {
x: x0 + (x1-x0)*c,
y: y0 + (y1-y0)*c
};
return [data[0], endPoint];
}
function getArrowData(data) {
var data = data.slice(-2),
x0 = data[0].x, y0 = data[0].y,
x1 = data[1].x, y1 = data[1].y,
t = Math.atan2(y1-y0, x1-x0),
dt = Math.PI*(3/4);
return {
right: {
x: arrowLength * Math.cos(t + dt) + x1,
y: arrowLength * Math.sin(t + dt) + y1
},
left: {
x: arrowLength * Math.cos(t - dt) + x1,
y: arrowLength * Math.sin(t - dt) + y1
}
};
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment