// Browser glue: turns a canvas and a window into a Platform. Impure by nature; not part of the exercises' logic. const PREVENT = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ']) export const browserPlatform = (canvas, win) => { const ctx = canvas.getContext('2d') // Keys that scroll the page should only steer the game. const onKey = (cb) => (e) => { if (PREVENT.has(e.key)) e.preventDefault() cb(e.key) } return { fillRect: (x, y, w, h, color) => { ctx.fillStyle = color ctx.fillRect(x, y, w, h) }, fillText: (x, y, text, color, size, align) => { ctx.fillStyle = color ctx.font = `${size}px monospace` ctx.textAlign = align ctx.fillText(text, x, y) }, randomSeed: () => crypto.getRandomValues(new Uint32Array(1))[0], // t is the number of milliseconds since the first frame. startClock: (onTime) => { const frame = (start) => (now) => { const t0 = start ?? now onTime(now - t0) win.requestAnimationFrame(frame(t0)) } win.requestAnimationFrame(frame(undefined)) }, onKeyDown: (cb) => win.addEventListener('keydown', onKey(cb)), onKeyUp: (cb) => win.addEventListener('keyup', onKey(cb)), } }