|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<style> |
|
body { |
|
display: table; |
|
margin: 0 auto; |
|
} |
|
|
|
svg { |
|
overflow: visible; |
|
} |
|
|
|
.outline { |
|
stroke: black; |
|
fill: #eee; |
|
} |
|
|
|
.text { |
|
font-family: sans-serif; |
|
paint-order: stroke fill; |
|
stroke: white; |
|
stroke-linecap: round; |
|
stroke-linejoin: round; |
|
stroke-opacity: .9; |
|
stroke-width: 4px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<script src="https://d3js.org/d3.v6.min.js"></script> |
|
<script src="https://unpkg.com/d3-geo-scale-bar@1"></script> |
|
<script src="https://unpkg.com/[email protected]"></script> |
|
<script> |
|
let size; |
|
|
|
const projection = d3.geoMercator(); |
|
const path = d3.geoPath(projection); |
|
|
|
const scaleBar = d3.geoScaleBar() |
|
.units(d3.geoScaleMiles) |
|
.left(0) |
|
.top(1) |
|
.projection(projection); |
|
|
|
const svg = d3.select("body").append("svg"); |
|
|
|
const outline = svg.append("path") |
|
.attr("class", "outline"); |
|
|
|
const text = svg.append("text") |
|
.attr("class", "text") |
|
.attr("dy", 16); |
|
|
|
const bar = svg.append("g") |
|
.attr("transform", `translate(5, -20)`) |
|
.append("g"); |
|
|
|
d3.json("geoJsonUsa.json") |
|
.then(usa => { |
|
let i = 0, state = usa.features[i], prevPath = path(state); |
|
|
|
draw(); |
|
update(); |
|
|
|
d3.interval(_ => { |
|
update(); |
|
}, 1500); |
|
|
|
addEventListener("resize", draw); |
|
|
|
function draw(){ |
|
size = Math.min(innerWidth, 500); |
|
|
|
projection.fitSize([size, size], state); |
|
scaleBar.size([size, size]); |
|
|
|
svg |
|
.attr("width", size) |
|
.attr("height", size); |
|
|
|
bar.call(scaleBar); |
|
} |
|
|
|
function update(){ |
|
i = i === usa.features.length - 1 ? 0 : i + 1; |
|
state = usa.features[i]; |
|
projection.fitSize([size, size], state); |
|
|
|
const currPath = path(state), |
|
interpolator = flubber.interpolate(prevPath, currPath); |
|
|
|
outline |
|
.transition().duration(1000) |
|
.attrTween("d", _ => interpolator); |
|
|
|
text.text(state.properties.name); |
|
|
|
bar |
|
.transition().duration(1000) |
|
.call(scaleBar); |
|
|
|
prevPath = currPath; |
|
} |
|
}); |
|
|
|
</script> |
|
</body> |
|
</html> |