UNPKG

jeri

Version:

JavaScript Extended-Range Image viewer

160 lines 7.65 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var linalg_1 = require("../utils/linalg"); var Layer_1 = require("./Layer"); var normalizeWheel = require('normalize-wheel'); var SCROLL_FACTOR = 1.001; /** * Mouse Layer * @todo add some proper documentation */ var MouseLayer = /** @class */ (function (_super) { __extends(MouseLayer, _super); function MouseLayer(canvas, image, enableMouseEvents) { var _this = _super.call(this, canvas, image) || this; _this.panningState = null; _this.unsubscribeFunctions = []; /** To be called on destruct */ _this.handleMouseMove = _this.handleMouseMove.bind(_this); _this.handleMouseDown = _this.handleMouseDown.bind(_this); _this.handleMouseUp = _this.handleMouseUp.bind(_this); _this.handleScroll = _this.handleScroll.bind(_this); _this.handlePointReporting = _this.handlePointReporting.bind(_this); _this.enableMouseEvents = enableMouseEvents; // Subscribe to changes in the layers reactive inputs and window size var unsubscribe; document.addEventListener('mouseup', _this.handleMouseUp); unsubscribe = document.removeEventListener.bind(document, 'mouseup', _this.handleMouseUp); _this.unsubscribeFunctions.push(unsubscribe); document.addEventListener('mousemove', _this.handleMouseMove); unsubscribe = document.removeEventListener.bind(document, 'mousemove', _this.handleMouseMove); _this.unsubscribeFunctions.push(unsubscribe); canvas.addEventListener('wheel', _this.handleScroll); unsubscribe = canvas.removeEventListener.bind(canvas, 'wheel', _this.handleScroll); _this.unsubscribeFunctions.push(unsubscribe); canvas.addEventListener('mousedown', _this.handleMouseDown); unsubscribe = canvas.removeEventListener.bind(canvas, 'mousedown', _this.handleMouseDown); _this.unsubscribeFunctions.push(unsubscribe); canvas.addEventListener('mousemove', _this.handlePointReporting); unsubscribe = canvas.removeEventListener.bind(canvas, 'mousemove', _this.handlePointReporting); _this.unsubscribeFunctions.push(unsubscribe); return _this; } MouseLayer.prototype.setTransformation = function (transformation, broadcast) { if (broadcast === void 0) { broadcast = false; } this.transformation = transformation; if (broadcast && this.transformationCallback != null) { this.transformationCallback(transformation); } }; MouseLayer.prototype.setEnableMouseEvents = function (enable) { this.enableMouseEvents = enable; }; MouseLayer.prototype.onTransformationChange = function (callback) { this.transformationCallback = callback; }; MouseLayer.prototype.setImage = function (image) { this.image = image; }; MouseLayer.prototype.onPointAt = function (callback) { this.pointCallback = callback; }; MouseLayer.prototype.destruct = function () { this.unsubscribeFunctions.forEach(function (fn) { return fn(); }); }; MouseLayer.prototype.handleMouseMove = function (event) { if (!this.enableMouseEvents) { return; } if (this.panningState) { var _a = this.relativeMousePosition(event.clientX, event.clientY), x = _a.x, y = _a.y; var dx = x - this.panningState.previousMouse.x; var dy = y - this.panningState.previousMouse.y; var transformation = linalg_1.Matrix4x4.create(); var aspect = this.getAspect(); linalg_1.Matrix4x4.translate(transformation, transformation, [dx / aspect.x, dy / aspect.y, 0.0]); linalg_1.Matrix4x4.multiply(transformation, transformation, this.transformation); this.setTransformation(transformation, true); this.panningState.previousMouse = { x: x, y: y }; } }; MouseLayer.prototype.handleMouseUp = function (event) { if (this.panningState) { this.panningState = null; } }; MouseLayer.prototype.handleMouseDown = function (event) { var mousePosition = this.relativeMousePosition(event.clientX, event.clientY); this.panningState = { transformationAtStart: linalg_1.Matrix4x4.clone(this.transformation), previousMouse: mousePosition, }; }; MouseLayer.prototype.handleScroll = function (event) { if (!this.enableMouseEvents) { return; } event.preventDefault(); var pixelY = normalizeWheel(event).pixelY; var mouse = this.relativeMousePosition(event.clientX, event.clientY); var transformation = linalg_1.Matrix4x4.create(); var deltaMatrix = linalg_1.Matrix4x4.create(); var aspect = this.getAspect(); linalg_1.Matrix4x4.translate(deltaMatrix, deltaMatrix, [mouse.x / aspect.x, mouse.y / aspect.y, 0.0]); var scaleFactor = Math.pow(SCROLL_FACTOR, pixelY); linalg_1.Matrix4x4.scale(deltaMatrix, deltaMatrix, [scaleFactor, scaleFactor, 1.0]); linalg_1.Matrix4x4.translate(deltaMatrix, deltaMatrix, [-mouse.x / aspect.x, -mouse.y / aspect.y, 0.0]); linalg_1.Matrix4x4.multiply(transformation, deltaMatrix, this.transformation); this.setTransformation(transformation, true); }; /** * Event handler for reporting mouse movement. * * Only applicable when the options 'onPoint' property is set on this component. */ MouseLayer.prototype.handlePointReporting = function (event) { if (this.pointCallback) { if (!this.panningState) { var _a = this.relativeMousePosition(event.clientX, event.clientY), x = _a.x, y = _a.y; var imageCoordinates = this.canvasToImage(x, y); this.pointCallback(imageCoordinates.x, imageCoordinates.y); } } }; /** * Translate clientX and clientY values to relative positions within the bounding box * of the viewer. */ MouseLayer.prototype.relativeMousePosition = function (clientX, clientY) { var _a = this.canvas, clientWidth = _a.clientWidth, clientHeight = _a.clientHeight; var _b = this.canvas.getBoundingClientRect(), left = _b.left, top = _b.top; return { x: -1.0 + 2.0 * (clientX - left) / clientWidth, y: 1.0 - 2.0 * (clientY - top) / clientHeight, }; }; /** * Translate canvas coordinates to image coodrinates */ MouseLayer.prototype.canvasToImage = function (x, y) { var point = linalg_1.Vector4.create(); linalg_1.Vector4.set(point, x, y, 1.0, 1.0); var inverseViewMatrix = linalg_1.Matrix4x4.create(); var viewMatrix = this.getViewMatrix(); linalg_1.Matrix4x4.invert(inverseViewMatrix, viewMatrix); linalg_1.Vector4.transformMat4(point, point, inverseViewMatrix); return { x: point.data[0], y: point.data[1] }; }; return MouseLayer; }(Layer_1.default)); exports.default = MouseLayer; //# sourceMappingURL=MouseLayer.js.map