canvas = {
const imgs = await Promise.all([FileAttachment("DSC_5805.jpg").image(),
FileAttachment("20191018-DSC_2449-Pano.jpg").image(), FileAttachment("20191018-DSC_2504.jpg").image(), FileAttachment("Dragons Teeth, Kapalua, Maui.jpg").image(), FileAttachment("Family Fishing at Dragons Teeth, Kapalua, Maui.jpg").image(), FileAttachment("Makaluapuna Point, Kapalua, Maui - panorama.jpg").image(), FileAttachment("Moonrise over Haleakala - panorama.jpg").image(), FileAttachment("Moonsea.jpg").image()]);
const context = DOM.context2d(width, height);
const particles = Array.from({length: imgs.length}, () => [Math.random() * width, Math.random() * height]);
function update() {
const delaunay = d3.Delaunay.from(particles);
const voronoi = delaunay.voronoi([0.5, 0.5, width - 0.5, height - 0.5]);
context.clearRect(0, 0, width, height);
for(let i = 0; i < particles.length; i++) {
context.save();
context.beginPath();
voronoi.renderCell(i, context);
context.strokeStyle = "#000";
context.stroke();
context.clip();
const img = imgs[i % imgs.length];
const aspectRatio = img.width / img.height;
let x = 0, y = 0, imgWidth = img.width, imgHeight = img.height;
if (aspectRatio <= 1) {
imgWidth = width - x;
imgHeight = imgWidth / aspectRatio;
} else {
imgHeight = height - y;
imgWidth = imgHeight * aspectRatio;
}
context.drawImage(img, 0, 0, img.width, img.height, x, y, imgWidth, imgHeight);
context.restore();
}
voronoi.renderBounds(context);
context.strokeStyle = "#000";
context.stroke();
context.beginPath();
delaunay.renderPoints(context);
context.fill();
context.canvas.ontouchmove =
context.canvas.onmousemove = event => {
event.preventDefault();
particles[0] = [event.layerX, event.layerY];
const closestIdx = delaunay.find(event.layerX, event.layerY);
update();
};
}
update();
return context.canvas;
}