summaryrefslogtreecommitdiff
path: root/src/Canvas.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/Canvas.js')
-rw-r--r--src/Canvas.js127
1 files changed, 5 insertions, 122 deletions
diff --git a/src/Canvas.js b/src/Canvas.js
index 6dff7bd..f3db3e0 100644
--- a/src/Canvas.js
+++ b/src/Canvas.js
@@ -1,142 +1,25 @@
-import { clamp } from './modules/Util.js';
-
class Canvas {
- constructor(rootId) {
- const root = document.getElementById(rootId);
-
+ constructor(parentElement) {
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 */
+ parentElement.appendChild(this.element);
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);
+ const scale = Math.min(width, height);
this.element.width = width; this.element.height = height;
- this.setTransform();
+ this.context.setTransform(0.4*scale, 0, 0, -0.4*scale, 0.5*scale, 0.5*scale);
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);
+ this.context.clearRect(-1, -1, 2, 2);
if (this.onDraw) this.onDraw(this.context);
}
}