function init_listeners(state, context) { window.addEventListener('keydown', (e) => keydown(e, state)); window.addEventListener('keyup', (e) => keyup(e, state)); context.canvas.addEventListener('mousedown', (e) => mousedown(e, state, context)); context.canvas.addEventListener('mousemove', (e) => mousemove(e, state, context)); context.canvas.addEventListener('mouseup', (e) => mouseup(e, state, context)); context.canvas.addEventListener('wheel', (e) => wheel(e, state, context)); } function keydown(e, state) { if (e.code === 'Space') { state.spacedown = true; } else if (e.code === 'KeyD') { } } function keyup(e, state) { if (e.code === 'Space') { state.spacedown = false; state.moving = false; } } function mousedown(e, state, context) { if (state.spacedown) { state.moving = true; return; } const x = cursor_x = (e.clientX - state.canvas.offset.x) / state.canvas.zoom; const y = cursor_y = (e.clientY - state.canvas.offset.y) / state.canvas.zoom; clear_dynamic_stroke(state, context); update_dynamic_stroke(state, context, {'x': x, 'y': y}); state.drawing = true; window.requestAnimationFrame(() => draw(state, context)); } function mousemove(e, state, context) { let do_draw = false; if (state.moving) { state.canvas.offset.x += e.movementX; state.canvas.offset.y += e.movementY; do_draw = true; } if (state.drawing) { const x = cursor_x = (e.clientX - state.canvas.offset.x) / state.canvas.zoom; const y = cursor_y = (e.clientY - state.canvas.offset.y) / state.canvas.zoom; update_dynamic_stroke(state, context, {'x': x, 'y': y}); do_draw = true; } if (do_draw) { window.requestAnimationFrame(() => draw(state, context)); } } function mouseup(e, state, context) { if (state.spacedown) { state.moving = false; return; } if (state.drawing) { const stroke = { 'color': Math.round(Math.random() * 4294967295), 'points': process_stroke(state.current_stroke.points) }; add_static_stroke(state, context, stroke); clear_dynamic_stroke(state, context); state.drawing = false; window.requestAnimationFrame(() => draw(state, context)); return; } } function wheel(e, state, context) { const x = Math.round((e.clientX - state.canvas.offset.x) / state.canvas.zoom); const y = Math.round((e.clientY - state.canvas.offset.y) / state.canvas.zoom); const dz = (e.deltaY < 0 ? 0.1 : -0.1); const old_zoom = state.canvas.zoom; state.canvas.zoom *= (1.0 + dz); if (state.canvas.zoom > 100.0) { state.canvas.zoom = old_zoom; return; } if (state.canvas.zoom < 0.2) { state.canvas.zoom = old_zoom; return; } const zoom_offset_x = Math.round((dz * old_zoom) * x); const zoom_offset_y = Math.round((dz * old_zoom) * y); state.canvas.offset.x -= zoom_offset_x; state.canvas.offset.y -= zoom_offset_y; window.requestAnimationFrame(() => draw(state, context)); }