UNPKG

pencil.js

Version:

Nice modular interactive 2D drawing library.

97 lines (83 loc) 2.91 kB
import Component from "@pencil.js/component"; import MouseEvent from "@pencil.js/mouse-event"; /** * @module Rotatable */ /** * @typedef {Object} RotatableAPI * @prop {Function} stop - Stop the component from being rotatable */ /** * Set this component rotatable (use drag and drop interaction to rotate) * @return {RotatableAPI} * @memberOf module:Component# */ Component.prototype.rotatable = function rotatable () { if (this.isDraggable) { throw new Error("Component can't be both draggable and rotatable."); } const cursorNotSet = this.options.cursor === Component.cursors.default; if (cursorNotSet) { this.options.cursor = Component.cursors.grab; } this.isRotatable = true; this.isRotated = false; let previousAngle = null; let startingAngle = null; const downHandler = ({ position }) => { if (cursorNotSet) { this.options.cursor = Component.cursors.grabbing; } previousAngle = this.options.rotation; startingAngle = position.subtract(this.getAbsolutePosition()).angle; this.isRotated = true; this.fire(new MouseEvent(MouseEvent.events.grab, this, position)); }; this.on(MouseEvent.events.down, downHandler); const moveHandler = ({ position }) => { if (previousAngle !== null) { const absolutePosition = this.getAbsolutePosition(); this.options.rotation = previousAngle + position.subtract(absolutePosition).angle - startingAngle; this.fire(new MouseEvent(MouseEvent.events.rotate, this, position)); } }; const upHandler = ({ position }) => { if (cursorNotSet) { this.options.cursor = Component.cursors.grab; } if (previousAngle !== null && this.isRotated) { previousAngle = null; startingAngle = null; this.isRotated = false; this.fire(new MouseEvent(MouseEvent.events.drop, this, position)); } }; let scene; this.getScene().then((theScene) => { if (this.isRotatable) { scene = theScene; scene .on(MouseEvent.events.move, moveHandler) .on(MouseEvent.events.up, upHandler); } }); return { /** * Stop the component from being rotatable * @memberOf RotatableAPI# */ stop: () => { this.removeListener(MouseEvent.events.down, downHandler, true); if (scene) { scene .removeListener(MouseEvent.events.move, moveHandler) .removeListener(MouseEvent.events.up, upHandler); } if (cursorNotSet) { this.options.cursor = Component.cursors.default; } this.isRotatable = false; this.isRotated = false; }, }; };