summaryrefslogtreecommitdiff
path: root/src/Canvas.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/Canvas.js')
-rw-r--r--src/Canvas.js144
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;