const SMALLEST_SIZE = 4.0; const LARGEST_SIZE = 48.0; const DEFAULT_SIZE = 24.0; class State { updateWindowSize(w, h) { this.w = w; this.h = h; this.canvas.width = w; this.canvas.height = h; this.data = {}; } constructor(canvas, ctx, w, h) { this.canvas = canvas; this.ctx = ctx; this.updateWindowSize(w, h); this.size = DEFAULT_SIZE; this.mode = 'square'; } scroll(delta) { this.size += delta / 30.0; if (this.size < SMALLEST_SIZE) { this.size = SMALLEST_SIZE; } else if (this.size > LARGEST_SIZE) { this.size = LARGEST_SIZE; } } draw(mouseLoc) { this.ctx.clearRect(0, 0, this.w, this.h); if (mouseLoc !== null) { let [fx, fy] = mouseLoc; this.ctx.fillStyle = '#f00'; if (this.mode === 'square') { fx = Math.floor(fx / this.size); fy = Math.floor(fy / this.size); this.ctx.fillRect(fx * this.size, fy * this.size, this.size, this.size); } else { this.ctx.strokeStyle = '#f00'; const half = this.size / 2 fx = Math.floor((fx + half) / this.size); fy = Math.floor((fy + half) / this.size); this.ctx.moveTo(fx * this.size, fy * this.size); this.ctx.arc(fx * this.size, fy * this.size, 5, 0, Math.PI * 2, true); this.ctx.stroke(); } } this.ctx.strokeStyle = '#000'; for (let x = 0; Math.floor(x / this.size < this.w); x++) { this.ctx.beginPath(); this.ctx.moveTo(x * this.size, 0); this.ctx.lineTo(x * this.size, this.h); this.ctx.stroke(); } for (let y = 0; Math.floor(y / this.size < this.h); y++) { this.ctx.beginPath(); this.ctx.moveTo(0, y * this.size); this.ctx.lineTo(this.w, y * this.size); this.ctx.stroke(); } } } let main = () => { const canvas = document.getElementById('cv'); const w = window.innerWidth; const h = window.innerHeight; const ctx = canvas.getContext('2d'); let state = new State(canvas, ctx, w, h); let last_mouse = null; state.draw(last_mouse); document.addEventListener('mousemove', e => { last_mouse = [e.clientX, e.clientY]; state.draw(last_mouse); }); document.addEventListener('wheel', e => { state.scroll(-e.deltaY); state.draw(last_mouse); }); window.addEventListener('resize', () => { state.updateWindowSize( window.innerWidth, window.innerHeight, ); state.draw(last_mouse); }); document.addEventListener('keydown', e => { if (e.key === ' ') { if (state.mode === 'square') state.mode = 'dot'; else state.mode = 'square'; } state.draw(last_mouse); }); }; window.onload = main;