Skip to content

Instantly share code, notes, and snippets.

@gilmoreorless
Last active June 28, 2016 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gilmoreorless/155e9d61af7aa892c4061c09338e75d9 to your computer and use it in GitHub Desktop.
Save gilmoreorless/155e9d61af7aa892c4061c09338e75d9 to your computer and use it in GitHub Desktop.
Draw an arrow between two points
license: cc-by-4.0

A simple reference for me to remember the trigonometry methods required to draw a given shape between two points. In this case it’s an arrow drawn from the centre of the canvas to wherever the mouse cursor is.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: sans-serif;
margin: auto;
position: relative;
width: 960px;
}
.control {
left: 50%;
position: absolute;
top: 2em;
transform: translateX(-50%);
}
.control input {
width: 200px;
}
.dot {
fill: #c30;
}
.path {
fill: #667;
fill-opacity: 0.7;
}
</style>
<body>
<script src="//d3js.org/d3.v3.js"></script>
<label class="control">Radius: <input type="range" min="2" max="20" step="1" value="10"></label>
<script>
var width = 960,
height = 500,
radius = 10;
var cx = width / 2, cy = height / 2;
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
var dot = svg.append('circle')
.attr('class', 'dot')
.attr('cx', cx)
.attr('cy', cy)
.attr('r', radius);
var path = svg.append('path')
.attr('class', 'path');
function trianglePath(xy) {
var x = xy[0] - cx;
var y = xy[1] - cy;
var dist = Math.sqrt(x * x + y * y);
var angle = Math.atan2(y, x) / Math.PI * 180;
return function () {
this.attr('d', 'M0,0 L' + [
0, radius,
dist - radius, radius / 3,
dist - radius, radius,
dist, 0,
dist - radius, -radius,
dist - radius, -radius / 3,
0, -radius
] + 'z');
this.attr('transform', 'translate(' + [cx, cy] + ') rotate(' + angle + ')');
}
}
d3.select(document).on('mousemove', function () {
path.call(trianglePath(d3.mouse(svg.node())));
});
document.querySelector('.control input').addEventListener('input', function (e) {
radius = +this.value;
dot.attr('r', radius);
}, false);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment