{
replay;
const div = html`<div style="height:${height}px;">`;
const canvas = div.appendChild(context.canvas);
context.canvas.style.maxWidth = "100%";
context.lineJoin = "round";
context.lineCap = "round";
let timer;
const duration = 10000;
const zoomDuration = 600;
const ease = d3.easeLinear;
function drawNation() {
context.beginPath();
context.lineWidth = 0.25;
context.strokeStyle = "#00000080";
path(topojson.mesh(us, us.objects.states, (a, b) => a !== b));
context.stroke();
context.beginPath();
context.lineWidth = 0.5;
context.strokeStyle = "#000";
path(topojson.feature(us, us.objects.nation));
context.stroke();
}
function pointStyles() {
context.fillStyle = "#94d2ff";
context.strokeStyle = "#EEE";
context.lineWidth = 0.5;
}
function drawPoints(data) {
for (var i = 0, n = data.length; i < n; ++i) {
const city = data[i];
if (city.current >= 0) {
context.beginPath();
context.arc(...city.coords, city.current, 0, city.current * Math.PI);
context.fill();
context.stroke();
}
}
}
function zoom(transform) {
context.save();
context.clearRect(0, 0, width, height);
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
drawNation();
pointStyles();
drawPoints(cities);
context.restore();
}
const interpolate = d3.interpolate(
{
k: 1,
x: 0,
y: 0
},
{
k: 4.09538760171377,
x: -2759.7118990427607,
y: -378.4222927920223
}
);
let start = null;
function step(timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
var t = progress / zoomDuration;
var scale = interpolate(t);
zoom(scale);
if (progress < zoomDuration) {
window.requestAnimationFrame(step);
}
}
function animate() {
timer = d3.timer(elapsed => {
context.clearRect(0, 0, width, height);
pointStyles();
const time = Math.min(1, ease(elapsed / duration));
const filtered = cities.filter((c, i) => (1 - time) * cities.length < i);
filtered.forEach(city => {
city.current -= 0.05;
if (city.current < city.end) city.current = city.start;
});
drawPoints(filtered);
drawNation();
if (time === 1) {
timer.stop();
window.requestAnimationFrame(step);
}
});
}
Promises.delay(1000).then(() => {
animate();
});
yield visibility(div);
}