Placing some offset directional arrows along a path, take 2.
Created
August 5, 2016 12:26
-
-
Save veltman/fc1af365f62c0121b47fd414bf08a3d7 to your computer and use it in GitHub Desktop.
Directional arrows #2
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<style> | |
path { | |
fill: none; | |
stroke: #fc0; | |
stroke-width: 2px; | |
} | |
.arrow path { | |
stroke: black; | |
} | |
#arrowhead { | |
stroke: none; | |
fill: black; | |
} | |
</style> | |
</head> | |
<body> | |
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="960" height="500"> | |
<path d="M636.5,315c-0.4-18.7,1.9-27.9-5.3-35.9 | |
c-22.7-25-107.3-2.8-118.3,35.9c-7,24.4,20.6,37.2,16,71c-4,29.6-30.8,60.7-56.5,61.1c-30.8,0.4-32.9-43.8-81.7-70.2 | |
c-50.9-27.6-110.1-12.9-125.2-9.2c-66.1,16.4-82.2,56.9-109.2,47.3c-38-13.6-55.9-112.1-19.8-143.5c39-34,121.2,27.7,148.1-3.8 | |
c18-21.1,3.1-74.3-25.2-105.3c-31.1-34.1-70.1-32.4-105.3-76.3c-8.2-10.2-16.9-23.8-15.3-39.7c1.2-11.4,7.5-23.3,15.3-29 | |
c33.8-25,101.6,62.6,193.1,59.5c40.1-1.3,38.7-18.5,99.2-38.9c126.2-42.6,242.4-4.9,297.7,13c54.7,17.7,105.4,35,129.8,82.4 | |
c13,25.3,22.9,67.7,4.6,87c-11.6,12.3-25.1,5.1-46.6,20.6c-2.8,2-28.9,21.4-32.1,49.6c-3.1,27.4,18.7,35,29,70.2 | |
c8.8,30.1,8.5,77.8-18.3,99.2c-32.3,25.8-87,0.6-100-5.3c-69.6-32-67.2-88.4-73.3-109.2z"/> | |
<defs> | |
<path id="arrowhead" d="M5,0 L-5,-3 L-5,3 Z" /> | |
</defs> | |
</svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var path = document.querySelector("path"), | |
str = path.getAttribute("d"), | |
length = path.getTotalLength(); | |
d3.select("svg").selectAll(".arrow") | |
.data(d3.range(16)) | |
.enter() | |
.append("g") | |
.attr("class", "arrow") | |
.each(draw); | |
function draw(d) { | |
var g = d3.select(this), | |
l = 20 + length * d / 16, | |
angle = angleAtLength(l), | |
end = pointAtLength(l + 20), | |
endAngle = angleAtLength(l + 20), | |
offset = [ | |
12 * Math.cos(angle - Math.PI / 2), | |
12 * Math.sin(angle - Math.PI / 2) | |
]; | |
g.attr("transform", "translate(" + offset + ")") | |
.append("path") | |
.attr("d", str) | |
.attr("stroke-dasharray", "0," + Math.max(0, l - 20) + ",40," + length); | |
g.append("use") | |
.attr("xlink:href", "#arrowhead") | |
.attr("transform", "translate(" + end + ") rotate(" + (endAngle * 180 / Math.PI) + ")"); | |
} | |
function pointAtLength(l) { | |
var xy = path.getPointAtLength(l); | |
return [xy.x, xy.y]; | |
} | |
// Approximate tangent | |
function angleAtLength(l) { | |
var a = pointAtLength(Math.max(l - 0.01,0)), // this could be slightly negative | |
b = pointAtLength(l + 0.01); // browsers cap at total length | |
return Math.atan2(b[1] - a[1], b[0] - a[0]); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment