sleep.js
1.9 kB · javascript · 64 lines
1import { pick } from './frame.js';2import { DESIGNS, LEVELS, NUMBERS, tile } from './tiles.js';34const SPEED = 4;5const SHARE = 0.15;67export function bounce(p, v, max) {8 if (p <= 0) return { p: 0, v: Math.abs(v), hit: true };9 if (p >= max) return { p: max, v: -Math.abs(v), hit: true };10 return { p, v, hit: false };11}1213export function sleep(canvas, view) {14 const ctx = canvas.getContext('2d');15 const rand = view.rand;16 const wide = () => view.w / view.dpr;17 const tall = () => view.h / view.dpr;18 const side = () => Math.min(wide(), tall()) * SHARE;19 let mark;20 let vx = rand() < 0.5 ? SPEED : -SPEED;21 let vy = rand() < 0.5 ? SPEED : -SPEED;22 let x = 0;23 let y = 0;24 const roll = () => {25 mark = tile(pick(rand, DESIGNS), pick(rand, NUMBERS), pick(rand, LEVELS));26 };27 const paint = () => {28 const box = side();29 const n = mark.size;30 ctx.clearRect(0, 0, wide(), tall());31 ctx.fillStyle = view.look().accent;32 for (let r = 0; r < n; r++) {33 const top = Math.round(y + (r * box) / n);34 const bottom = Math.round(y + ((r + 1) * box) / n);35 for (let c = 0; c < n; c++) {36 if (!mark.cells[r * n + c]) continue;37 const left = Math.round(x + (c * box) / n);38 const right = Math.round(x + ((c + 1) * box) / n);39 ctx.fillRect(left, top, right - left, bottom - top);40 }41 }42 };43 const size = () => {44 ctx.setTransform(view.dpr, 0, 0, view.dpr, 0, 0);45 x = Math.min(x, Math.max(0, wide() - side()));46 y = Math.min(y, Math.max(0, tall() - side()));47 };48 const draw = () => {49 const box = side();50 const hx = bounce(x + vx, vx, Math.max(0, wide() - box));51 const hy = bounce(y + vy, vy, Math.max(0, tall() - box));52 x = hx.p;53 vx = hx.v;54 y = hy.p;55 vy = hy.v;56 if (hx.hit || hy.hit) roll();57 paint();58 };59 roll();60 size();61 x = rand() * Math.max(0, wide() - side());62 y = rand() * Math.max(0, tall() - side());63 return { draw, size, theme: paint };64}