diff options
author | sanine <sanine.not@pm.me> | 2022-05-31 22:54:59 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-05-31 22:54:59 -0500 |
commit | f82f540a0cf07e8fd95e36dea10a49aa839832d0 (patch) | |
tree | a0855b56182f521781a0b33247e5f08a23604f1f /src/Canvas.js | |
parent | 5efc7885e1c3959aa165be640858ffb3f8a5860b (diff) |
move test.js and package.json to the root
Diffstat (limited to 'src/Canvas.js')
-rw-r--r-- | src/Canvas.js | 144 |
1 files changed, 0 insertions, 144 deletions
diff --git a/src/Canvas.js b/src/Canvas.js deleted file mode 100644 index 6dff7bd..0000000 --- a/src/Canvas.js +++ /dev/null @@ -1,144 +0,0 @@ -import { clamp } from './modules/Util.js'; - -class Canvas { - constructor(rootId) { - const root = document.getElementById(rootId); - - this.element = document.createElement('canvas'); - this.context = this.element.getContext('2d'); - - /* state variables */ - this.scale = 1; - this.zoom = 1; - const ZOOM_SPEED = 1.2; - - this.mouse = { - screenPos: { x: 0, y: 0 }, - drawingPos: { x: 0, y: 0 }, - }; - this.pan = { x: 0, y: 0 }; - this.panning = false; - - /* callbacks */ - this.onDraw = null; - this.onMouseMove = null; - this.onMouseDown = null; - this.onMouseUp = null; - - /* register event listeners */ - - /* mouse movement */ - this.element.addEventListener('mousemove', e => { - this.mouse.screenPos.x = e.offsetX; - this.mouse.screenPos.y = e.offsetY; - - const [xd, yd] = this.screenToDrawingPos(e.offsetX, e.offsetY); - - /* compute movement */ - const dx = e.movementX / (this.zoom * this.scale); - const dy = e.movementY / (this.zoom * this.scale); - - /* pan? */ - if (this.panning) { - this.pan.x += dx; - this.pan.y += dy; - this.setTransform(); - } - - this.mouse.drawingPos.x = xd; - this.mouse.drawingPos.y = yd; - - if (this.onMouseMove) this.onMouseMove(this.mousePos); - }); - - /* clicking */ - this.element.addEventListener('mousedown', e => { - e.preventDefault(); - if (e.button === 1) this.panning = true; - if (this.onMouseDown) this.onMouseDown(e); - }); - this.element.addEventListener('mouseup', e => { - if (e.button === 1) this.panning = false; - if (this.onMouseUp) this.onMouseUp(e); - }); - - /* mouse leave */ - this.element.addEventListener('mouseleave', e => { - this.panning = false; - }); - - /* mouse wheel */ - this.element.addEventListener('wheel', e => { - if (this.panning) return; // don't zoom and pan simultaneously - - const delta = e.deltaY < 0 ? ZOOM_SPEED : 1/ZOOM_SPEED; - const alpha = (1/delta) - 1; - - /* zoom in */ - this.zoom *= delta; - this.zoom = clamp(this.zoom, 1, 1000); - this.setTransform(); - - /* pan to keep mouse in the same place */ - const [mouseX, mouseY] = this.screenToDrawingPos(this.mouse.screenPos.x, this.mouse.screenPos.y); - this.pan.x += mouseX - this.mouse.drawingPos.x; - this.pan.y += mouseY - this.mouse.drawingPos.y; - this.setTransform(); - this.draw(); - }); - - /* finalize setup */ - this.fillWindow(); - window.addEventListener('resize', () => this.fillWindow()); - root.appendChild(this.element); - } - - setTransform() { - /* clamp pan */ - const xMax = this.pixelsToUnits(this.element.width) - 1; - const yMax = this.pixelsToUnits(this.element.height) - 1; - this.pan.x = clamp(this.pan.x, xMax, 0); - this.pan.y = clamp(this.pan.y, yMax, 0); - - this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.scale(this.zoom * this.scale, this.zoom * this.scale); - this.context.translate(this.pan.x, this.pan.y); - } - - fillWindow() { - const width = window.innerWidth; - const height = window.innerHeight; - this.scale = Math.max(width, height); - - this.element.width = width; this.element.height = height; - this.setTransform(); - - this.draw(); - } - - pixelsToUnits(value) { - return value / this.zoom / this.scale; - } - - unitsToPixels(value) { - return value * this.zoom * this.scale; - } - - screenToDrawingPos(xs, ys) { - const matrix = this.context.getTransform(); - matrix.invertSelf(); - - /* compute drawing-space position */ - const x = matrix.a*xs + matrix.b*ys + matrix.e; - const y = matrix.c*xs + matrix.d*ys + matrix.f; - - return [ x, y ]; - } - - draw() { - this.context.clearRect(0, 0, 1, 1); - if (this.onDraw) this.onDraw(this.context); - } -} - -export default Canvas; |