PHP Classes

File: toastui/src/js/component/shape.js

Recommend this page to a friend!
  Classes of Mark de Leon   PHP Document Scanner using SANE or eSCL AirPrint   toastui/src/js/component/shape.js   Download  
File: toastui/src/js/component/shape.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: PHP Document Scanner using SANE or eSCL AirPrint
Web interface to scan printed documents
Author: By
Last change:
Date: 4 years ago
Size: 13,165 bytes
 

Contents

Class file image Download
/** * @author NHN Ent. FE Development Team <dl_javascript@nhn.com> * @fileoverview Shape component */ import fabric from 'fabric/dist/fabric.require'; import Promise from 'core-js/library/es6/promise'; import Component from '../interface/component'; import consts from '../consts'; import resizeHelper from '../helper/shapeResizeHelper'; import {extend, inArray} from 'tui-code-snippet'; const {rejectMessages, eventNames} = consts; const KEY_CODES = consts.keyCodes; const DEFAULT_TYPE = 'rect'; const DEFAULT_WIDTH = 20; const DEFAULT_HEIGHT = 20; const DEFAULT_OPTIONS = { strokeWidth: 1, stroke: '#000000', fill: '#ffffff', width: 1, height: 1, rx: 0, ry: 0, lockSkewingX: true, lockSkewingY: true, lockUniScaling: false, bringForward: true, isRegular: false }; const shapeType = ['rect', 'circle', 'triangle']; /** * Shape * @class Shape * @param {Graphics} graphics - Graphics instance * @extends {Component} * @ignore */ class Shape extends Component { constructor(graphics) { super(consts.componentNames.SHAPE, graphics); /** * Object of The drawing shape * @type {fabric.Object} * @private */ this._shapeObj = null; /** * Type of the drawing shape * @type {string} * @private */ this._type = DEFAULT_TYPE; /** * Options to draw the shape * @type {Object} * @private */ this._options = extend({}, DEFAULT_OPTIONS); /** * Whether the shape object is selected or not * @type {boolean} * @private */ this._isSelected = false; /** * Pointer for drawing shape (x, y) * @type {Object} * @private */ this._startPoint = {}; /** * Using shortcut on drawing shape * @type {boolean} * @private */ this._withShiftKey = false; /** * Event handler list * @type {Object} * @private */ this._handlers = { mousedown: this._onFabricMouseDown.bind(this), mousemove: this._onFabricMouseMove.bind(this), mouseup: this._onFabricMouseUp.bind(this), keydown: this._onKeyDown.bind(this), keyup: this._onKeyUp.bind(this) }; } /** * Start to draw the shape on canvas * @ignore */ start() { const canvas = this.getCanvas(); this._isSelected = false; canvas.defaultCursor = 'crosshair'; canvas.selection = false; canvas.uniScaleTransform = true; canvas.on({ 'mouse:down': this._handlers.mousedown }); fabric.util.addListener(document, 'keydown', this._handlers.keydown); fabric.util.addListener(document, 'keyup', this._handlers.keyup); } /** * End to draw the shape on canvas * @ignore */ end() { const canvas = this.getCanvas(); this._isSelected = false; canvas.defaultCursor = 'default'; canvas.selection = true; canvas.uniScaleTransform = false; canvas.off({ 'mouse:down': this._handlers.mousedown }); fabric.util.removeListener(document, 'keydown', this._handlers.keydown); fabric.util.removeListener(document, 'keyup', this._handlers.keyup); } /** * Set states of the current drawing shape * @ignore * @param {string} type - Shape type (ex: 'rect', 'circle') * @param {Object} [options] - Shape options * @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent') * @param {string} [options.stoke] - Shape outline color * @param {number} [options.strokeWidth] - Shape outline width * @param {number} [options.width] - Width value (When type option is 'rect', this options can use) * @param {number} [options.height] - Height value (When type option is 'rect', this options can use) * @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use) * @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use) */ setStates(type, options) { this._type = type; if (options) { this._options = extend(this._options, options); } } /** * Add the shape * @ignore * @param {string} type - Shape type (ex: 'rect', 'circle') * @param {Object} options - Shape options * @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent') * @param {string} [options.stroke] - Shape outline color * @param {number} [options.strokeWidth] - Shape outline width * @param {number} [options.width] - Width value (When type option is 'rect', this options can use) * @param {number} [options.height] - Height value (When type option is 'rect', this options can use) * @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use) * @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use) * @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not * @returns {Promise} */ add(type, options) { return new Promise(resolve => { const canvas = this.getCanvas(); options = this._extendOptions(options); const shapeObj = this._createInstance(type, options); this._bindEventOnShape(shapeObj); canvas.add(shapeObj).setActiveObject(shapeObj); const objectProperties = this.graphics.createObjectProperties(shapeObj); resolve(objectProperties); }); } /** * Change the shape * @ignore * @param {fabric.Object} shapeObj - Selected shape object on canvas * @param {Object} options - Shape options * @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent') * @param {string} [options.stroke] - Shape outline color * @param {number} [options.strokeWidth] - Shape outline width * @param {number} [options.width] - Width value (When type option is 'rect', this options can use) * @param {number} [options.height] - Height value (When type option is 'rect', this options can use) * @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use) * @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use) * @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not * @returns {Promise} */ change(shapeObj, options) { return new Promise((resolve, reject) => { if (inArray(shapeObj.get('type'), shapeType) < 0) { reject(rejectMessages.unsupportedType); } shapeObj.set(options); this.getCanvas().renderAll(); resolve(); }); } /** * Create the instance of shape * @param {string} type - Shape type * @param {Object} options - Options to creat the shape * @returns {fabric.Object} Shape instance * @private */ _createInstance(type, options) { let instance; switch (type) { case 'rect': instance = new fabric.Rect(options); break; case 'circle': instance = new fabric.Ellipse(extend({ type: 'circle' }, options)); break; case 'triangle': instance = new fabric.Triangle(options); break; default: instance = {}; } return instance; } /** * Get the options to create the shape * @param {Object} options - Options to creat the shape * @returns {Object} Shape options * @private */ _extendOptions(options) { const selectionStyles = consts.fObjectOptions.SELECTION_STYLE; options = extend({}, DEFAULT_OPTIONS, this._options, selectionStyles, options); if (options.isRegular) { options.lockUniScaling = true; } return options; } /** * Bind fabric events on the creating shape object * @param {fabric.Object} shapeObj - Shape object * @private */ _bindEventOnShape(shapeObj) { const self = this; const canvas = this.getCanvas(); shapeObj.on({ added() { self._shapeObj = this; resizeHelper.setOrigins(self._shapeObj); }, selected() { self._isSelected = true; self._shapeObj = this; canvas.uniScaleTransform = true; canvas.defaultCursor = 'default'; resizeHelper.setOrigins(self._shapeObj); }, deselected() { self._isSelected = false; self._shapeObj = null; canvas.defaultCursor = 'crosshair'; canvas.uniScaleTransform = false; }, modified() { const currentObj = self._shapeObj; resizeHelper.adjustOriginToCenter(currentObj); resizeHelper.setOrigins(currentObj); }, scaling(fEvent) { const pointer = canvas.getPointer(fEvent.e); const currentObj = self._shapeObj; canvas.setCursor('crosshair'); resizeHelper.resize(currentObj, pointer, true); } }); } /** * MouseDown event handler on canvas * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object * @private */ _onFabricMouseDown(fEvent) { if (!fEvent.target) { this._isSelected = false; this._shapeObj = false; } if (!this._isSelected && !this._shapeObj) { const canvas = this.getCanvas(); this._startPoint = canvas.getPointer(fEvent.e); canvas.on({ 'mouse:move': this._handlers.mousemove, 'mouse:up': this._handlers.mouseup }); } } /** * MouseDown event handler on canvas * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object * @private */ _onFabricMouseMove(fEvent) { const canvas = this.getCanvas(); const pointer = canvas.getPointer(fEvent.e); const startPointX = this._startPoint.x; const startPointY = this._startPoint.y; const width = startPointX - pointer.x; const height = startPointY - pointer.y; const shape = this._shapeObj; if (!shape) { this.add(this._type, { left: startPointX, top: startPointY, width, height }).then(objectProps => { this.fire(eventNames.ADD_OBJECT, objectProps); }); } else { this._shapeObj.set({ isRegular: this._withShiftKey }); resizeHelper.resize(shape, pointer); canvas.renderAll(); } } /** * MouseUp event handler on canvas * @private */ _onFabricMouseUp() { const canvas = this.getCanvas(); const startPointX = this._startPoint.x; const startPointY = this._startPoint.y; const shape = this._shapeObj; if (!shape) { this.add(this._type, { left: startPointX, top: startPointY, width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT }).then(objectProps => { this.fire(eventNames.ADD_OBJECT, objectProps); }); } else if (shape) { resizeHelper.adjustOriginToCenter(shape); this.fire(eventNames.ADD_OBJECT_AFTER, this.graphics.createObjectProperties(shape)); } canvas.off({ 'mouse:move': this._handlers.mousemove, 'mouse:up': this._handlers.mouseup }); } /** * Keydown event handler on document * @param {KeyboardEvent} e - Event object * @private */ _onKeyDown(e) { if (e.keyCode === KEY_CODES.SHIFT) { this._withShiftKey = true; if (this._shapeObj) { this._shapeObj.isRegular = true; } } } /** * Keyup event handler on document * @param {KeyboardEvent} e - Event object * @private */ _onKeyUp(e) { if (e.keyCode === KEY_CODES.SHIFT) { this._withShiftKey = false; if (this._shapeObj) { this._shapeObj.isRegular = false; } } } } module.exports = Shape;