<body>
<svg width="960" height="600">
<g id="map"></g>
<path id="alaska-blocker" fill="#fff" d="M0,300 L500,500 L0,500"></path>
<g id="traces"></g>
</svg>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://unpkg.com/ssvg@1.4.1/ssvg.js"></script>
<script src="https://measure-fps.surge.sh/measureFPS.js"></script>
<script src="http://ssvg-example-resources.surge.sh/data-processing.js"></script>
#map path {
fill: #333;
}
line {
stroke: rgb(255, 255, 255);
}
new SSVG({getFps: function(fps) {
const fpsElement = document.getElementById("fps-element");
fpsElement.innerHTML = fps;
}});
const svg = d3.select("svg");
const mapG = svg.select('#map');
const tracesG = svg.select('#traces');
const projection = d3.geoAlbersUsa();
const path = d3.geoPath()
.projection(projection);
d3.json("https://ssvg-example-resources.surge.sh/us.json").then(us => {
mapG.append("path")
.attr("class", "states")
.datum(topojson.feature(us, us.objects.states))
.attr("d", path);
$.get({url: "https://ssvg-example-resources.surge.sh/latest.json"}).then(response => {
console.log(response);
const data = getParsedData(response);
let pathDs = [];
const numberOfSegments = 4;
let segmentLength = 12;
for (let i = 0; i < Math.random() * 1000000; i++) {
pathDs.push(createPath(projection, data));
}
let numberRafs = 0;
const raf = () => {
numberRafs++;
if(numberRafs > 50) {
for (let i = 0; i < Math.random() * 120; i++) {
pathDs.push(createPath(projection, data));
}
}
pathDs = pathDs.filter(p => p.progressPercent < 300);
const segmentData = [];
for(let d of pathDs) {
const guideLength = d.length;
if (!guideLength) {
continue;
}
d.progressPercent += 1.1; // Move 0.4% of the guide length per frame.
const progressLength = d.progressPercent * guideLength / 100;
for (let i = 0; i < numberOfSegments; i++) {
let startDistance = progressLength + segmentLength * (i - numberOfSegments);
let endDistance = progressLength + segmentLength * (i - numberOfSegments + 1);
startDistance = startDistance < 0 ? 0 : startDistance;
endDistance = endDistance < 0 ? 0 : endDistance;
startDistance = startDistance > guideLength ? guideLength : startDistance;
endDistance = endDistance > guideLength ? guideLength : endDistance;
segmentData.push({
start: getPointAtLength(d, startDistance),
end: getPointAtLength(d, endDistance),
index: i
});
}
}
const segmentLines = tracesG
.selectAll('line')
.data(segmentData);
const pathsEnter = segmentLines.enter()
.append('line')
.attr('opacity', (d) => (d.index + 1) / (numberOfSegments + 2));
pathsEnter.merge(segmentLines)
.attr('x1', d => d.start.x)
.attr('y1', d => d.start.y)
.attr('x2', d => d.end.x)
.attr('y2', d => d.end.y);
requestAnimationFrame(raf);
};
raf();
});
}, err => {
console.error(err);
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.