function renderPath2({ positions, waypoints }) {
let min = { x: 0, y: 0 };
let max = { x: 0, y: 0 };
for (const [x, y] of positions) {
if (x < min.x) min.x = x;
if (y < min.y) min.y = y;
if (x > max.x) max.x = x;
if (y > max.y) max.y = y;
}
const w = max.x - min.x;
const h = max.y - min.y;
const { random, sin, PI } = Math;
let rnd = () =>
random() +
random() -
random() +
random() -
random() +
random() -
random() -
random();
const scale = width / w;
const height = (h * scale) | 0;
const ctx = DOM.context2d(width, height);
let step = 400,
waveOffset = 0;
const render = () => {
ctx.fillStyle = "aqua";
ctx.fillRect(0, 0, w, h);
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.font = "bold 20px sans";
let treshold = 0;
const T = 10;
ctx.fillStyle = "deepskyblue";
const wave = (x, y) => {
return (
sin((waveOffset + x / 13 + y / 5 + rnd()) / T) +
0.25 * sin((step + x / 3 + y / 2 + rnd()) / T) -
0.5 * sin((step + x / 11 + y / 11 + rnd()) / T) +
rnd() * 0.5
);
};
for (let x = 0; x < width; x += 5) {
treshold = (treshold + rnd() * 2) / 10;
for (let y = 0; y < height; y += 5) {
if (wave(x, y) > treshold) {
ctx.fillRect(x, y, 5, 5);
}
}
}
ctx.beginPath();
ctx.moveTo(-min.x * scale, -min.y * scale);
const realStep = Math.min(step, positions.length - 1);
for (let i = 0; i <= realStep; i++) {
const [x, y] = positions[i];
ctx.lineTo((x - min.x) * scale, (y - min.y) * scale);
}
ctx.lineWidth = 1;
ctx.lineWidth = "#000";
ctx.stroke();
ctx.fillText(
"🚢",
(positions[realStep][0] - min.x) * scale,
(positions[realStep][1] - min.y) * scale
);
ctx.fillText(
"🌟",
(positions[realStep][0] + 50 * waypoints[realStep][0] - min.x) * scale,
(positions[realStep][1] + 50 * waypoints[realStep][1] - min.y) * scale
);
ctx.fillStyle = "#000";
ctx.fillText(
Math.min(step, positions.length) + "/" + positions.length,
50,
30
);
step = (step + 1) % (positions.length + 60);
waveOffset += 3;
};
render();
return { ctx, render };
}