Skip to content

Instantly share code, notes, and snippets.

@HarryStevens HarryStevens/.block

Last active Nov 25, 2018
Embed
What would you like to do?
Arc Path
license: gpl-3.0

Draw an arc path between two points. Drag the points to see the arc adapt.

<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
.circle {
cursor: move;
}
.circle.selected {
fill: tomato;
stroke: black;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var width = window.innerWidth,
height = window.innerHeight,
radius = 15;
var data = [[100, 100], [width - 100, height - 100]];
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var arc = svg.append("path")
.style("fill", "none")
.style("stroke", "black")
.attr("d", drawArc(data));
var circles = svg.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("class", (d, i) => "circle circle-" + i)
.attr("r", radius)
.attr("transform", d => "translate(" + d + ")")
.call(d3.drag()
.on("start", dragStart)
.on("drag", dragging)
.on("end", dragEnd)
);
function dragStart(d, i){
d3.select(".circle-" + i).classed("selected", 1);
}
function dragging(d, i){
data[i] = [
event.pageX < radius ? radius : event.pageX > width - radius ? width - radius : event.pageX,
event.pageY < radius ? radius : event.pageY > height - radius ? height - radius : event.pageY
];
d3.select(".circle-" + i).attr("transform", "translate(" + data[i] + ")");
arc.attr("d", drawArc(data));
}
function dragEnd(d, i){
d3.select(".circle-" + i).classed("selected", 0);
}
// The argument "d" is an array of two points, where each point is an array of two coordinates
function drawArc(d){
var dx = d[1][0] - d[0][0],
dy = d[1][1] - d[0][1],
dr = Math.sqrt(dx * dx + dy * dy) * .67; // Reduce for more bend
return "M" + d[0][0] + "," + d[0][1] + "A" + dr + "," + dr + " 0 0,1 " + d[1][0] + "," + d[1][1];
}
window.onresize = _ => {
width = window.innerWidth;
height = window.innerHeight;
svg
.attr("width", width)
.attr("height", height);
circles
.attr("transform", (d, i, e) => {
var curr_transform = d3.select(e[i]).attr("transform").replace("translate(", "").replace(")", "").split(",").map(d => +d);
data[i] = [
curr_transform[0] > width - radius ? width - radius : curr_transform[0],
curr_transform[1] > height - radius ? height - radius : curr_transform[1]
];
arc.attr("d", drawArc(data));
return "translate(" + data[i] + ")";
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.