
Created 2025-09-12
/** * ============================================================================ * = Moondial: Moon Sundial = * ============================================================================ * * I'm taking a class called **Time**. The first assignment is to create a * sundial. It could be a physic device, or a digital one and really depends * on your imagination. * * So I'm wondering what features make a sundial a sundial? * * ChatGPT says: * * > A sundial is a device that tells the time by casting a shadow from a * > stick or gnomon onto a marked surface, using the sun’s position in the * > sky. * * I get two features from the definition: * * 1. It tells the time using the sun's position. * 2. It casts a shadow from an object. * * Based on these features, a sundial to me is **a device that maps the time to * visual patterns formed by shadows**. So I think why not create a moon * sundial? It uses shadows from a matrix of moons and the phases of the moon * relies on the time. Then I based on Mike's "Beesandbombs"[1] to create this * **Moondial**. * * This piece is a good example of how to use emojis to create animations in * Recho. Also, theoretically speaking, you can tell time based the pattern of * this matrix if the animation slows down and you're familiar enough with it! */ const moons = ["🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘", "🌑"]; const size = 20; const now = recho.now(); const rotate = d3.scaleLinear([-360, 360], [0, moons.length - 1]); const pos = d3.scaleLinear([0, size], [-1, 1]); //➜ 🌘🌕🌕🌕🌕🌕🌕🌖🌖🌖🌖🌕🌕🌕🌕🌕🌕🌘🌘🌘 //➜ 🌕🌕🌕🌕🌖🌖🌖🌖🌖🌖🌖🌖🌖🌖🌕🌕🌕🌕🌘🌘 //➜ 🌕🌕🌖🌖🌖🌖🌖🌖🌖🌖🌖🌖🌖🌖🌖🌕🌕🌕🌕🌘 //➜ 🌕🌖🌖🌖🌖🌗🌗🌗🌗🌗🌗🌗🌖🌖🌖🌖🌕🌕🌕🌘 //➜ 🌖🌖🌖🌖🌗🌗🌗🌗🌗🌗🌗🌗🌗🌗🌖🌖🌖🌕🌕🌕 //➜ 🌖🌖🌖🌗🌗🌗🌗🌘🌘🌘🌘🌗🌗🌗🌗🌖🌖🌖🌕🌕 //➜ 🌖🌖🌗🌗🌗🌘🌘🌘🌘🌘🌘🌘🌗🌗🌗🌖🌖🌖🌕🌕 //➜ 🌖🌗🌗🌗🌘🌘🌘🌘🌘🌘🌘🌘🌘🌗🌗🌗🌖🌖🌕🌕 //➜ 🌖🌗🌗🌗🌘🌘🌘🌕🌕🌕🌕🌘🌘🌗🌗🌗🌖🌖🌕🌕 //➜ 🌖🌗🌗🌘🌘🌘🌕🌕🌕🌕🌕🌘🌘🌗🌗🌗🌖🌖🌕🌕 //➜ 🌗🌗🌗🌘🌘🌕🌕🌕🌖🌖🌕🌘🌘🌗🌗🌗🌖🌖🌕🌕 //➜ 🌗🌗🌗🌘🌘🌕🌕🌕🌖🌖🌗🌗🌗🌗🌗🌖🌖🌖🌕🌕 //➜ 🌗🌗🌗🌘🌘🌕🌕🌕🌖🌖🌗🌗🌗🌗🌖🌖🌖🌕🌕🌕 //➜ 🌗🌗🌗🌘🌘🌕🌕🌕🌖🌖🌖🌖🌖🌖🌖🌖🌖🌕🌕🌕 //➜ 🌖🌗🌗🌘🌘🌘🌕🌕🌕🌖🌖🌖🌖🌖🌖🌖🌕🌕🌕🌘 //➜ 🌖🌗🌗🌘🌘🌘🌕🌕🌕🌕🌖🌖🌖🌖🌕🌕🌕🌕🌘🌘 //➜ 🌖🌗🌗🌗🌘🌘🌘🌕🌕🌕🌕🌕🌕🌕🌕🌕🌕🌘🌘🌘 //➜ 🌖🌖🌗🌗🌗🌘🌘🌘🌘🌕🌕🌕🌕🌕🌕🌕🌘🌘🌘🌘 //➜ 🌖🌖🌗🌗🌗🌗🌘🌘🌘🌘🌘🌘🌘🌘🌘🌘🌘🌘🌘🌗 //➜ 🌖🌖🌖🌗🌗🌗🌗🌘🌘🌘🌘🌘🌘🌘🌘🌘🌘🌗🌗🌗 { let output = ""; for (let i = 0; i < size; i++) { for (let j = 0; j < size; j++) { const [x, y] = [pos(j), pos(i)]; const r = Math.hypot(x, y); const theta = Math.atan2(y, x) / (Math.PI * 2); const phase = now / 3000; const l = ((r + theta - phase) % 1) * -360; const index = ~~rotate(l); output += moons[index]; } output += i == size - 1 ? "" : "\n"; } echo(output); } const d3 = recho.require("d3"); /** * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * References * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * [1] https://observablehq.com/d/a741f9a27e8c0e73 */