import { EvHandler, EvHandlerRes, Mouse } from "./input.ts"; import { Renderer, RendererImage } from "./renderer.ts"; export class CanvasRenderer implements Renderer { constructor( private c: HTMLCanvasElement, private g: CanvasRenderingContext2D, ) {} get width(): number { return this.c.width; } get height(): number { return this.c.height; } clear(color: string): void { const { g } = this; g.fillStyle = color; g.fillRect(0, 0, this.c.width, this.c.height); } fillRect(x: number, y: number, w: number, h: number, color: string): void { const { g } = this; g.fillStyle = color; g.fillRect(x, y, w, h); } strokeRect( x: number, y: number, w: number, h: number, color: string, lineWidth: number, ): void { const { g } = this; g.strokeStyle = color; g.lineWidth = lineWidth; g.strokeRect(x, y, w, h); } fillCirc(x: number, y: number, radius: number, color: string): void { const { g } = this; g.fillStyle = color; g.beginPath(); g.arc(x, y, radius, 0, Math.PI * 2); g.fill(); } putImage( data: RendererImage, x: number, y: number, w = data.width, h = data.height, alpha = 1, ): void { const { g } = this; g.globalAlpha = alpha; g.drawImage(data, x, y, w, h); g.globalAlpha = 1.0; } } export class CanvasMouse implements Mouse { public x = 0; public y = 0; private pressHandlers: EvHandler[] = []; private releaseHandlers: EvHandler[] = []; private moveHandlers: EvHandler[] = []; private scrollHandlers: ((direction: "up" | "down") => EvHandlerRes)[] = []; constructor(c: HTMLCanvasElement) { c.onmousemove = (ev) => { this.x = ev.x; this.y = ev.y; }; c.onmousedown = (ev) => { if (ev.button === 0) { this.runHandlers(this.pressHandlers); } }; c.onmouseup = (ev) => { if (ev.button === 0) { this.runHandlers(this.releaseHandlers); } }; c.onmousemove = (ev) => { this.x = ev.x; this.y = ev.y; this.runHandlers(this.moveHandlers); }; c.onwheel = (ev) => { if (ev.deltaY !== 0) { this.runHandlers( this.scrollHandlers, ev.deltaY < 0 ? "up" : "down", ); } }; } private runHandlers( handlers: EvHandler[], ...args: Args ) { for (const handler of handlers.toReversed()) { if (handler(...args) === "stop") { break; } } } addOnPress(handler: EvHandler) { this.pressHandlers.push(handler); } addOnRelease(handler: EvHandler) { this.releaseHandlers.push(handler); } addOnMove(handler: EvHandler) { this.moveHandlers.push(handler); } addOnScroll(handler: EvHandler<["up" | "down"]>) { this.scrollHandlers.push(handler); } }