UNPKG

sigma

Version:

A JavaScript library dedicated to graph drawing.

271 lines (270 loc) 10.9 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); var captor_1 = __importStar(require("./captor")); /** * Constants. */ var DRAG_TIMEOUT = 200; var DRAGGED_EVENTS_TOLERANCE = 3; var MOUSE_INERTIA_DURATION = 200; var MOUSE_INERTIA_RATIO = 3; var MOUSE_ZOOM_DURATION = 250; var ZOOMING_RATIO = 1.7; var DOUBLE_CLICK_TIMEOUT = 300; var DOUBLE_CLICK_ZOOMING_RATIO = 2.2; var DOUBLE_CLICK_ZOOMING_DURATION = 200; /** * Mouse captor class. * * @constructor */ var MouseCaptor = /** @class */ (function (_super) { __extends(MouseCaptor, _super); function MouseCaptor(container, camera) { var _this = _super.call(this, container, camera) || this; // State _this.enabled = true; _this.draggedEvents = 0; _this.downStartTime = null; _this.lastMouseX = null; _this.lastMouseY = null; _this.isMouseDown = false; _this.isMoving = false; _this.movingTimeout = null; _this.startCameraState = null; _this.clicks = 0; _this.doubleClickTimeout = null; _this.currentWheelDirection = 0; // Binding methods _this.handleClick = _this.handleClick.bind(_this); _this.handleRightClick = _this.handleRightClick.bind(_this); _this.handleDown = _this.handleDown.bind(_this); _this.handleUp = _this.handleUp.bind(_this); _this.handleMove = _this.handleMove.bind(_this); _this.handleWheel = _this.handleWheel.bind(_this); _this.handleOut = _this.handleOut.bind(_this); // Binding events container.addEventListener("click", _this.handleClick, false); container.addEventListener("contextmenu", _this.handleRightClick, false); container.addEventListener("mousedown", _this.handleDown, false); container.addEventListener("mousemove", _this.handleMove, false); container.addEventListener("wheel", _this.handleWheel, false); container.addEventListener("mouseout", _this.handleOut, false); document.addEventListener("mouseup", _this.handleUp, false); return _this; } MouseCaptor.prototype.kill = function () { var container = this.container; container.removeEventListener("click", this.handleClick); container.removeEventListener("contextmenu", this.handleRightClick); container.removeEventListener("mousedown", this.handleDown); container.removeEventListener("mousemove", this.handleMove); container.removeEventListener("wheel", this.handleWheel); container.removeEventListener("mouseout", this.handleOut); document.removeEventListener("mouseup", this.handleUp); }; MouseCaptor.prototype.handleClick = function (e) { var _this = this; if (!this.enabled) return; this.clicks++; if (this.clicks === 2) { this.clicks = 0; if (typeof this.doubleClickTimeout === "number") { clearTimeout(this.doubleClickTimeout); this.doubleClickTimeout = null; } return this.handleDoubleClick(e); } setTimeout(function () { _this.clicks = 0; _this.doubleClickTimeout = null; }, DOUBLE_CLICK_TIMEOUT); // NOTE: this is here to prevent click events on drag if (this.draggedEvents < DRAGGED_EVENTS_TOLERANCE) this.emit("click", captor_1.getMouseCoords(e)); }; MouseCaptor.prototype.handleRightClick = function (e) { if (!this.enabled) return; this.emit("rightClick", captor_1.getMouseCoords(e)); }; MouseCaptor.prototype.handleDoubleClick = function (e) { if (!this.enabled) return; var newRatio = this.camera.getState().ratio / DOUBLE_CLICK_ZOOMING_RATIO; this.camera.animate(this.camera.getViewportZoomedState({ x: captor_1.getX(e), y: captor_1.getY(e) }, { width: this.container.offsetWidth, height: this.container.offsetHeight, }, newRatio), { easing: "quadraticInOut", duration: DOUBLE_CLICK_ZOOMING_DURATION, }); if (e.preventDefault) e.preventDefault(); else e.returnValue = false; e.stopPropagation(); return false; }; MouseCaptor.prototype.handleDown = function (e) { if (!this.enabled) return; this.startCameraState = this.camera.getState(); this.lastMouseX = captor_1.getX(e); this.lastMouseY = captor_1.getY(e); this.draggedEvents = 0; this.downStartTime = Date.now(); // TODO: dispatch events switch (e.which) { default: // Left button pressed this.isMouseDown = true; this.emit("mousedown", captor_1.getMouseCoords(e)); } }; MouseCaptor.prototype.handleUp = function (e) { var _this = this; if (!this.enabled || !this.isMouseDown) return; this.isMouseDown = false; if (typeof this.movingTimeout === "number") { clearTimeout(this.movingTimeout); this.movingTimeout = null; } var x = captor_1.getX(e), y = captor_1.getY(e); var cameraState = this.camera.getState(), previousCameraState = this.camera.getPreviousState(); if (this.isMoving) { this.camera.animate({ x: cameraState.x + MOUSE_INERTIA_RATIO * (cameraState.x - previousCameraState.x), y: cameraState.y + MOUSE_INERTIA_RATIO * (cameraState.y - previousCameraState.y), }, { duration: MOUSE_INERTIA_DURATION, easing: "quadraticOut", }); } else if (this.lastMouseX !== x || this.lastMouseY !== y) { this.camera.setState({ x: cameraState.x, y: cameraState.y, }); } this.isMoving = false; setTimeout(function () { return (_this.draggedEvents = 0); }, 0); this.emit("mouseup", captor_1.getMouseCoords(e)); }; MouseCaptor.prototype.handleMove = function (e) { var _this = this; if (!this.enabled) return; this.emit("mousemove", captor_1.getMouseCoords(e)); if (this.isMouseDown) { // TODO: dispatch events this.isMoving = true; this.draggedEvents++; if (typeof this.movingTimeout === "number") { clearTimeout(this.movingTimeout); } this.movingTimeout = window.setTimeout(function () { _this.movingTimeout = null; _this.isMoving = false; }, DRAG_TIMEOUT); var dimensions = { width: this.container.offsetWidth, height: this.container.offsetHeight, }; var eX = captor_1.getX(e), eY = captor_1.getY(e); var lastMouse = this.camera.viewportToFramedGraph(dimensions, { x: this.lastMouseX, y: this.lastMouseY, }); var mouse = this.camera.viewportToFramedGraph(dimensions, { x: eX, y: eY }); var offsetX = lastMouse.x - mouse.x, offsetY = lastMouse.y - mouse.y; var cameraState = this.camera.getState(); var x = cameraState.x + offsetX, y = cameraState.y + offsetY; this.camera.setState({ x: x, y: y }); this.lastMouseX = eX; this.lastMouseY = eY; } if (e.preventDefault) e.preventDefault(); else e.returnValue = false; e.stopPropagation(); return false; }; MouseCaptor.prototype.handleWheel = function (e) { var _this = this; if (e.preventDefault) e.preventDefault(); else e.returnValue = false; e.stopPropagation(); if (!this.enabled) return false; var delta = captor_1.getWheelDelta(e); if (!delta) return false; var ratioDiff = delta > 0 ? 1 / ZOOMING_RATIO : ZOOMING_RATIO; var newRatio = this.camera.getState().ratio * ratioDiff; var wheelDirection = delta > 0 ? 1 : -1; var now = Date.now(); // Cancel events that are too close too each other and in the same direction: if (this.currentWheelDirection === wheelDirection && this.lastWheelTriggerTime && now - this.lastWheelTriggerTime < MOUSE_ZOOM_DURATION / 5) { return false; } this.camera.animate(this.camera.getViewportZoomedState({ x: captor_1.getX(e), y: captor_1.getY(e) }, { width: this.container.offsetWidth, height: this.container.offsetHeight, }, newRatio), { easing: "quadraticOut", duration: MOUSE_ZOOM_DURATION, }, function () { _this.currentWheelDirection = 0; }); this.currentWheelDirection = wheelDirection; this.lastWheelTriggerTime = now; return false; }; MouseCaptor.prototype.handleOut = function () { // TODO: dispatch event }; return MouseCaptor; }(captor_1.default)); exports.default = MouseCaptor;