Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active Dec 20, 2018
Embed
What would you like to do?
Angle Between Points
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
div {
background: rgba(255, 255, 255, .8);
font-size: 30px;
padding: 10px;
pointer-events: none;
position: absolute;
}
.instruction {
pointer-events: none;
text-anchor: middle;
}
.arc {
fill-opacity: .1;
stroke-opacity: .1;
stroke: #000;
pointer-events: none;
}
.arc.selected {
fill: steelblue;
stroke: steelblue;
}
.baseline {
display: none;
stroke-dasharray: 5, 5;
stroke: #000;
}
.triangle {
cursor: move;
fill: black;
}
.connector {
pointer-events: none;
stroke: black;
stroke-width: 5px;
}
.triangle.selected {
fill: steelblue;
}
.connector.selected {
stroke: steelblue;
}
</style>
</head>
<body>
<div><span>90.0</span>°</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/geometric@1.0.0/build/geometric.min.js"></script>
<script>
var dragged = 0;
var width = 960, height = 500, center = [width / 2, height / 2], arrow_position = [center[0], center[1] / 2]
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("line")
.attr("class", "baseline")
.attr("x2", width)
.attr("y1", center[1])
.attr("y2", center[1]);
var arc = svg.append("path")
.attr("class", "arc")
.attr("d", drawArc([center[0] + geometric.lineLength([center, arrow_position]), center[1]], arrow_position));
var triangle = svg.append("polygon")
.attr("class", "triangle")
.attr("points", "-15,10 0,-10 15,10")
.attr("transform", "translate(" + arrow_position + ")");
var connector = svg.append("line")
.attr("class", "connector")
.attr("x1", center[0])
.attr("y1", center[1])
.attr("x2", center[0])
.attr("y2", center[1] / 2);
var text = svg.append("text")
.attr("class", "instruction")
.attr("transform", "translate(" + arrow_position + ")")
.attr("dy", -25)
.text("Drag the arrow");
svg.append("circle")
.attr("r", 5)
.attr("transform", "translate(" + center + ")");
var drag_generator = d3.drag()
.on("start", start)
.on("drag", drag)
.on("end", end);
triangle.call(drag_generator);
function start(){
triangle.classed("selected", 1);
connector.classed("selected", 1);
arc.classed("selected", 1);
if (!dragged){
text.transition().style("opacity", 1e-6).remove();
dragged = 1;
}
}
function drag(){
arrow_position = [event.pageX, event.pageY];
var angle = geometric.lineAngle([center, arrow_position]);
d3.select("span").text((angle * -1).toFixed(1));
triangle.attr("transform", "translate(" + arrow_position + ") rotate(" + (angle + 90) + ")");
connector.attr("x2", arrow_position[0]).attr("y2", arrow_position[1]);
arc.attr("d", drawArc([center[0] + geometric.lineLength([center, arrow_position]), center[1]], arrow_position, angle * -1));
}
function end(){
triangle.classed("selected", 0);
connector.classed("selected", 0);
arc.classed("selected", 0);
}
function drawArc(a, b, angle){
var d = geometric.lineLength([a, b]);
return "M" + (angle < 0 ? a : b) + "A" + d + "," + d + " 0 0,1 " + (angle < 0 ? b : a) + " L" + center + " Z";
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment