diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..e1a05b6 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,34 @@ +{ + "env": { + "browser": true, + "commonjs": true + }, + "extends": ["eslint:recommended"], + "rules": { + "no-console": 0, + "strict": [ + "error", + "safe" + ], + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "comma-dangle": [ + "error", + "only-multiline" + ] + } +} diff --git a/README.md b/README.md index d2eb838..bc71089 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ Photowall Image Editor ====================== -Image editor for the Photowall web project +Image editor for the Photowall web project + +# Linting +Linting can be run manually with +`npm run lint` + diff --git a/dist/image-editor.js b/dist/image-editor.js index 32450b6..10adb22 100644 --- a/dist/image-editor.js +++ b/dist/image-editor.js @@ -7,102 +7,102 @@ * @param {canvas} canvas */ function ThreeDHandler(canvas) { - var _overlay = new fabric.Group(); - var _image; + var _overlay = new fabric.Group(); + var _image; - function init() { - _overlay - .set({ - visible: false, - left: 0 - }) - .addWithUpdate(new fabric.Rect({ - // Width is made bigger as this works better with resizing the editor - width: canvas.width * 2, - height: canvas.height, - top: 0, - left: 0, - fill: canvas.backgroundColor, - })); + function init() { + _overlay + .set({ + visible: false, + left: 0 + }) + .addWithUpdate(new fabric.Rect({ + // Width is made bigger as this works better with resizing the editor + width: canvas.width * 2, + height: canvas.height, + top: 0, + left: 0, + fill: canvas.backgroundColor, + })); - canvas.add(_overlay); - } + canvas.add(_overlay); + } - init(); + init(); - /** + /** * Disables the 3d image by removing visibility * @return {ThreeDHandler} */ - this.disable = function () { - _overlay.setVisible(false).canvas.resize(); - return this; - }; + this.disable = function () { + _overlay.setVisible(false).canvas.resize(); + return this; + }; - /** + /** * Enables the 3d image by setting the width and visibility of the overlay and moving elements which * needs to be visible to the front. * @return {ThreeDHandler} */ - this.enable = function () { - _overlay - .set({ - width: canvas.width, - visible: true - }).bringToFront(); + this.enable = function () { + _overlay + .set({ + width: canvas.width, + visible: true + }).bringToFront(); - canvas.getButtonMenu().bringToFront(); - canvas.renderAll(); - return this; - }; + canvas.getButtonMenu().bringToFront(); + canvas.renderAll(); + return this; + }; - /** + /** * Checks if 3d mode is enabled/visible. * @returns {boolean} */ - this.isEnabled = function () { - return _overlay.visible; - }; + this.isEnabled = function () { + return _overlay.visible; + }; - /** + /** * Refreshes the image. This is mostly done upon resize of the window */ - this.refreshImage = function() { - _overlay.set({ - width: canvas.width, - }); + this.refreshImage = function() { + _overlay.set({ + width: canvas.width, + }); - this.applyImage(); - }; + this.applyImage(); + }; - /** + /** * (Re)adds the new/existing image with new configuration to the overlay. * @param {img} */ - this.applyImage = function(img) { - img = img || _image; + this.applyImage = function(img) { + img = img || _image; - _overlay - .remove(_image) - .add(_image = canvas.getResizedImage(img)); - }; + _overlay + .remove(_image) + .add(_image = canvas.getResizedImage(img)); + }; - /** + /** * Sets the image and enables 3d mode. * @param {img} * @return {ThreeDHandler} */ - this.setImage = function (img) { - img.set({ - // Image should be about 20px lower than the center (because of the buttons) - top: 20, - originX: 'center', - originY: 'center', - }); + this.setImage = function (img) { + img.set({ + // Image should be about 20px lower than the center (because of the buttons) + top: 20, + originX: 'center', + originY: 'center', + }); - this.applyImage(img); - return this.enable(); - }; + this.applyImage(img); + return this.enable(); + }; } @@ -117,94 +117,94 @@ module.exports = ThreeDHandler; * @param {canvas} canvas */ function ApertureHandler(canvas) { - var _items = {x: [], y: []}; + var _items = {x: [], y: []}; - function init() { - var bounds = canvas; - var xRect = new fabric.Rect({ - width: bounds.width, - height: bounds.height / 2, - fill: canvas.backgroundColor, - opacity: 0.7, - }); + function init() { + var bounds = canvas; + var xRect = new fabric.Rect({ + width: bounds.width, + height: bounds.height / 2, + fill: canvas.backgroundColor, + opacity: 0.7, + }); - var yRect = xRect.clone().set({ - width: bounds.width / 2, - height: bounds.height - }); + var yRect = xRect.clone().set({ + width: bounds.width / 2, + height: bounds.height + }); - _items.x = [].concat([xRect, xRect.clone()]); - _items.y= [].concat([yRect, yRect.clone()]); + _items.x = [].concat([xRect, xRect.clone()]); + _items.y= [].concat([yRect, yRect.clone()]); - [].concat(_items.x, _items.y).forEach(function (o) { - canvas.add(o); - }); - canvas.renderAll(); - } - init(); + [].concat(_items.x, _items.y).forEach(function (o) { + canvas.add(o); + }); + canvas.renderAll(); + } + init(); - /** + /** * Applies configuration to the apertures apertures on the viewport * @param {string} axis * @param {viewport} viewport */ - this.apply = function (axis, viewport) { - this.getApertures(axis).forEach(function (o) { - o.visible = false; - }); + this.apply = function (axis, viewport) { + this.getApertures(axis).forEach(function (o) { + o.visible = false; + }); - var active = this.getApertures(axis === 'x' ? 'y' : 'x'); + var active = this.getApertures(axis === 'x' ? 'y' : 'x'); - active.forEach(function (o) { - o.visible = true; - }); + active.forEach(function (o) { + o.visible = true; + }); - active[0].width= active[1].width = canvas.width; - active[0].height = active[1].height = canvas.height; + active[0].width= active[1].width = canvas.width; + active[0].height = active[1].height = canvas.height; - if (axis === 'y') { - active[0].top = viewport.top - active[0].height + 0.5; - active[1].top = viewport.top + viewport.height - 0.5; - } else { - active[0].left = viewport.left - active[0].width + 0.5; - active[1].left = viewport.left + viewport.width - 0.5; - } + if (axis === 'y') { + active[0].top = viewport.top - active[0].height + 0.5; + active[1].top = viewport.top + viewport.height - 0.5; + } else { + active[0].left = viewport.left - active[0].width + 0.5; + active[1].left = viewport.left + viewport.width - 0.5; + } - this.getApertures().forEach(function (o) { - o.setCoords(); - }); + this.getApertures().forEach(function (o) { + o.setCoords(); + }); - canvas.renderAll(); - }; + canvas.renderAll(); + }; - /** + /** * Gets the apertures on specified axis. If no axis is provided, both x and y are returned. * @param {string} axis * @returns {Array} */ - this.getApertures = function (axis) { - return axis ? _items[axis] : [].concat(_items.x, _items.y); - }; + this.getApertures = function (axis) { + return axis ? _items[axis] : [].concat(_items.x, _items.y); + }; - /** + /** * Sets transparency of the apertures depending on the crop status * @param {boolean} apply * @returns {ApertureHandler} */ - this.setTransparent = function (apply) { - this.getApertures().forEach(function (o) { - o.opacity = apply ? 0.7 : 1; - }); + this.setTransparent = function (apply) { + this.getApertures().forEach(function (o) { + o.opacity = apply ? 0.7 : 1; + }); - canvas.renderAll(); - return this; - }; + canvas.renderAll(); + return this; + }; - this.disable = function () { - this.getApertures().forEach(function (o) { - o.visible = false; - }); - }; + this.disable = function () { + this.getApertures().forEach(function (o) { + o.visible = false; + }); + }; } module.exports = ApertureHandler; @@ -221,143 +221,143 @@ var TextButton = require('./TextButton'); * @param {Object=} settings */ function ButtonMenu(canvas, settings) { - var _textButtons = []; - var _width = 0; + var _textButtons = []; + var _width = 0; - /** + /** * Calculates the width of all contained items * @return {Number} */ - function setWidth() { - var startWidth = 0; - _textButtons.forEach(function(textButton) { - startWidth += textButton.width; - }); - _width = startWidth += settings.margin * (_textButtons.length - 1); - } + function setWidth() { + var startWidth = 0; + _textButtons.forEach(function(textButton) { + startWidth += textButton.width; + }); + _width = startWidth += settings.margin * (_textButtons.length - 1); + } - /** + /** * Adds items to the button-menu. * @param {String} text * @param {Function} callback * @return {ButtonMenu} */ - this.addItem = function(id, text, callback, isActive) { - _textButtons.push( - new TextButton(id, text, settings, isActive) - .onClick(callback) - .set({__group: this}) - ); + this.addItem = function(id, text, callback, isActive) { + _textButtons.push( + new TextButton(id, text, settings, isActive) + .onClick(callback) + .set({__group: this}) + ); - return this; - }; + return this; + }; - /** + /** * Brings the buttons to the front inside the canvas * @return {ButtonMenu} */ - this.bringToFront = function() { - _textButtons.forEach(function(textButton) { - textButton.bringToFront(); - }); - return this; - }; + this.bringToFront = function() { + _textButtons.forEach(function(textButton) { + textButton.bringToFront(); + }); + return this; + }; - /** + /** * Gets all buttons inside the menu. * @return {Array} */ - this.getItems = function() { - return _textButtons; - }; + this.getItems = function() { + return _textButtons; + }; - /** + /** * Gets the full width of the buttonMenu. * @return {Number} */ - this.getWidth = function() { - return _width; - }; + this.getWidth = function() { + return _width; + }; - /** + /** * Sets the button with id=buttonId to active/not active mode */ - this.setButtonActive = function(buttonId, isActive) { - _textButtons.forEach(function (button) { - if (button.getId() === buttonId) { - button.setActive(isActive); - } - }); - }; + this.setButtonActive = function(buttonId, isActive) { + _textButtons.forEach(function (button) { + if (button.getId() === buttonId) { + button.setActive(isActive); + } + }); + }; - /** + /** * Sets the button with id=buttonId to disabled/enabled mode */ - this.setButtonDisabled = function(buttonId, isDisabled) { - _textButtons.forEach(function (button) { - if (button.getId() === buttonId) { - button.setDisabled(isDisabled); - } - }); - }; + this.setButtonDisabled = function(buttonId, isDisabled) { + _textButtons.forEach(function (button) { + if (button.getId() === buttonId) { + button.setDisabled(isDisabled); + } + }); + }; - /** + /** * Hides the buttons */ - this.hide = function() { - _textButtons.forEach(function(textButton) { - textButton.set({ - opacity: 0, - disabled: true - }); - }); - }; + this.hide = function() { + _textButtons.forEach(function(textButton) { + textButton.set({ + opacity: 0, + disabled: true + }); + }); + }; - /** + /** * Shows all the buttons */ - this.show = function() { - _textButtons.forEach(function(textButton) { - textButton.set({ - opacity: 1, - disabled: false - }); - }); - }; + this.show = function() { + _textButtons.forEach(function(textButton) { + textButton.set({ + opacity: 1, + disabled: false + }); + }); + }; - /** + /** * Recalculate boundaries and add all items to canvas if required * @return {ButtonMenu} */ - this.render = function() { - setWidth(); + this.render = function() { + setWidth(); - var start = canvas.width / 2 - this.getWidth() / 2; - var currPos = Math.round(start); + var start = canvas.width / 2 - this.getWidth() / 2; + var currPos = Math.round(start); - _textButtons.forEach(function(textButton) { - textButton - .set({ - top: 10, - left: currPos - }) - .setCoords(); + _textButtons.forEach(function(textButton) { + textButton + .set({ + top: 10, + left: currPos + }) + .setCoords(); - if (!textButton.canvas) { - textButton.addTo(canvas); - } - currPos += Math.round(textButton.width + settings.margin); + if (!textButton.canvas) { + textButton.addTo(canvas); + } + currPos += Math.round(textButton.width + settings.margin); - // Disable moving of text-buttons - textButton.lockMovementX = textButton.lockMovementY = true; - }); + // Disable moving of text-buttons + textButton.lockMovementX = textButton.lockMovementY = true; + }); - canvas.renderAll(); + canvas.renderAll(); - this.show(); + this.show(); - return this; - }; + return this; + }; } module.exports = ButtonMenu; @@ -384,221 +384,221 @@ var $document = $(document); * Fe. getDragbars method can be called from most places as the Canvas class is available in most places. */ var Canvas = fabric.util.createClass(fabric.Canvas, { - initialize: function (id, dimensions) { - this.callSuper('initialize', id, { - enableRetinaScaling: true, - renderOnAddRemove: false, - // Allow touch scrolling on touch-devices larger than mobile screen sizes. - allowTouchScrolling: !util.isMobile(), - stateful: false, - backgroundColor: '#ededed', - preserveObjectStacking: true, - selection: false, - width: dimensions.width, - height: dimensions.height - }); - }, + initialize: function (id, dimensions) { + this.callSuper('initialize', id, { + enableRetinaScaling: true, + renderOnAddRemove: false, + // Allow touch scrolling on touch-devices larger than mobile screen sizes. + allowTouchScrolling: !util.isMobile(), + stateful: false, + backgroundColor: '#ededed', + preserveObjectStacking: true, + selection: false, + width: dimensions.width, + height: dimensions.height + }); + }, - resize: function (args) { - args = args || { height: this.height, width: this.width}; - if (!args.width || !args.height) { - return; - } + resize: function (args) { + args = args || { height: this.height, width: this.width}; + if (!args.width || !args.height) { + return; + } - this.setHeight(args.height); - this.setWidth(args.width); - this.getButtonMenu().render(); - if (this.get3dHandler().isEnabled()) { - this.get3dHandler().refreshImage(); - } else { - this.refreshImage(this.getResizedImage(this.getImage())); - this.getViewport().reset(); - } - this.sendToBack(this.getImage()); - this.getImage().center(); - this.getDragbars().resetPosition(); - this.renderAll(); - }, + this.setHeight(args.height); + this.setWidth(args.width); + this.getButtonMenu().render(); + if (this.get3dHandler().isEnabled()) { + this.get3dHandler().refreshImage(); + } else { + this.refreshImage(this.getResizedImage(this.getImage())); + this.getViewport().reset(); + } + this.sendToBack(this.getImage()); + this.getImage().center(); + this.getDragbars().resetPosition(); + this.renderAll(); + }, - disableScroll: function() { - this.set({ - allowTouchScrolling: false - }); - return this; - }, + disableScroll: function() { + this.set({ + allowTouchScrolling: false + }); + return this; + }, - enableScroll: function() { - this.set({ - allowTouchScrolling: true - }); - return this; - }, + enableScroll: function() { + this.set({ + allowTouchScrolling: true + }); + return this; + }, - get3dHandler: function () { - return this.__3dHandler || + get3dHandler: function () { + return this.__3dHandler || (this.__3dHandler = new ThreeDHandler(this)); - }, + }, - /** + /** * @return {String} */ - get3dUrl: function () { - var imageData = this.getImageData().getData(); - var params = [ - 'h=400', - 'canvas[edge]=' + imageData.edge, - 'crop[w]=' + imageData.width, - 'crop[h]=' + imageData.height, - 'crop[x]=' + imageData.x, - 'crop[y]=' + imageData.y, - ]; + get3dUrl: function () { + var imageData = this.getImageData().getData(); + var params = [ + 'h=400', + 'canvas[edge]=' + imageData.edge, + 'crop[w]=' + imageData.width, + 'crop[h]=' + imageData.height, + 'crop[x]=' + imageData.x, + 'crop[y]=' + imageData.y, + ]; - if (imageData.mirrored) { - params.push('mirror=1'); - } + if (imageData.mirrored) { + params.push('mirror=1'); + } - return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&'); - }, + return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&'); + }, - getApertures: function () { - return this.__aperturehandler || + getApertures: function () { + return this.__aperturehandler || (this.__aperturehandler = new ApertureHandler(this)); - }, + }, - /** + /** * * @returns {DragbarHandler} */ - getDragbars: function () { - return this.__dragbars || + getDragbars: function () { + return this.__dragbars || (this.__dragbars = new DragbarHandler(this)); - }, + }, - /** + /** * @return {fabric.Image} */ - getImage: function () { - return this.__image; - }, + getImage: function () { + return this.__image; + }, - /** + /** * @return {MirrorHandler} */ - getMirror: function () { - return this.__mirror || + getMirror: function () { + return this.__mirror || (this.__mirror = new MirrorHandler(this.getImage())); - }, + }, - /** + /** * @return {MirrorHandler} */ - getImageData: function () { - return this.__imageData || + getImageData: function () { + return this.__imageData || (this.__imageData = new ImageDataHandler(this.getImage())); - }, + }, - /** + /** * @return {Viewport} */ - getViewport: function () { - return this.__viewport || + getViewport: function () { + return this.__viewport || (this.__viewport = new Viewport(this)); - }, + }, - /** + /** * Gets the menu for this instance * @returns {ButtonMenu} */ - getButtonMenu: function (settings) { - if (!this.__buttonMenu) { - var defaults = config.buttonMenu[this.__type]; - this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings)); - } - return this.__buttonMenu; - }, + getButtonMenu: function (settings) { + if (!this.__buttonMenu) { + var defaults = config.buttonMenu[this.__type]; + this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings)); + } + return this.__buttonMenu; + }, - /** + /** * Reloads the 3D view, if it is present * @return {Canvas} */ - refresh3dView: function () { - if (this.get3dHandler().isEnabled()) { - this.toggle3D(true); - } - return this; - }, + refresh3dView: function () { + if (this.get3dHandler().isEnabled()) { + this.toggle3D(true); + } + return this; + }, - /** + /** * @return {Canvas} */ - removeImage: function () { - if (!this.__image) { - return this; - } - this.__imageData = null; - return this.remove(this.__image); - }, + removeImage: function () { + if (!this.__image) { + return this; + } + this.__imageData = null; + return this.remove(this.__image); + }, - refreshImage: function(img) { - this.__image = img; - return this; - }, + refreshImage: function(img) { + this.__image = img; + return this; + }, - /** + /** * @param {fabric.Image} img * @return {Canvas} */ - setImage: function (img) { - this.removeImage(); - this.__image = img; - this.__image.__dragged = false; - this.__image.__cropped = false; - this.__image.addTo(this).center().on('mousedown', function () { - img.canvas.getApertures().setTransparent(true); - }).setCoords(); - this.getViewport().reset(); - return this; - }, + setImage: function (img) { + this.removeImage(); + this.__image = img; + this.__image.__dragged = false; + this.__image.__cropped = false; + this.__image.addTo(this).center().on('mousedown', function () { + img.canvas.getApertures().setTransparent(true); + }).setCoords(); + this.getViewport().reset(); + return this; + }, - getResizedImage: function(img) { - // Calculate maxHeight and maxWidth of the 3d image - // and scale the image accoring to those values - var maxHeight = this.getHeight() - 100; - var maxWidth = this.getWidth() - 100; + getResizedImage: function(img) { + // Calculate maxHeight and maxWidth of the 3d image + // and scale the image accoring to those values + var maxHeight = this.getHeight() - 100; + var maxWidth = this.getWidth() - 100; - img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height); - img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX); + img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height); + img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX); - return img; - }, + return img; + }, - toggle3D: function (showAs3d) { + toggle3D: function (showAs3d) { - this.getButtonMenu().setButtonActive('toggle3d', showAs3d); + this.getButtonMenu().setButtonActive('toggle3d', showAs3d); - if (!showAs3d) { - return this.get3dHandler().disable(); + if (!showAs3d) { + return this.get3dHandler().disable(); + } + + $document.trigger('PIE:image-start-load'); + + $.ajax({ + url: this.get3dUrl(), + crossDomain: true, + type: 'HEAD', + cache: true, + }).done(function() { + fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) { + if (!img._element) { + $document.trigger('PIE:image-error-load'); + return; } - $document.trigger('PIE:image-start-load'); - - $.ajax({ - url: this.get3dUrl(), - crossDomain: true, - type: "HEAD", - cache: true, - }).done(function() { - fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) { - if (!img._element) { - $document.trigger('PIE:image-error-load'); - return; - } - - this.get3dHandler().setImage(img); - $document.trigger('PIE:image-end-load'); - }.bind(this)); - }.bind(this)); - }, + this.get3dHandler().setImage(img); + $document.trigger('PIE:image-end-load'); + }.bind(this)); + }.bind(this)); + }, }); module.exports = Canvas; @@ -611,145 +611,145 @@ var config = require('./config'); var util = require('./util'); var DragHandle = function (handler) { - var _currentAxis; - var _dragHandle; - var _clickHandle = false; - var _movedHandle; + var _currentAxis; + var _dragHandle; + var _clickHandle = false; + var _movedHandle; - // Event declarations - var events = { - mouseDown: function () { - if(handler.canvas.__type !== 'wallpaper') { - _dragHandle = true; - } + // Event declarations + var events = { + mouseDown: function () { + if(handler.canvas.__type !== 'wallpaper') { + _dragHandle = true; + } - _clickHandle = true; - _currentAxis = this.axis; - handler.canvas.getImage().trigger('mousedown'); - }, - mouseUp: function () { - if (!_dragHandle && !_clickHandle) { - return; - } + _clickHandle = true; + _currentAxis = this.axis; + handler.canvas.getImage().trigger('mousedown'); + }, + mouseUp: function () { + if (!_dragHandle && !_clickHandle) { + return; + } - if (_clickHandle) { - $(document).trigger('PIE:dragbar-click', { axis: _currentAxis }); - _clickHandle = false; - } + if (_clickHandle) { + $(document).trigger('PIE:dragbar-click', { axis: _currentAxis }); + _clickHandle = false; + } - _dragHandle = false; - _movedHandle = false; - _currentAxis = null; - util.MouseMetrics.deletePreviousMouseData(); - handler.canvas.getImage().trigger('mouseup'); - }, - mouseMove: function (e) { - if (!_dragHandle) { - return; - } + _dragHandle = false; + _movedHandle = false; + _currentAxis = null; + util.MouseMetrics.deletePreviousMouseData(); + handler.canvas.getImage().trigger('mouseup'); + }, + mouseMove: function (e) { + if (!_dragHandle) { + return; + } - //Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case - var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX); - var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY); + //Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case + var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX); + var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY); - // We're using a polyfill to calculate moude/touch movement if the browser/device - // does not support movementX/movementY. - var previousMouseData = util.MouseMetrics.previousMouseData; - var movement = { - x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0), - y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0) - }; - util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY}); - _movedHandle = true; + // We're using a polyfill to calculate moude/touch movement if the browser/device + // does not support movementX/movementY. + var previousMouseData = util.MouseMetrics.previousMouseData; + var movement = { + x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0), + y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0) + }; + util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY}); + _movedHandle = true; - if (_currentAxis === 'x') { - handler.canvas.getImage().left -= movement.x; - } else { - handler.canvas.getImage().top -= movement.y; - } - // Trigger moving for image, to stay within bounds - handler.canvas.getImage().setCoords().trigger('moving'); - handler.canvas.renderAll(); - } - }; + if (_currentAxis === 'x') { + handler.canvas.getImage().left -= movement.x; + } else { + handler.canvas.getImage().top -= movement.y; + } + // Trigger moving for image, to stay within bounds + handler.canvas.getImage().setCoords().trigger('moving'); + handler.canvas.renderAll(); + } + }; - function getRect(text, width) { - var txt = new fabric.Text(text, config.dragHandle.text); - var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, { - width: width, - })); + function getRect(text, width) { + var txt = new fabric.Text(text, config.dragHandle.text); + var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, { + width: width, + })); - return new fabric.Group([rect, txt]).set({ - evented: false, - }); + return new fabric.Group([rect, txt]).set({ + evented: false, + }); + } + + this.getCanvas = function () { + return handler.canvas; + }; + + this.getHandles = function () { + if (!this.__handles) { + return []; } - this.getCanvas = function () { - return handler.canvas; + return [].concat(this.__handles.x, this.__handles.y); + }; + + this.setHandlePosition = function() { + this.__handles.y.set({left: handler.getTracks().y.left}).setCoords(); + this.__handles.x.set({top: handler.getTracks().x.top}).setCoords(); + return this; + }; + + this.init = function () { + var canvas = this.getCanvas(); + var viewport = canvas.getViewport(); + var viewportData = viewport.getData(); + var frameHandler = viewport.getFrameHandler(); + var tracks = handler.getTracks(); + + if (this.__handles) { + this.getCanvas().remove(this.__handles.x); + this.getCanvas().remove(this.__handles.y); + } + + var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels. + var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm. + var frameType = frameHandler.getFrameType(); + + var handleWidth = viewportData.width; + var handleHeight = viewportData.height; + var widthToDisplay = viewportData.dim.width; + var heightToDisplay = viewportData.dim.height; + var unit = viewportData.dim.units; + + if (frameType == 'image') { + var doubleRealFrameWidth = realFrameWidth * 2; + handleWidth -= frameWidth * 2; + handleHeight -= frameWidth * 2; + widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; + heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; + } + + this.__handles = { + x: getRect(widthToDisplay + ' ' + unit, handleWidth), + y: getRect(heightToDisplay + ' ' + unit, handleHeight) }; - this.getHandles = function () { - if (!this.__handles) { - return []; - } + this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords(); + this.__handles.y.addTo(this.getCanvas()) + .setAngle(-90) + .centerV().set({ left: tracks.y.left }) + .setCoords(); - return [].concat(this.__handles.x, this.__handles.y); - }; + this.getCanvas() + .on('mouse:move', events.mouseMove) + .on('mouse:up', events.mouseUp); - this.setHandlePosition = function() { - this.__handles.y.set({left: handler.getTracks().y.left}).setCoords(); - this.__handles.x.set({top: handler.getTracks().x.top}).setCoords(); - return this; - }; - - this.init = function () { - var canvas = this.getCanvas(); - var viewport = canvas.getViewport(); - var viewportData = viewport.getData(); - var frameHandler = viewport.getFrameHandler(); - var tracks = handler.getTracks(); - - if (this.__handles) { - this.getCanvas().remove(this.__handles.x); - this.getCanvas().remove(this.__handles.y); - } - - var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels. - var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm. - var frameType = frameHandler.getFrameType(); - - var handleWidth = viewportData.width; - var handleHeight = viewportData.height; - var widthToDisplay = viewportData.dim.width; - var heightToDisplay = viewportData.dim.height; - var unit = viewportData.dim.units; - - if (frameType == 'image') { - var doubleRealFrameWidth = realFrameWidth * 2; - handleWidth -= frameWidth * 2; - handleHeight -= frameWidth * 2; - widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; - heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; - } - - this.__handles = { - x: getRect(widthToDisplay + ' ' + unit, handleWidth), - y: getRect(heightToDisplay + ' ' + unit, handleHeight) - }; - - this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords(); - this.__handles.y.addTo(this.getCanvas()) - .setAngle(-90) - .centerV().set({ left: tracks.y.left }) - .setCoords(); - - this.getCanvas() - .on('mouse:move', events.mouseMove) - .on('mouse:up', events.mouseUp); - - tracks.x.on('mousedown', events.mouseDown.bind(tracks.x)); - tracks.y.on('mousedown', events.mouseDown.bind(tracks.y)); - }; + tracks.x.on('mousedown', events.mouseDown.bind(tracks.x)); + tracks.y.on('mousedown', events.mouseDown.bind(tracks.y)); + }; }; module.exports = DragHandle; @@ -762,127 +762,127 @@ var DragHandle = require('./DragHandle'); var config = require('./config'); function DragbarHandler(canvas) { - var _dragbars = { - x: null, - y: null - }; + var _dragbars = { + x: null, + y: null + }; - /** + /** * @return {DragbarHandler} */ - this.apply = function () { - if (!canvas.__hasDragbars) { - this.init(); - canvas.__hasDragbars = true; - } - this.sync(); + this.apply = function () { + if (!canvas.__hasDragbars) { + this.init(); + canvas.__hasDragbars = true; + } + this.sync(); - if (!this.__handles) { - this.__handles = new DragHandle(this); - } + if (!this.__handles) { + this.__handles = new DragHandle(this); + } - this.__handles.init(); + this.__handles.init(); - this.bringToFront(); + this.bringToFront(); - canvas.renderAll(); - return this; - }; + canvas.renderAll(); + return this; + }; - this.canvas = canvas; + this.canvas = canvas; - this.bringToFront = function() { - [].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) { - dragbar.bringToFront(); - }); + this.bringToFront = function() { + [].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) { + dragbar.bringToFront(); + }); - this.__handles.getHandles().forEach(function (handle) { - handle.bringToFront(); - }); - }; - /** + this.__handles.getHandles().forEach(function (handle) { + handle.bringToFront(); + }); + }; + /** * Removes dragbars from canvas */ - this.clear = function () { - canvas - .remove(_dragbars.x) - .remove(_dragbars.y) - .renderAll(); - return this; - }; + this.clear = function () { + canvas + .remove(_dragbars.x) + .remove(_dragbars.y) + .renderAll(); + return this; + }; - this.getTracks = function () { - return _dragbars; - }; + this.getTracks = function () { + return _dragbars; + }; - this.resetPosition = function() { - if (!_dragbars.y || !_dragbars.x) { - return this; - } + this.resetPosition = function() { + if (!_dragbars.y || !_dragbars.x) { + return this; + } - _dragbars.y.set({ - left: canvas.width - 30, - height: canvas.getImage().height * canvas.getImage().scaleY, - }).setCoords(); + _dragbars.y.set({ + left: canvas.width - 30, + height: canvas.getImage().height * canvas.getImage().scaleY, + }).setCoords(); - _dragbars.x.set({ - top: canvas.height - 30, - width: canvas.getImage().width * canvas.getImage().scaleY, - }).setCoords(); + _dragbars.x.set({ + top: canvas.height - 30, + width: canvas.getImage().width * canvas.getImage().scaleY, + }).setCoords(); - this.__handles.setHandlePosition(); + this.__handles.setHandlePosition(); - return this; - }; + return this; + }; - /** + /** * @return {DragbarHandler} */ - this.init = function () { - this.clear(); - var typeIsWallpaper = canvas.__type === 'wallpaper'; + this.init = function () { + this.clear(); + var typeIsWallpaper = canvas.__type === 'wallpaper'; - _dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { - axis: 'x', - width: canvas.getImage().width * canvas.getImage().scaleY, - height: config.dragBar.size, - lockMovementY: true, - // Movement should also be disabled when the user is on wallpaper (repeating paterns) - lockMovementX: typeIsWallpaper, - selectable: true, - hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', - moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', - })) - .addTo(canvas) - .centerH().set({ top: canvas.height - 30 }).setCoords(); + _dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { + axis: 'x', + width: canvas.getImage().width * canvas.getImage().scaleY, + height: config.dragBar.size, + lockMovementY: true, + // Movement should also be disabled when the user is on wallpaper (repeating paterns) + lockMovementX: typeIsWallpaper, + selectable: true, + hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', + moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', + })) + .addTo(canvas) + .centerH().set({ top: canvas.height - 30 }).setCoords(); - _dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { - axis: 'y', - width: config.dragBar.size, - height: canvas.getImage().height * canvas.getImage().scaleY, - lockMovementX: true, - // Movement should also be disabled when the user is on wallpaper (repeating paterns) - lockMovementY: typeIsWallpaper, - selectable: true, - hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', - moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', - })) - .addTo(canvas) - .set({ left: canvas.width - 30 }).setCoords(); + _dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { + axis: 'y', + width: config.dragBar.size, + height: canvas.getImage().height * canvas.getImage().scaleY, + lockMovementX: true, + // Movement should also be disabled when the user is on wallpaper (repeating paterns) + lockMovementY: typeIsWallpaper, + selectable: true, + hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', + moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', + })) + .addTo(canvas) + .set({ left: canvas.width - 30 }).setCoords(); - canvas.getImage().on('moving', this.sync); + canvas.getImage().on('moving', this.sync); - return this; - }; + return this; + }; - /** + /** * @return {DragbarHandler} */ - this.sync = function () { - _dragbars.x.set({left: canvas.getImage().left}).setCoords(); - _dragbars.y.set({top: canvas.getImage().top}).setCoords(); - return this; - }; + this.sync = function () { + _dragbars.x.set({left: canvas.getImage().left}).setCoords(); + _dragbars.y.set({top: canvas.getImage().top}).setCoords(); + return this; + }; } module.exports = DragbarHandler; @@ -897,69 +897,69 @@ var util = require('./util'); * @param {fabric.Rect} boundingRect */ function Draggable(img, boundingRect) { - var _bounds = boundingRect; - var _img = img; + var _bounds = boundingRect; + var _img = img; - /** + /** * Triggers when object is moved */ - function onMove() { - /*jshint validthis: true */ - if (!this.__dragging) { - //Trigger start-drag on first 'moving' trigger. - $(document).trigger('PIE:start-drag'); - this.__dragging = true; - } - this.canvas.disableScroll(); - - util.setPositionInside(this, _bounds); + function onMove() { + /*jshint validthis: true */ + if (!this.__dragging) { + //Trigger start-drag on first 'moving' trigger. + $(document).trigger('PIE:start-drag'); + this.__dragging = true; } + this.canvas.disableScroll(); - this.onMouseUp = function () { - if (this.__dragging) { - this.__dragged = true; - this.__dragging = false; - this.canvas.getImageData().setCropData(); - if (!util.isMobile()) { - this.canvas.enableScroll(); - } - // Trigger event to tell the image has been dragged. - $(document).trigger('PIE:dragged'); - } - if (this.__dragged) { - // Always set aperture transparency to false even if image hasn't been dragged this click. - this.canvas.getApertures().setTransparent(false); - } - this.canvas.renderAll(); - }; + util.setPositionInside(this, _bounds); + } - // Attach onMove event to image - _img.on('moving', onMove); + this.onMouseUp = function () { + if (this.__dragging) { + this.__dragged = true; + this.__dragging = false; + this.canvas.getImageData().setCropData(); + if (!util.isMobile()) { + this.canvas.enableScroll(); + } + // Trigger event to tell the image has been dragged. + $(document).trigger('PIE:dragged'); + } + if (this.__dragged) { + // Always set aperture transparency to false even if image hasn't been dragged this click. + this.canvas.getApertures().setTransparent(false); + } + this.canvas.renderAll(); + }; - // Attach mouse up event to canvas, can't do mouse up events on canvas objects. - _img.canvas.on('mouse:up', this.onMouseUp.bind(_img)); + // Attach onMove event to image + _img.on('moving', onMove); - /** + // Attach mouse up event to canvas, can't do mouse up events on canvas objects. + _img.canvas.on('mouse:up', this.onMouseUp.bind(_img)); + + /** * @param {fabric.Rect} localBoundingRect * @return {Draggable} */ - this.enable = function (localBoundingRect) { - if (localBoundingRect) { - _bounds = localBoundingRect; - } + this.enable = function (localBoundingRect) { + if (localBoundingRect) { + _bounds = localBoundingRect; + } - // @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect - if (_img.canvas.getViewport().getData().axis === 'x') { - _bounds.top.min = _bounds.top.max = _img.top; - } else { - _bounds.left.min = _bounds.left.max = _img.left; - } + // @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect + if (_img.canvas.getViewport().getData().axis === 'x') { + _bounds.top.min = _bounds.top.max = _img.top; + } else { + _bounds.left.min = _bounds.left.max = _img.left; + } - _img.lockMovementX = _img.lockMovementY = false; - _img.selectable = true; - _img.hoverCursor = 'move'; - return this; - }; + _img.lockMovementX = _img.lockMovementY = false; + _img.selectable = true; + _img.hoverCursor = 'move'; + return this; + }; } module.exports = Draggable; @@ -971,146 +971,146 @@ module.exports = Draggable; var config = require('./config'); function FrameHandler(viewport) { - var _frames; - var _frameType = viewport.canvas.__canvasFrameType; - var _frameSize; + var _frames; + var _frameType = viewport.canvas.__canvasFrameType; + var _frameSize; - function getFramesAsArray() { - return [ - _frames.top, _frames.right, _frames.bottom, _frames.left - ]; - } + function getFramesAsArray() { + return [ + _frames.top, _frames.right, _frames.bottom, _frames.left + ]; + } - /** + /** * Sets the 4 rectangles which are used when current canvas should be framed */ - function initFrames() { - var frame = new fabric.Rect(config.frames.default); + function initFrames() { + var frame = new fabric.Rect(config.frames.default); - _frames = { - top: frame.clone(), - right: frame.clone(), - bottom: frame.clone(), - left: frame.clone() - }; + _frames = { + top: frame.clone(), + right: frame.clone(), + bottom: frame.clone(), + left: frame.clone() + }; - getFramesAsArray().forEach(function (o) { - viewport.canvas.add(o); - }); - } + getFramesAsArray().forEach(function (o) { + viewport.canvas.add(o); + }); + } - function init() { - initFrames(); - } + function init() { + initFrames(); + } - init(); + init(); - /** + /** * @return {String} */ - this.getFrameType = function () { - return _frameType; - }; + this.getFrameType = function () { + return _frameType; + }; - this.getFrameSize = function() { - return _frameSize; - }; + this.getFrameSize = function() { + return _frameSize; + }; - this.setVisible = function (isVisible) { - isVisible = typeof isVisible === 'undefined' ? true : !!isVisible; + this.setVisible = function (isVisible) { + isVisible = typeof isVisible === 'undefined' ? true : !!isVisible; - getFramesAsArray().forEach(function (frame) { - frame.set({ visible: isVisible }); - }); + getFramesAsArray().forEach(function (frame) { + frame.set({ visible: isVisible }); + }); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * Sets passed frametype to passed viewwport * @param {string} frameType none|image|black|white * @return {FrameHandler} */ - this.setFrames = function (frameType) { - var bounds = viewport.getBounds(); + this.setFrames = function (frameType) { + var bounds = viewport.getBounds(); - frameType = frameType || _frameType || 'image'; - _frameType = frameType; + frameType = frameType || _frameType || 'image'; + _frameType = frameType; - if (!frameType) { - return; - } + if (!frameType) { + return; + } - if (frameType === 'none') { - viewport.canvas.getDragbars().apply(); - return this.setVisible(false); - } + if (frameType === 'none') { + viewport.canvas.getDragbars().apply(); + return this.setVisible(false); + } - this.setVisible(true); + this.setVisible(true); - getFramesAsArray().forEach(function (o) { - o.set(config.frames[frameType]); - }); + getFramesAsArray().forEach(function (o) { + o.set(config.frames[frameType]); + }); - var vpData = viewport.getData(); - var realFrameSize = 29; // Actual real life frame size width in mm. + var vpData = viewport.getData(); + var realFrameSize = 29; // Actual real life frame size width in mm. - _frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX; + _frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX; - _frames.top.height = + _frames.top.height = _frames.bottom.height = _frames.right.width = _frames.left.width = _frameSize; - _frames.top.width = _frames.bottom.width = vpData.width; - _frames.right.height = _frames.left.height = vpData.height; + _frames.top.width = _frames.bottom.width = vpData.width; + _frames.right.height = _frames.left.height = vpData.height; - if (frameType === 'image') { - _frames.top.width -= _frameSize * 2; - _frames.bottom.width = _frames.top.width; - _frames.right.height -= _frameSize * 2; - _frames.left.height = _frames.right.height; + if (frameType === 'image') { + _frames.top.width -= _frameSize * 2; + _frames.bottom.width = _frames.top.width; + _frames.right.height -= _frameSize * 2; + _frames.left.height = _frames.right.height; - _frames.top.set({ - top: bounds.top, - }).centerH().setCoords(); + _frames.top.set({ + top: bounds.top, + }).centerH().setCoords(); - _frames.bottom.set({ - top: (bounds.top + bounds.height - _frames.bottom.height) - 1 - }).centerH().setCoords(); + _frames.bottom.set({ + top: (bounds.top + bounds.height - _frames.bottom.height) - 1 + }).centerH().setCoords(); - _frames.right.set({ - left: (bounds.left + bounds.width - _frames.right.width) - 1 - }).centerV().setCoords(); + _frames.right.set({ + left: (bounds.left + bounds.width - _frames.right.width) - 1 + }).centerV().setCoords(); - _frames.left.set({ - left: bounds.left - }).centerV().setCoords(); - } else { - _frames.top.set({ - top: (bounds.top - _frames.top.height) + 1, - }).centerH().setCoords(); + _frames.left.set({ + left: bounds.left + }).centerV().setCoords(); + } else { + _frames.top.set({ + top: (bounds.top - _frames.top.height) + 1, + }).centerH().setCoords(); - _frames.bottom.set({ - top: (bounds.top + bounds.height) - 1, - }).centerH().setCoords(); + _frames.bottom.set({ + top: (bounds.top + bounds.height) - 1, + }).centerH().setCoords(); - _frames.right.set({ - left: (bounds.left + bounds.width) - 1 - }).centerV().setCoords(); + _frames.right.set({ + left: (bounds.left + bounds.width) - 1 + }).centerV().setCoords(); - _frames.left.set({ - left: (bounds.left - _frames.left.width) + 1 - }).centerV().setCoords(); - } - viewport.canvas.getDragbars().apply(); - viewport.canvas.renderAll(); + _frames.left.set({ + left: (bounds.left - _frames.left.width) + 1 + }).centerV().setCoords(); + } + viewport.canvas.getDragbars().apply(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; } module.exports = FrameHandler; @@ -1120,78 +1120,78 @@ module.exports = FrameHandler; /* globals fabric */ function GoreHandler(viewport) { - var _enabled = false; - var _lines = []; + var _enabled = false; + var _lines = []; - /** + /** * @return {fabric.Line} */ - function getLine(left) { - return new fabric.Line([0, 0, 0, viewport.getData().height], { - evented: false, - strokeDashArray: [5, 5], - stroke: '#F31FB3', - strokeWidth: 1, - left: left, - top: viewport.getBounds().top - }); - } + function getLine(left) { + return new fabric.Line([0, 0, 0, viewport.getData().height], { + evented: false, + strokeDashArray: [5, 5], + stroke: '#F31FB3', + strokeWidth: 1, + left: left, + top: viewport.getBounds().top + }); + } - /** + /** * @return {GoreHandler} */ - this.clear = function () { - _lines.forEach(function (line) { - viewport.canvas.remove(line); - }); - _lines = []; - return this; - }; + this.clear = function () { + _lines.forEach(function (line) { + viewport.canvas.remove(line); + }); + _lines = []; + return this; + }; - /** + /** * @param {Boolean} enabled * @return {GoreHandler} */ - this.enable = function (enabled) { - _enabled = enabled; - this.clear(); + this.enable = function (enabled) { + _enabled = enabled; + this.clear(); - if (!_enabled) { - viewport.canvas.renderAll(); - return this; - } + if (!_enabled) { + viewport.canvas.renderAll(); + return this; + } - var viewportData = viewport.getData(); - var bounds = viewport.getBounds(); - var step = viewportData.ppmm * viewportData.image.scaleX * 450; + var viewportData = viewport.getData(); + var bounds = viewport.getBounds(); + var step = viewportData.ppmm * viewportData.image.scaleX * 450; - /* + /* * First round to 5 digits to fix pixel rounding issues when requested width is an even multiplier of 450mm. * Could set precision higher but 5 decimals places should be enough, pixel rounding issues show somewhere * around 15 decimals places. * Then round up to get correct number of gores. */ - var count = Math.ceil((bounds.width / step).toFixed(5)); + var count = Math.ceil((bounds.width / step).toFixed(5)); - for (var i = 1; i < count; i++) { - _lines.push(getLine(bounds.left + step * i)); - } + for (var i = 1; i < count; i++) { + _lines.push(getLine(bounds.left + step * i)); + } - _lines.forEach(function (o) { - viewport.canvas.add(o); - }); + _lines.forEach(function (o) { + viewport.canvas.add(o); + }); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * @return {GoreHandler} */ - this.reset = function () { - return this.enable(_enabled); - }; + this.reset = function () { + return this.enable(_enabled); + }; } module.exports = GoreHandler; @@ -1202,70 +1202,70 @@ module.exports = GoreHandler; function ImageDataHandler(img) { - var _cropData; + var _cropData; - /** + /** * Gets information about how the cropped image is dragged * @return {Object} */ - this.getCropData = function () { - return _cropData; + this.getCropData = function () { + return _cropData; + }; + + this.setCropData = function() { + var viewportBounds = img.canvas.getViewport().getBounds(); + if (!viewportBounds) { + return; + } + + var dragAxis = img.canvas.getViewport().getData().axis; + + var leftDiff = viewportBounds.left - img.left; + var topDiff = viewportBounds.top - img.top; + + // Robustness measure to handle the extreme precision of shape positioning in canvas. + var countAsZeroLimit = 1e-5; + leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff; + topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff; + + _cropData = { + x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0, + y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0, + viewportWidth: viewportBounds.width, + viewportHeight: viewportBounds.height, }; + }; - this.setCropData = function() { - var viewportBounds = img.canvas.getViewport().getBounds(); - if (!viewportBounds) { - return; - } + this.removeCropData = function() { + _cropData = null; + }; - var dragAxis = img.canvas.getViewport().getData().axis; - - var leftDiff = viewportBounds.left - img.left; - var topDiff = viewportBounds.top - img.top; - - // Robustness measure to handle the extreme precision of shape positioning in canvas. - var countAsZeroLimit = 1e-5; - leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff; - topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff; - - _cropData = { - x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0, - y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0, - viewportWidth: viewportBounds.width, - viewportHeight: viewportBounds.height, - }; - }; - - this.removeCropData = function() { - _cropData = null; - }; - - /** + /** * Gets an object containing applied transformations for the Image and also * how it is cropped and dragged. * @return {Object} */ - this.getData = function () { - var viewportData = img.canvas.getViewport().getData(); + this.getData = function () { + var viewportData = img.canvas.getViewport().getData(); - var returnValue = $.extend( - {}, - { - mirrored: img.canvas.getMirror().getStatus(), - width: viewportData.dim.width, - height: viewportData.dim.height, - }, - this.getCropData() - ); + var returnValue = $.extend( + {}, + { + mirrored: img.canvas.getMirror().getStatus(), + width: viewportData.dim.width, + height: viewportData.dim.height, + }, + this.getCropData() + ); - if (img.canvas.__type === 'canvas') { - var frameHandler = img.canvas.getViewport().getFrameHandler(); - returnValue.edge = frameHandler.getFrameType(); - returnValue.framed = returnValue.edge !== 'none'; - } + if (img.canvas.__type === 'canvas') { + var frameHandler = img.canvas.getViewport().getFrameHandler(); + returnValue.edge = frameHandler.getFrameType(); + returnValue.framed = returnValue.edge !== 'none'; + } - return returnValue; - }; + return returnValue; + }; } module.exports = ImageDataHandler; @@ -1278,198 +1278,198 @@ var Canvas = require('./Canvas'); var util = require('./util'); function ImageEditor(canvasId, args) { - var _canvas; + var _canvas; - var _settings = $.extend({ - // Type defaults to wallpaper - type: 'wallpaper', - // canvasFrameType defaults to image on frame - canvasFrameType: 'image', - canvasFrameSize: 2.9, - // Default texts on the buttons - texts: { - showThreeD: '3d', - hideThreeD: 'Flat', - showMurals: 'Show Murals Panel', - hideMurals: 'Hide Murals Panel', - showRulers: 'Show Ruler', - hideRulers: 'Hide Ruler', - showFullscreen: 'Fullscreen', - exitFullscreen: 'Exit Fullscreen', - cm: 'cm', - inch: 'inch' - }, - // Default dimensions - dimensions: { - width: 800, - height: 600 - }, - // Default unit - unit: 'cm', - isVisibleFullscreenButton: true - }, args); + var _settings = $.extend({ + // Type defaults to wallpaper + type: 'wallpaper', + // canvasFrameType defaults to image on frame + canvasFrameType: 'image', + canvasFrameSize: 2.9, + // Default texts on the buttons + texts: { + showThreeD: '3d', + hideThreeD: 'Flat', + showMurals: 'Show Murals Panel', + hideMurals: 'Hide Murals Panel', + showRulers: 'Show Ruler', + hideRulers: 'Hide Ruler', + showFullscreen: 'Fullscreen', + exitFullscreen: 'Exit Fullscreen', + cm: 'cm', + inch: 'inch' + }, + // Default dimensions + dimensions: { + width: 800, + height: 600 + }, + // Default unit + unit: 'cm', + isVisibleFullscreenButton: true + }, args); - // Initialize canvas - _canvas = new Canvas(canvasId, _settings.dimensions); + // Initialize canvas + _canvas = new Canvas(canvasId, _settings.dimensions); - // Let Canvas know which type it is, canvas or wallpaper since it is - // accessible for all objects contained within. + // Let Canvas know which type it is, canvas or wallpaper since it is + // accessible for all objects contained within. + _canvas.set({ + __type: _settings.type, + __texts: _settings.texts + }); + + // Adding buttons to the canvas depending on which type is active. + // It might be better that this resides somewhere else, either in Canvas or + // during the initialization of the image editor. + if (_canvas.__type === 'canvas') { + _canvas.getButtonMenu() + .addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () { + _canvas.toggle3D(this.isActive()); + }); _canvas.set({ - __type: _settings.type, - __texts: _settings.texts + __canvasFrameType: _settings.canvasFrameType, + __canvasFrameSize: _settings.canvasFrameSize, }); + } else { + _canvas.getButtonMenu() + .addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () { + _canvas.getViewport().getGores().enable(this.isActive()); + }) + .addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () { + _canvas.getViewport().getRulers().enable(this.isActive()); + }); + } - // Adding buttons to the canvas depending on which type is active. - // It might be better that this resides somewhere else, either in Canvas or - // during the initialization of the image editor. - if (_canvas.__type === 'canvas') { - _canvas.getButtonMenu() - .addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () { - _canvas.toggle3D(this.isActive()); - }); - _canvas.set({ - __canvasFrameType: _settings.canvasFrameType, - __canvasFrameSize: _settings.canvasFrameSize, - }); - } else { - _canvas.getButtonMenu() - .addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () { - _canvas.getViewport().getGores().enable(this.isActive()); - }) - .addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () { - _canvas.getViewport().getRulers().enable(this.isActive()); - }); + if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) { + _canvas.getButtonMenu() + .addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () { + util.toggleFullscreen(_canvas.getSelectionElement().parentNode); + }); + } + + _canvas.getButtonMenu().render(); + + // Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active. + $(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() { + var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen; + + if (isFullscreen) { + return; } - if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) { - _canvas.getButtonMenu() - .addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () { - util.toggleFullscreen(_canvas.getSelectionElement().parentNode); - }); - } - - _canvas.getButtonMenu().render(); - - // Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active. - $(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() { - var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen; - - if (isFullscreen) { - return; - } - - _canvas.getButtonMenu().getItems().forEach(function(button) { - if (button.getId() === 'toggleFullscreen') { - button.setActive(false); - } - }); - + _canvas.getButtonMenu().getItems().forEach(function(button) { + if (button.getId() === 'toggleFullscreen') { + button.setActive(false); + } }); - /** + }); + + /** * Crops image to desired dimensions * @param {int} width [description] * @param {int} height [description] * @param {string} unit cm|inch * @return {ImageEditor} */ - this.crop = function (width, height, unit, removeTransparency) { - removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false; + this.crop = function (width, height, unit, removeTransparency) { + removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false; - if (!width || !height) { - return this; - } + if (!width || !height) { + return this; + } - unit = typeof unit !== 'undefined' ? unit : _settings.unit; - var viewport = _canvas.getViewport(); - var frameType = _canvas.__canvasFrameType; + unit = typeof unit !== 'undefined' ? unit : _settings.unit; + var viewport = _canvas.getViewport(); + var frameType = _canvas.__canvasFrameType; - if (frameType === 'image') { - var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize; - width += 2 * canvasFrameSize; - height += 2 * canvasFrameSize; - } - viewport.set(width, height, unit); + if (frameType === 'image') { + var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize; + width += 2 * canvasFrameSize; + height += 2 * canvasFrameSize; + } + viewport.set(width, height, unit); - var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height); - if (shouldBeCropped) { - _canvas.getImage().__dragged = false; - _canvas.getImage().__cropped = true; - } - else { - _canvas.getImage().__cropped = false; - } + var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height); + if (shouldBeCropped) { + _canvas.getImage().__dragged = false; + _canvas.getImage().__cropped = true; + } + else { + _canvas.getImage().__cropped = false; + } - if (removeTransparency) { - _canvas.getApertures().setTransparent(false); - } + if (removeTransparency) { + _canvas.getApertures().setTransparent(false); + } - return this; - }; + return this; + }; - this.getCropRatio = function () { - var image = _canvas.getImage(); - var cropData = _canvas.getImageData().getCropData(); - if (!cropData) { - return false; - } - var scaledImageWidth = image.width * image.scaleX; - var scaledImageHeight = image.height * image.scaleY; - var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100; - var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100; + this.getCropRatio = function () { + var image = _canvas.getImage(); + var cropData = _canvas.getImageData().getCropData(); + if (!cropData) { + return false; + } + var scaledImageWidth = image.width * image.scaleX; + var scaledImageHeight = image.height * image.scaleY; + var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100; + var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100; - return {width: ratioWidth, height: ratioHeight}; - }; + return {width: ratioWidth, height: ratioHeight}; + }; - /** + /** * @param {string|object} key * @param {object} defaultValue * @return {object} */ - this.get = function (key, defaultValue) { - var value = _settings[key]; - return typeof value === 'undefined' ? defaultValue : value; - }; + this.get = function (key, defaultValue) { + var value = _settings[key]; + return typeof value === 'undefined' ? defaultValue : value; + }; - /** + /** * Loads the image into the canvas. * @param {Number|String} url * @param {Function} callback * @return {ImageEditor} */ - this.loadImage = function (url, callback) { - callback = typeof callback === 'function' ? callback : function () {}; - fabric.util.loadImage(this._url = url, function (obj) { - if(obj === null) { - throw new Error('Error loading ' + url); - } - var img = new fabric.Image(obj); - _canvas.setImage(img); - img.__url = url; - img.sendToBack(); - callback(img); - }, { crossOrigin: 'anonymous' }); - return this; - }; + this.loadImage = function (url, callback) { + callback = typeof callback === 'function' ? callback : function () {}; + fabric.util.loadImage(this._url = url, function (obj) { + if(obj === null) { + throw new Error('Error loading ' + url); + } + var img = new fabric.Image(obj); + _canvas.setImage(img); + img.__url = url; + img.sendToBack(); + callback(img); + }, { crossOrigin: 'anonymous' }); + return this; + }; - /** + /** * @param {string|object} key * @param {object} value * @return {ImageEditor} */ - this.set = function (key, value) { - $.extend(_settings, util.assertKeyValuePair(key, value)); - return this; - }; + this.set = function (key, value) { + $.extend(_settings, util.assertKeyValuePair(key, value)); + return this; + }; - util.setProperties(this, { - canvas: { - get: function () { - return _canvas; - } - } - }); + util.setProperties(this, { + canvas: { + get: function () { + return _canvas; + } + } + }); } module.exports = ImageEditor; @@ -1479,22 +1479,22 @@ module.exports = ImageEditor; function MirrorHandler(img) { - var _mirrored = 0; + var _mirrored = 0; - /** + /** * @param {Boolean} checked * @return {MirrorHandler} */ - this.set = function(checked) { - _mirrored = (img.flipX = checked) ? 1 : 0; - img.setCoords().canvas.renderAll(); + this.set = function(checked) { + _mirrored = (img.flipX = checked) ? 1 : 0; + img.setCoords().canvas.renderAll(); - return this; - }; + return this; + }; - this.getStatus = function() { - return _mirrored; - }; + this.getStatus = function() { + return _mirrored; + }; } @@ -1510,130 +1510,130 @@ var TextButton = require('./TextButton'); var config = require('./config'); function RulerHandler(viewport) { - var _enabled = false; - var _lines = { x: null, y: null }; - var _rect = { x: null, y: null }; + var _enabled = false; + var _lines = { x: null, y: null }; + var _rect = { x: null, y: null }; - function updateRulerText(ruler) { - var axis = ruler.axis; - var bounds = viewport.getBounds(); - var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]); - ruler.marker[axis] = ruler[axis] = pos; - var posWithinBounds = ruler[axis] - bounds[axis]; - var viewportData = viewport.getData(); - var imageData = viewport.canvas.getImage(); - var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX; - var dim = posWithinBounds / pixelsPerCm; - var units = viewportData.dim.units; + function updateRulerText(ruler) { + var axis = ruler.axis; + var bounds = viewport.getBounds(); + var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]); + ruler.marker[axis] = ruler[axis] = pos; + var posWithinBounds = ruler[axis] - bounds[axis]; + var viewportData = viewport.getData(); + var imageData = viewport.canvas.getImage(); + var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX; + var dim = posWithinBounds / pixelsPerCm; + var units = viewportData.dim.units; - if (units === 'inch') { - dim /= 2.54; - } - if (axis === 'top') { - dim = viewportData.dim.height - dim; - } - var value = Math.round(dim * 100) / 100; - if(units === 'cm') { - value = Math.round(value); - } - var label = viewport.canvas.__texts[units] || 'cm'; - ruler.setText(value + ' ' + label); + if (units === 'inch') { + dim /= 2.54; } + if (axis === 'top') { + dim = viewportData.dim.height - dim; + } + var value = Math.round(dim * 100) / 100; + if(units === 'cm') { + value = Math.round(value); + } + var label = viewport.canvas.__texts[units] || 'cm'; + ruler.setText(value + ' ' + label); + } - var Event = { - /** + var Event = { + /** * Triggers when handlebar is moved */ - onMove: function () { - updateRulerText(this); - } - }; + onMove: function () { + updateRulerText(this); + } + }; - /** + /** * @return {fabric.Line} */ - function getLine(axis) { - var bounds = viewport.getBounds(); - return new fabric.Line([ - 0, 0, - axis === 'x' ? bounds.width : 0, - axis === 'y' ? bounds.height : 0 - ], { - evented: false, - strokeDashArray: [5, 5], - stroke: '#000', - strokeWidth: 1, - top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, - left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left - }); - } + function getLine(axis) { + var bounds = viewport.getBounds(); + return new fabric.Line([ + 0, 0, + axis === 'x' ? bounds.width : 0, + axis === 'y' ? bounds.height : 0 + ], { + evented: false, + strokeDashArray: [5, 5], + stroke: '#000', + strokeWidth: 1, + top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, + left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left + }); + } - /** + /** * @return {RulerHandler} */ - this.clear = function () { - [].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) { - viewport.canvas.remove(o); - }); - return this; - }; + this.clear = function () { + [].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) { + viewport.canvas.remove(o); + }); + return this; + }; - /** + /** * @param {Boolean} enabled * @return {RulerHandler} */ - this.enable = function (enabled) { - var bounds = viewport.getBounds(); + this.enable = function (enabled) { + var bounds = viewport.getBounds(); - var keepPosition = ( - enabled && (_enabled === enabled) && + var keepPosition = ( + enabled && (_enabled === enabled) && _lines.x && (Math.abs(_lines.x.width - bounds.width) < 1) && _lines.y && (Math.abs(_lines.y.height - bounds.height) < 1) - ); + ); - if (keepPosition) { - updateRulerText(_rect.x); - updateRulerText(_rect.y); - return this; - } + if (keepPosition) { + updateRulerText(_rect.x); + updateRulerText(_rect.y); + return this; + } - _enabled = enabled; + _enabled = enabled; - this.clear(); + this.clear(); - if (!_enabled) { - viewport.canvas.renderAll(); - return this; - } + if (!_enabled) { + viewport.canvas.renderAll(); + return this; + } - _lines = { x: getLine('x'), y: getLine('y') }; + _lines = { x: getLine('x'), y: getLine('y') }; - viewport.canvas.add(_lines.x); - viewport.canvas.add(_lines.y); + viewport.canvas.add(_lines.x); + viewport.canvas.add(_lines.y); - _rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true) - .set(config.rulerHandle.x(_lines, bounds)) - .addTo(viewport.canvas) - .on('moving', Event.onMove) - .trigger('moving'); + _rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true) + .set(config.rulerHandle.x(_lines, bounds)) + .addTo(viewport.canvas) + .on('moving', Event.onMove) + .trigger('moving'); - _rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true) - .set(config.rulerHandle.y(_lines, bounds)) - .addTo(viewport.canvas) - .on('moving', Event.onMove) - .trigger('moving'); + _rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true) + .set(config.rulerHandle.y(_lines, bounds)) + .addTo(viewport.canvas) + .on('moving', Event.onMove) + .trigger('moving'); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * @return {RulerHandler} */ - this.reset = function () { - return this.enable(_enabled); - }; + this.reset = function () { + return this.enable(_enabled); + }; } module.exports = RulerHandler; @@ -1652,113 +1652,113 @@ var config = require('./config'); * @param {bool} isActive */ function TextButton(id, text, settings, isActive) { - /* jshint unused:false */ + /* jshint unused:false */ - fabric.Group.call(this); + fabric.Group.call(this); - var __active = isActive || false; - var _callback = null; - var _rect = null; - var _text = null; - var _id = id; - var width = settings.rect ? settings.rect.width : 0; - var height = settings.rect ? settings.rect.height : 0; + var __active = isActive || false; + var _callback = null; + var _rect = null; + var _text = null; + var _id = id; + var width = settings.rect ? settings.rect.width : 0; + var height = settings.rect ? settings.rect.height : 0; - var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect); - var _textSettings = $.extend({}, config.textButton.text, settings.text, { - text: Array.isArray(text) ? text[0] : text, - textActive: Array.isArray(text) ? text[1] : text, - }); + var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect); + var _textSettings = $.extend({}, config.textButton.text, settings.text, { + text: Array.isArray(text) ? text[0] : text, + textActive: Array.isArray(text) ? text[1] : text, + }); - this.selectable = true; + this.selectable = true; - // Make sure we're interactive - this.disabled = false; - this.hoverCursor = config.textButton.cursor; + // Make sure we're interactive + this.disabled = false; + this.hoverCursor = config.textButton.cursor; - // Initialize text and rectangle - _text = new fabric.Text('', _textSettings); - _rect = new fabric.Rect(_rectSettings); + // Initialize text and rectangle + _text = new fabric.Text('', _textSettings); + _rect = new fabric.Rect(_rectSettings); - this.addWithUpdate(_rect).addWithUpdate(_text); + this.addWithUpdate(_rect).addWithUpdate(_text); - /** + /** * @param {String} text * @return {TextButton} */ - this.setText = function(text) { - _text.setText((text || '').toString()).setCoords(); + this.setText = function(text) { + _text.setText((text || '').toString()).setCoords(); - if (_rectSettings.dynamicW) { - this.width = _rect.width = _text.width + config.textButton.padding; - } + if (_rectSettings.dynamicW) { + this.width = _rect.width = _text.width + config.textButton.padding; + } - if (_rectSettings.dynamicH) { - this.height = _rect.height = _text.height + config.textButton.padding; - } + if (_rectSettings.dynamicH) { + this.height = _rect.height = _text.height + config.textButton.padding; + } - return this.setCoords(); - }; + return this.setCoords(); + }; - this.getId = function() { - return _id; - }; + this.getId = function() { + return _id; + }; - /** + /** * @return {Boolean} */ - this.isActive = function() { - return this.__active; - }; + this.isActive = function() { + return this.__active; + }; - function toggleActiveStyle() { - /*jshint validthis: true */ - _rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']); - _text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']); - this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']); + function toggleActiveStyle() { + /*jshint validthis: true */ + _rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']); + _text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']); + this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']); + } + + function handleMouseDown(e) { + /*jshint validthis: true */ + toggleActiveStyle.call(this); + _callback.call(this, e); + + if (this.__group) { + this.__group.render(); } + } - function handleMouseDown(e) { - /*jshint validthis: true */ - toggleActiveStyle.call(this); - _callback.call(this, e); + this.onClick = function(callback) { + _callback = callback || function() {}; + this.on('mousedown', function (e) { + // As inactive buttons are still clickable, we first check if the button is disabled. + // Only then we should do stuff. + if (!this.disabled) { + this.__active = !this.__active; + handleMouseDown.call(this, e); + } + }.bind(this)); + return this; + }; - if (this.__group) { - this.__group.render(); - } - } + this.setActive = function (isActive) { + this.__active = typeof isActive === 'undefined' ? true : !!isActive; + toggleActiveStyle.call(this); + }; - this.onClick = function(callback) { - _callback = callback || function() {}; - this.on('mousedown', function (e) { - // As inactive buttons are still clickable, we first check if the button is disabled. - // Only then we should do stuff. - if (!this.disabled) { - this.__active = !this.__active; - handleMouseDown.call(this, e); - } - }.bind(this)); - return this; - }; + this.setDisabled = function (isDisabled) + { + this.disabled = isDisabled; - this.setActive = function (isActive) { - this.__active = typeof isActive === 'undefined' ? true : !!isActive; - toggleActiveStyle.call(this); - }; + _rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']); + _text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']); - this.setDisabled = function (isDisabled) - { - this.disabled = isDisabled; + this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor; + }; - _rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']); - _text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']); - - this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor; - }; - - if (_textSettings.text) { - this.setText(_textSettings.text); - } + if (_textSettings.text) { + this.setText(_textSettings.text); + } } TextButton.prototype = Object.create(fabric.Group.prototype); @@ -1776,203 +1776,203 @@ var RulerHandler = require('./RulerHandler'); var util = require('./util'); function Viewport(canvas) { - var _beams = []; - var _borderWidth = 2; - var _data = null; - var _rect; - var self = this; + var _beams = []; + var _borderWidth = 2; + var _data = null; + var _rect; + var self = this; - /** + /** * Render the diagonal lines from viewport to edge of the canvas */ - function drawBeams() { - _beams.forEach(function (beam) { - canvas.remove(beam); - }); + function drawBeams() { + _beams.forEach(function (beam) { + canvas.remove(beam); + }); - _beams = []; + _beams = []; - // TOP LEFT - _beams.push(new fabric.Line( - [_rect.left, _rect.top, _rect.left - _rect.top, -1], { - stroke: '#fff', - strokeWidth: 2, - } - )); + // TOP LEFT + _beams.push(new fabric.Line( + [_rect.left, _rect.top, _rect.left - _rect.top, -1], { + stroke: '#fff', + strokeWidth: 2, + } + )); - // TOP RIGHT - _beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width })); - // BOTTOM RIGHT - _beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height })); - // BOTTOM LEFT - _beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height })); + // TOP RIGHT + _beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width })); + // BOTTOM RIGHT + _beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height })); + // BOTTOM LEFT + _beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height })); - _beams.forEach(function (o) { - canvas.add(o); - o.bringToFront(); - }); - } + _beams.forEach(function (o) { + canvas.add(o); + o.bringToFront(); + }); + } - /** + /** * Gets an object with min / max values for each axis, based on the bounds * of passed fabric.Rect * @param {fabric.Rect} rect * @return {Object} */ - function calcMinMaxBoundsForRect(rect, img) { - return { - left: { - min: rect.left + rect.width - (img.width * img.scaleX), - max: rect.left - }, - top: { - min: rect.top + rect.height - (img.height * img.scaleY), - max: rect.top - } - }; - } + function calcMinMaxBoundsForRect(rect, img) { + return { + left: { + min: rect.left + rect.width - (img.width * img.scaleX), + max: rect.left + }, + top: { + min: rect.top + rect.height - (img.height * img.scaleY), + max: rect.top + } + }; + } - /** + /** * Applies viewport to page */ - function apply() { - var cropData = canvas.getImageData().getCropData(); - canvas.remove(_rect); + function apply() { + var cropData = canvas.getImageData().getCropData(); + canvas.remove(_rect); - _rect = new fabric.Rect({ - evented: false, - fill: 'transparent', - width: _data.width, - height: _data.height, - stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff', - strokeWidth: _borderWidth, - }); + _rect = new fabric.Rect({ + evented: false, + fill: 'transparent', + width: _data.width, + height: _data.height, + stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff', + strokeWidth: _borderWidth, + }); - _rect.width += _borderWidth; - _rect.height += _borderWidth; - _rect.addTo(canvas).center().setCoords(); + _rect.width += _borderWidth; + _rect.height += _borderWidth; + _rect.addTo(canvas).center().setCoords(); - if (cropData) { - var viewportBounds = _rect.getInsideBoundingRect(); + if (cropData) { + var viewportBounds = _rect.getInsideBoundingRect(); - // Calculate the new position after screenresize and when the - // image already has been cropped to a certain position. - var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x); - var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y); + // Calculate the new position after screenresize and when the + // image already has been cropped to a certain position. + var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x); + var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y); - canvas.getImage().set({ left: left, top: top }).setCoords(); - } else { - canvas.getImage().center().setCoords(); - canvas.getImageData().setCropData(); - } - - if(canvas.__type !== 'wallpaper') { - canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage())); - canvas.getApertures().apply(_data.axis, _rect.getBoundingRect()); - } else { - canvas.getApertures().disable(); - } - - if (canvas.__type !== 'canvas') { - drawBeams(); - } else { - self.setFrame(canvas.__canvasFrameType); - } - - canvas.getDragbars().apply(); - // Apertures sometimes overlaps the viewports bounding rect. - // Solve this by bringing it to the front after apertures are applied. - _rect.bringToFront(); + canvas.getImage().set({ left: left, top: top }).setCoords(); + } else { + canvas.getImage().center().setCoords(); + canvas.getImageData().setCropData(); } - this.canvas = canvas; + if(canvas.__type !== 'wallpaper') { + canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage())); + canvas.getApertures().apply(_data.axis, _rect.getBoundingRect()); + } else { + canvas.getApertures().disable(); + } - this.getBounds = function () { - return _rect ? _rect.getInsideBoundingRect() : null; - }; + if (canvas.__type !== 'canvas') { + drawBeams(); + } else { + self.setFrame(canvas.__canvasFrameType); + } - /** + canvas.getDragbars().apply(); + // Apertures sometimes overlaps the viewports bounding rect. + // Solve this by bringing it to the front after apertures are applied. + _rect.bringToFront(); + } + + this.canvas = canvas; + + this.getBounds = function () { + return _rect ? _rect.getInsideBoundingRect() : null; + }; + + /** * @return {Viewport} */ - this.reset = function () { - if (_data) { - return this.set(_data.dim.width, _data.dim.height, _data.dim.units); - } - return this; - }; + this.reset = function () { + if (_data) { + return this.set(_data.dim.width, _data.dim.height, _data.dim.units); + } + return this; + }; - /** + /** * @param {Number} width * @param {Number} height * @param {string} units * @return {Viewport} */ - this.set = function (width, height, units) { - if (!width || !height) { - return this; - } + this.set = function (width, height, units) { + if (!width || !height) { + return this; + } - _data = util.calcCrop(canvas.getImage(), width, height, units); + _data = util.calcCrop(canvas.getImage(), width, height, units); - var cropData = canvas.getImageData().getCropData(); - var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); + var cropData = canvas.getImageData().getCropData(); + var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); - if (!isAspectTheSame) { - canvas.getImageData().removeCropData(); - } + if (!isAspectTheSame) { + canvas.getImageData().removeCropData(); + } - apply(); - this.getGores().reset(); - this.getRulers().reset(); + apply(); + this.getGores().reset(); + this.getRulers().reset(); - if (canvas.getImage().__cropped && !isAspectTheSame) { - canvas.getApertures().setTransparent(true); + if (canvas.getImage().__cropped && !isAspectTheSame) { + canvas.getApertures().setTransparent(true); - // Trigger event to tell the image needs to be dragged. - $(document).trigger('PIE:needs-dragging', { axis: _data.axis }); - } + // Trigger event to tell the image needs to be dragged. + $(document).trigger('PIE:needs-dragging', { axis: _data.axis }); + } - canvas.getButtonMenu().bringToFront(); + canvas.getButtonMenu().bringToFront(); - return this; - }; + return this; + }; - /** + /** * @param {string} frameType white|black|image|none * @return {Viewport} */ - this.setFrame = function (frameType) { - this.getFrameHandler().setFrames(frameType); + this.setFrame = function (frameType) { + this.getFrameHandler().setFrames(frameType); - var buttons = canvas.getButtonMenu().getItems(); - if (frameType === 'none') { - buttons[0].setDisabled(true); - } - else { - buttons[0].setDisabled(false); - } - canvas.getButtonMenu().bringToFront(); + var buttons = canvas.getButtonMenu().getItems(); + if (frameType === 'none') { + buttons[0].setDisabled(true); + } + else { + buttons[0].setDisabled(false); + } + canvas.getButtonMenu().bringToFront(); - canvas.refresh3dView(); - }; + canvas.refresh3dView(); + }; - this.getData = function () { - return _data; - }; + this.getData = function () { + return _data; + }; - var _frameHandler = null; + var _frameHandler = null; - this.getFrameHandler = function () { - return _frameHandler || (_frameHandler = new FrameHandler(this)); - }; + this.getFrameHandler = function () { + return _frameHandler || (_frameHandler = new FrameHandler(this)); + }; - this.getGores = function () { - return this.__goreHandler || (this.__goreHandler = new GoreHandler(this)); - }; + this.getGores = function () { + return this.__goreHandler || (this.__goreHandler = new GoreHandler(this)); + }; - this.getRulers = function () { - return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this)); - }; + this.getRulers = function () { + return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this)); + }; } @@ -1982,12 +1982,12 @@ module.exports = Viewport; 'use strict'; module.exports = { - frames: require('./config/frames'), - textButton: require('./config/text-button'), - buttonMenu: require('./config/button-menu'), - rulerHandle: require('./config/ruler-handle'), - dragHandle: require('./config/drag-handle'), - dragBar: require('./config/drag-bar') + frames: require('./config/frames'), + textButton: require('./config/text-button'), + buttonMenu: require('./config/button-menu'), + rulerHandle: require('./config/ruler-handle'), + dragHandle: require('./config/drag-handle'), + dragBar: require('./config/drag-bar') }; },{"./config/button-menu":17,"./config/drag-bar":18,"./config/drag-handle":19,"./config/frames":20,"./config/ruler-handle":21,"./config/text-button":22}],17:[function(require,module,exports){ @@ -1995,41 +1995,41 @@ module.exports = { module.exports = { - canvas: { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#343434', - activeFill: '#494949', - }, + canvas: { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', }, - - 'photo-wallpaper': { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#000000', - activeFill: '#444444', - }, + rect: { + fill: '#343434', + activeFill: '#494949', }, + }, - wallpaper: { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#343434', - activeFill: '#494949', - }, - } + 'photo-wallpaper': { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', + }, + rect: { + fill: '#000000', + activeFill: '#444444', + }, + }, + + wallpaper: { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', + }, + rect: { + fill: '#343434', + activeFill: '#494949', + }, + } }; @@ -2037,26 +2037,26 @@ module.exports = { 'use strict'; module.exports = { - fill: '#bbbbbb', - size: 20, + fill: '#bbbbbb', + size: 20, }; },{}],19:[function(require,module,exports){ 'use strict'; module.exports = { - text: { - fontFamily: 'breuer', - fontSize: 12, - fill: '#ffffff', - originX: 'center', - top: 2, - }, - rect: { - fill: '#666666', - height: 20, - originX: 'center', - }, + text: { + fontFamily: 'breuer', + fontSize: 12, + fill: '#ffffff', + originX: 'center', + top: 2, + }, + rect: { + fill: '#666666', + height: 20, + originX: 'center', + }, }; },{}],20:[function(require,module,exports){ @@ -2064,27 +2064,27 @@ module.exports = { module.exports = { - default: { - fill: '#000000', - stroke: '#f31fb3', - width: 1, - height: 1, - }, + default: { + fill: '#000000', + stroke: '#f31fb3', + width: 1, + height: 1, + }, - image: { - fill: 'rgba(0,0,0,0.2)', - strokeWidth: 1, - }, + image: { + fill: 'rgba(0,0,0,0.2)', + strokeWidth: 1, + }, - black: { - fill: '#000000', - strokeWidth: 0, - }, + black: { + fill: '#000000', + strokeWidth: 0, + }, - white: { - fill: '#ffffff', - strokeWidth: 0, - }, + white: { + fill: '#ffffff', + strokeWidth: 0, + }, }; @@ -2093,48 +2093,48 @@ module.exports = { module.exports = { - line: function(axis, bounds) { - return { - evented: false, - strokeDashArray: [5, 5], - stroke: '#000', - strokeWidth: 1, - top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, - left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left - }; - }, + line: function(axis, bounds) { + return { + evented: false, + strokeDashArray: [5, 5], + stroke: '#000', + strokeWidth: 1, + top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, + left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left + }; + }, - text: { - fontSize: 12, - width: 75, - height: 20, - fill: '#FFFFFF', - }, + text: { + fontSize: 12, + width: 75, + height: 20, + fill: '#FFFFFF', + }, - x: function(lines, bounds) { - return { - axis: 'left', - marker: lines.y, - top: Math.ceil(bounds.top + bounds.height + 5), - left: lines.y.left, - originX: 'center', - lockMovementY: true, - moveCursor: 'ew-resize', - hoverCursor: 'ew-resize', - }; - }, - y: function(lines, bounds) { - return { - axis: 'top', - marker: lines.x, - top: lines.x.top, - left: Math.ceil(bounds.left + bounds.width + 5), - originY: 'center', - lockMovementX: true, - moveCursor: 'ns-resize', - hoverCursor: 'ns-resize', - }; - } + x: function(lines, bounds) { + return { + axis: 'left', + marker: lines.y, + top: Math.ceil(bounds.top + bounds.height + 5), + left: lines.y.left, + originX: 'center', + lockMovementY: true, + moveCursor: 'ew-resize', + hoverCursor: 'ew-resize', + }; + }, + y: function(lines, bounds) { + return { + axis: 'top', + marker: lines.x, + top: lines.x.top, + left: Math.ceil(bounds.left + bounds.width + 5), + originY: 'center', + lockMovementX: true, + moveCursor: 'ns-resize', + hoverCursor: 'ns-resize', + }; + } }; },{}],22:[function(require,module,exports){ @@ -2142,32 +2142,32 @@ module.exports = { module.exports = { - rect: function(width, height) { - return { - fill: '#343434', - activeFill: '#494949', - disabledFill: '#494949', - originX: 'center', - originY: 'center', - width: width || 1, - dynamicW: !width, - height: height || 1, - dynamicH: !height, - }; - }, + rect: function(width, height) { + return { + fill: '#343434', + activeFill: '#494949', + disabledFill: '#494949', + originX: 'center', + originY: 'center', + width: width || 1, + dynamicW: !width, + height: height || 1, + dynamicH: !height, + }; + }, - text: { - fill: '#ffffff', - disabledFill: '#999999', - fontFamily: 'breuer', - fontSize: 14, - originX: 'center', - originY: 'center', - }, + text: { + fill: '#ffffff', + disabledFill: '#999999', + fontFamily: 'breuer', + fontSize: 14, + originX: 'center', + originY: 'center', + }, - cursor: 'pointer', - disabledCursor: 'default', - padding: 20, + cursor: 'pointer', + disabledCursor: 'default', + padding: 20, }; },{}],23:[function(require,module,exports){ @@ -2179,59 +2179,59 @@ var util = require('./util'); function ExtendFabricFunctionality() { - // Set default values for the fabric canvas - $.extend(fabric.Object.prototype, { - cornerSize: 0, - hasBorders: false, - hasControls: false, - padding: 0, - selectable: false, - strokeWidth: 0, - addTo: function(canvas) { - canvas.add(this); - return this; - }, - }); + // Set default values for the fabric canvas + $.extend(fabric.Object.prototype, { + cornerSize: 0, + hasBorders: false, + hasControls: false, + padding: 0, + selectable: false, + strokeWidth: 0, + addTo: function(canvas) { + canvas.add(this); + return this; + }, + }); - util.setProperties(fabric.Image.prototype, { - drag: { - get: function() { - return this.__draggable || (this.__draggable = new Draggable(this)); - } - } - }); + util.setProperties(fabric.Image.prototype, { + drag: { + get: function() { + return this.__draggable || (this.__draggable = new Draggable(this)); + } + } + }); - $.extend(fabric.Rect.prototype, { - /** + $.extend(fabric.Rect.prototype, { + /** * Gets the inner bounds of this fabric.Rect * @return {Object} */ - getInsideBoundingRect: function() { - var bounds = this.getBoundingRect(); - var returnValue = { - left: bounds.left + this.strokeWidth, - top: bounds.top + this.strokeWidth, - width: bounds.width - this.strokeWidth * 2, - height: bounds.height - this.strokeWidth * 2 - }; + getInsideBoundingRect: function() { + var bounds = this.getBoundingRect(); + var returnValue = { + left: bounds.left + this.strokeWidth, + top: bounds.top + this.strokeWidth, + width: bounds.width - this.strokeWidth * 2, + height: bounds.height - this.strokeWidth * 2 + }; - returnValue.right = returnValue.left + returnValue.width; - returnValue.bottom = returnValue.top + returnValue.height; + returnValue.right = returnValue.left + returnValue.width; + returnValue.bottom = returnValue.top + returnValue.height; - returnValue.min = { - left: returnValue.left, - top: returnValue.top - }; + returnValue.min = { + left: returnValue.left, + top: returnValue.top + }; - returnValue.max = { - left: returnValue.left + returnValue.width, - top: returnValue.top + returnValue.height - }; + returnValue.max = { + left: returnValue.left + returnValue.width, + top: returnValue.top + returnValue.height + }; - return returnValue; - } - }); + return returnValue; + } + }); } module.exports = ExtendFabricFunctionality; @@ -2242,18 +2242,18 @@ module.exports = ExtendFabricFunctionality; (function() { - /** + /** * Fabric functionality is extended with some custom functionality. This is done before * we do anything else. */ - require('./extend-fabric-functionality')(); + require('./extend-fabric-functionality')(); - /** + /** * ImageEditor is the starting point of all files. Here the image editor is created and * it receives attributes from the initialisation. As this is done from outside of this file, * the ImageEditor should be available on globally. */ - window.ImageEditor = require('./ImageEditor'); + window.ImageEditor = require('./ImageEditor'); }()); @@ -2262,30 +2262,30 @@ module.exports = ExtendFabricFunctionality; module.exports = { - assertKeyValuePair: require('./utils/assert-key-value-pair'), - assertBetween: require('./utils/assert-between'), - calcCrop: require('./utils/calc-crop'), - setPositionInside: require('./utils/set-position-inside'), - setProperties: require('./utils/set-properties'), - toggleFullscreen: require('./utils/toggle-fullscreen'), - isMobile: require('./utils/is-mobile'), - MouseMetrics: require('./utils/mouse-metrics'), - supportsFullscreen: require('./utils/supports-fullscreen'), - isFullscreen: require('./utils/is-fullscreen'), - isAspectChanged: require('./utils/is-aspect-changed'), + assertKeyValuePair: require('./utils/assert-key-value-pair'), + assertBetween: require('./utils/assert-between'), + calcCrop: require('./utils/calc-crop'), + setPositionInside: require('./utils/set-position-inside'), + setProperties: require('./utils/set-properties'), + toggleFullscreen: require('./utils/toggle-fullscreen'), + isMobile: require('./utils/is-mobile'), + MouseMetrics: require('./utils/mouse-metrics'), + supportsFullscreen: require('./utils/supports-fullscreen'), + isFullscreen: require('./utils/is-fullscreen'), + isAspectChanged: require('./utils/is-aspect-changed'), }; },{"./utils/assert-between":26,"./utils/assert-key-value-pair":27,"./utils/calc-crop":28,"./utils/is-aspect-changed":29,"./utils/is-fullscreen":30,"./utils/is-mobile":31,"./utils/mouse-metrics":32,"./utils/set-position-inside":33,"./utils/set-properties":34,"./utils/supports-fullscreen":35,"./utils/toggle-fullscreen":36}],26:[function(require,module,exports){ 'use strict'; function assertBetween(value, min, max) { - if (value < min) { - return min; - } - if (value > max) { - return max; - } - return value; + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; } module.exports = assertBetween; @@ -2294,14 +2294,14 @@ module.exports = assertBetween; 'use strict'; function assertKeyValuePair(key, value) { - if (typeof key === 'object') { - return key; - } + if (typeof key === 'object') { + return key; + } - var returnValue = {}; - returnValue[key] = value; + var returnValue = {}; + returnValue[key] = value; - return returnValue; + return returnValue; } module.exports = assertKeyValuePair; @@ -2322,38 +2322,38 @@ module.exports = assertKeyValuePair; * ppmm: NUMBER */ function calcCrop(obj, width, height, units) { - var cropRatio = width / height; - var objRatio = obj.width / obj.height; - var inchToCm = units === "inch" ? 2.54 : 1; + var cropRatio = width / height; + var objRatio = obj.width / obj.height; + var inchToCm = units === 'inch' ? 2.54 : 1; - var returnValue = { - image: obj, - axis: objRatio > cropRatio ? 'x' : 'y', - dim: { - width: Number(width), - height: Number(height), - units: units - }, - width: obj.width * obj.scaleX, - height: obj.height * obj.scaleY, - objectRatio: objRatio, - cropRatio: cropRatio - }; + var returnValue = { + image: obj, + axis: objRatio > cropRatio ? 'x' : 'y', + dim: { + width: Number(width), + height: Number(height), + units: units + }, + width: obj.width * obj.scaleX, + height: obj.height * obj.scaleY, + objectRatio: objRatio, + cropRatio: cropRatio + }; - if (objRatio > cropRatio) { - returnValue.width *= cropRatio / objRatio; - } else { - returnValue.height /= cropRatio / objRatio; - } + if (objRatio > cropRatio) { + returnValue.width *= cropRatio / objRatio; + } else { + returnValue.height /= cropRatio / objRatio; + } - // Pixels per millimeter - var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10); + // Pixels per millimeter + var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10); - //Round to four decimal places to avoid precision issues. At least 4 decimals is needed though - //for correct calculation of number of gores on wide wallpaperes in editor. - returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4; + //Round to four decimal places to avoid precision issues. At least 4 decimals is needed though + //for correct calculation of number of gores on wide wallpaperes in editor. + returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4; - return returnValue; + return returnValue; } module.exports = calcCrop; @@ -2362,7 +2362,7 @@ module.exports = calcCrop; 'use strict'; function isAspectChanged(x1, y1, x2, y2) { - return (Math.abs(x1 / y1 - x2 / y2) > 0.005); + return (Math.abs(x1 / y1 - x2 / y2) > 0.005); } module.exports = isAspectChanged; @@ -2371,7 +2371,7 @@ module.exports = isAspectChanged; 'use strict'; function isFullscreen() { - return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; } module.exports = isFullscreen; @@ -2381,7 +2381,7 @@ module.exports = isFullscreen; /* globals $, window */ function isMobile() { - return $(window).width() < 768; + return $(window).width() < 768; } module.exports = isMobile; @@ -2390,24 +2390,24 @@ module.exports = isMobile; 'use strict'; var MouseMetrics = { - previousMouseData: { - x: null, - y: null - }, + previousMouseData: { + x: null, + y: null + }, - deletePreviousMouseData: function() { - MouseMetrics.previousMouseData = { - x: null, - y: null - }; - }, + deletePreviousMouseData: function() { + MouseMetrics.previousMouseData = { + x: null, + y: null + }; + }, - setPreviousMouseData: function(values) { - MouseMetrics.previousMouseData = { - x: values.x || null, - y: values.y || null, - }; - }, + setPreviousMouseData: function(values) { + MouseMetrics.previousMouseData = { + x: values.x || null, + y: values.y || null, + }; + }, }; module.exports = MouseMetrics; @@ -2421,16 +2421,16 @@ module.exports = MouseMetrics; * @return {fabric.Object} */ function setPositionInside(obj, bounds) { - ['left', 'top'].forEach(function (v) { - if (obj[v] < bounds[v].min) { - obj.set(v, bounds[v].min).setCoords(); - } + ['left', 'top'].forEach(function (v) { + if (obj[v] < bounds[v].min) { + obj.set(v, bounds[v].min).setCoords(); + } - if (obj[v] > bounds[v].max) { - obj.set(v, bounds[v].max).setCoords(); - } - }); - return obj; + if (obj[v] > bounds[v].max) { + obj.set(v, bounds[v].max).setCoords(); + } + }); + return obj; } module.exports = setPositionInside; @@ -2443,11 +2443,11 @@ module.exports = setPositionInside; * @param {Object} properties */ function setProperties(obj, properties) { - for (var o in properties) { - if (properties.hasOwnProperty(o)) { - Object.defineProperty(obj, o, properties[o]); - } + for (var o in properties) { + if (properties.hasOwnProperty(o)) { + Object.defineProperty(obj, o, properties[o]); } + } } module.exports = setProperties; @@ -2457,7 +2457,7 @@ module.exports = setProperties; function supportsFullscreen() { - return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen; + return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen; } @@ -2472,28 +2472,28 @@ var isFullscreen = require('./is-fullscreen'); * @param {HTMLElement} elem */ function toggleFullscreen(elem) { - if (isFullscreen()) { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitCancelFullScreen) { - document.webkitCancelFullScreen(); - } - return; + if (isFullscreen()) { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitCancelFullScreen) { + document.webkitCancelFullScreen(); } + return; + } - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if (elem.webkitRequestFullScreen) { - elem.webkitRequestFullScreen(); - } else if (elem.mozRequestFullScreen) { - elem.mozRequestFullScreen(); - } else if (elem.msRequestFullscreen) { - elem.msRequestFullscreen(); - } + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullScreen) { + elem.webkitRequestFullScreen(); + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen(); + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen(); + } } module.exports = toggleFullscreen; diff --git a/examples/.eslintrc b/examples/.eslintrc new file mode 100644 index 0000000..0445aed --- /dev/null +++ b/examples/.eslintrc @@ -0,0 +1,7 @@ +{ + "globals": { + "$": false, + "ImageEditor": false, + "QUnit": false + } +} diff --git a/examples/basic/app.js b/examples/basic/app.js index 0b7cadc..13b114b 100644 --- a/examples/basic/app.js +++ b/examples/basic/app.js @@ -8,174 +8,174 @@ (function() { - var $document = $(document); - var $window = $(window); - var $wrapper = $('#wrapper'); - var $formControl = $('#form-control'); - var editor = null; - var widthInCm, heightInCm; + var $document = $(document); + var $window = $(window); + var $wrapper = $('#wrapper'); + var $formControl = $('#form-control'); + var editor = null; + var widthInCm, heightInCm; - // Inputs for the editor - var $input = { - w: $formControl.find('input[name="w"]'), - h: $formControl.find('input[name="h"]'), - units: $formControl.find('select[name="units"]'), - image_id: $formControl.find('input[name="image_id"]'), - mirror: $formControl.find('input[name="mirror"]'), - noCrop: $formControl.find('input[name="no-crop"]'), - border: $formControl.find('select[name="canvas-border"]'), + // Inputs for the editor + var $input = { + w: $formControl.find('input[name="w"]'), + h: $formControl.find('input[name="h"]'), + units: $formControl.find('select[name="units"]'), + image_id: $formControl.find('input[name="image_id"]'), + mirror: $formControl.find('input[name="mirror"]'), + noCrop: $formControl.find('input[name="no-crop"]'), + border: $formControl.find('select[name="canvas-border"]'), + }; + var imageUrl = '//images.photowall.com/products/' + $input.image_id.val() + '.jpg?h=450'; + + widthInCm = $input.w.val(); + heightInCm = $input.h.val(); + + function isFullscreen() { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; + } + + function getOptimalDimension(values, currentDimension, ratio) { + if (currentDimension === 'h') { + values.width = Math.round(values.height * ratio); + } else { + values.height = Math.round(values.width / ratio); + } + + return values; + } + + function handleDimensionChange() { + var noCropIsChecked = $input.noCrop.is(':checked'); + var data = editor.canvas.getViewport().getData(); + var values = { + width: $input.w.val(), + height: $input.h.val(), }; - var imageUrl = '//images.photowall.com/products/' + $input.image_id.val() + '.jpg?h=450'; - widthInCm = $input.w.val(); - heightInCm = $input.h.val(); - - function isFullscreen() { - return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; + if (noCropIsChecked) { + var currentDimension = $(this).attr('name') === 'h' ? 'h' : 'w'; + values = getOptimalDimension(values, currentDimension, data.objectRatio); } - function getOptimalDimension(values, currentDimension, ratio) { - if (currentDimension === 'h') { - values.width = Math.round(values.height * ratio); - } else { - values.height = Math.round(values.width / ratio); - } + $input.w.val(values.width); + $input.h.val(values.height); - return values; + if ($input.units.val() == 'inch') { + widthInCm = Math.round(values.width * 2.54); + heightInCm = Math.round(values.height * 2.54); + } + else { + widthInCm = values.width; + heightInCm = values.height; } - function handleDimensionChange() { - var noCropIsChecked = $input.noCrop.is(':checked'); - var data = editor.canvas.getViewport().getData(); - var values = { - width: $input.w.val(), - height: $input.h.val(), - }; + editor.crop(values.width, values.height, $input.units.val()); + } - if (noCropIsChecked) { - var currentDimension = $(this).attr('name') === 'h' ? 'h' : 'w'; - values = getOptimalDimension(values, currentDimension, data.objectRatio); - } + function handleMirrorChange() { + editor.canvas.getMirror().set(this.checked); + } - $input.w.val(values.width); - $input.h.val(values.height); + function handleNoCropChange() { + $input.w.trigger('input'); + } - if ($input.units.val() == 'inch') { - widthInCm = Math.round(values.width * 2.54); - heightInCm = Math.round(values.height * 2.54); - } - else { - widthInCm = values.width; - heightInCm = values.height; - } + function handleFrameChange() { - editor.crop(values.width, values.height, $input.units.val()); + if ($(this).val() === 'none') { + editor.canvas.toggle3D(false); } - function handleMirrorChange() { - editor.canvas.getMirror().set(this.checked); - } + editor.canvas.getViewport().setFrame($(this).val()); + } - function handleNoCropChange() { + function handleResize() { + var width = $wrapper.width(); + var height = isFullscreen() ? $window.height() : $wrapper.height(); + editor.canvas.resize({width: width, height: height}); + } + + function getWrapperData() { + var $navbar = $('.image-editor__navbar'); + var isFullScreen = isFullscreen(); + var isMobile = $window.width() <= 767; + var windowHeight = window.innerHeight ? window.innerHeight : $window.height(); + var windowWidth = window.innerWidth ? window.innerWidth : $window.width(); + + return { + width: isFullScreen ? windowWidth : (isMobile ? windowWidth : $wrapper.width()), + height: isFullScreen ? windowHeight : (isMobile ? windowHeight - $navbar.height() : $wrapper.height()) + }; + } + + function handleUnitsChange() { + switch ($input.units.val()) { + case 'inch': + $input.w.val(Math.round(widthInCm / 2.54 * 100) / 100); + $input.h.val(Math.round(heightInCm / 2.54 * 100) / 100); + break; + + case 'cm': + default: + $input.w.val(widthInCm); + $input.h.val(heightInCm); + break; + } + handleDimensionChange(); + } + + function eventHandlers() { + $input.w.on('input', handleDimensionChange); + $input.h.on('input', handleDimensionChange); + $input.mirror.on('change', handleMirrorChange); + $input.noCrop.on('change', handleNoCropChange); + $input.border.on('change', handleFrameChange); + $input.units.on('change', handleUnitsChange); + + $document + .on('PIE:dragged', function() { + console.log('Dragged the image/dragbar!'); + }) + .on('PIE:needs-dragging', function(e, data) { + console.log('Image needs dragging on: ' + data.axis); + }) + .on('PIE:dragbar-click', function(e, data) { + console.log('Clicked on a dragbar! Axis: ' + data.axis); + }) + .on('PIE:image-start-load', function() { + console.log('Start loading image'); + }) + .on('PIE:image-end-load', function() { + console.log('Image loaded'); + }); + + $window.on('resize', handleResize); + } + + function init() { + + editor = new ImageEditor('canvas-editor', { + type: 'wallpaper', + buttons: { + showThreeD: '3d', + hideThreeD: 'Flat', + showMurals: 'show-murals', + hideMurals: 'hide-murals', + showRulers: 'show-rulers', + hideRulers: 'hide-rulers', + showFullscreen: 'show-fullscreen', + exitFullscreen: 'exit-fullscreen', + }, + dimensions: getWrapperData() + }) + .loadImage(imageUrl, function() { $input.w.trigger('input'); - } + handleResize(); + }); - function handleFrameChange() { + eventHandlers(); + } - if ($(this).val() === 'none') { - editor.canvas.toggle3D(false); - } - - editor.canvas.getViewport().setFrame($(this).val()); - } - - function handleResize() { - var width = $wrapper.width(); - var height = isFullscreen() ? $window.height() : $wrapper.height(); - editor.canvas.resize({width: width, height: height}); - } - - function getWrapperData() { - var $navbar = $('.image-editor__navbar'); - var isFullScreen = isFullscreen(); - var isMobile = $window.width() <= 767; - var windowHeight = window.innerHeight ? window.innerHeight : $window.height(); - var windowWidth = window.innerWidth ? window.innerWidth : $window.width(); - - return { - width: isFullScreen ? windowWidth : (isMobile ? windowWidth : $wrapper.width()), - height: isFullScreen ? windowHeight : (isMobile ? windowHeight - $navbar.height() : $wrapper.height()) - }; - } - - function handleUnitsChange() { - switch ($input.units.val()) { - case 'inch': - $input.w.val(Math.round(widthInCm / 2.54 * 100) / 100); - $input.h.val(Math.round(heightInCm / 2.54 * 100) / 100); - break; - - case 'cm': - default: - $input.w.val(widthInCm); - $input.h.val(heightInCm); - break; - } - handleDimensionChange(); - } - - function eventHandlers() { - $input.w.on('input', handleDimensionChange); - $input.h.on('input', handleDimensionChange); - $input.mirror.on('change', handleMirrorChange); - $input.noCrop.on('change', handleNoCropChange); - $input.border.on('change', handleFrameChange); - $input.units.on('change', handleUnitsChange); - - $document - .on('PIE:dragged', function() { - console.log('Dragged the image/dragbar!'); - }) - .on('PIE:needs-dragging', function(e, data) { - console.log('Image needs dragging on: ' + data.axis); - }) - .on('PIE:dragbar-click', function(e, data) { - console.log('Clicked on a dragbar! Axis: ' + data.axis); - }) - .on('PIE:image-start-load', function() { - console.log('Start loading image'); - }) - .on('PIE:image-end-load', function() { - console.log('Image loaded'); - }); - - $window.on('resize', handleResize); - } - - function init() { - - editor = new ImageEditor('canvas-editor', { - type: 'wallpaper', - buttons: { - showThreeD: '3d', - hideThreeD: 'Flat', - showMurals: 'show-murals', - hideMurals: 'hide-murals', - showRulers: 'show-rulers', - hideRulers: 'hide-rulers', - showFullscreen: 'show-fullscreen', - exitFullscreen: 'exit-fullscreen', - }, - dimensions: getWrapperData() - }) - .loadImage(imageUrl, function() { - $input.w.trigger('input'); - handleResize(); - }); - - eventHandlers(); - } - - init(); + init(); }()); diff --git a/gulpfile.js b/gulpfile.js index a8c2565..a5ceb3d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,5 @@ var gulp = require('gulp'); -var browserify = require('browserify') +var browserify = require('browserify'); var buffer = require('vinyl-buffer'); var rename = require('gulp-rename'); var source = require('vinyl-source-stream'); @@ -7,17 +7,17 @@ var jshint = require('gulp-jshint'); var qunit = require('gulp-qunit'); gulp.task('build', function() { - return browserify('./src/main.js') - .bundle() - .pipe(source('main.js')) - .pipe(buffer()) - .pipe(rename('image-editor.js')) - .pipe(gulp.dest('./dist')); + return browserify('./src/main.js') + .bundle() + .pipe(source('main.js')) + .pipe(buffer()) + .pipe(rename('image-editor.js')) + .pipe(gulp.dest('./dist')); }); gulp.task('test', ['build'], function() { - return gulp.src('./test/index.html') - .pipe(qunit({timeout: 1})); + return gulp.src('./test/index.html') + .pipe(qunit({timeout: 1})); }); gulp.task('lint', function() { @@ -27,7 +27,7 @@ gulp.task('lint', function() { }); gulp.task('watch', function() { - gulp.watch('./src/**/*.js', ['build']); + gulp.watch('./src/**/*.js', ['build']); }); gulp.task('default', ['lint', 'build']); diff --git a/package-lock.json b/package-lock.json index e940dcc..205d4aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,63 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "JSONStream": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", @@ -26,6 +83,12 @@ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", "dev": true }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "ajv": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", @@ -65,6 +128,12 @@ "ansi-wrap": "0.1.0" } }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-red": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", @@ -103,7 +172,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", "dev": true, - "optional": true, "requires": { "sprintf-js": "~1.0.2" } @@ -218,6 +286,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "astw": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", @@ -649,6 +723,12 @@ "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", "dev": true }, + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -686,6 +766,12 @@ "supports-color": "^2.0.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -735,6 +821,15 @@ "glob": "^7.1.1" } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cli-table": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", @@ -744,6 +839,12 @@ "colors": "1.0.3" } }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -943,6 +1044,27 @@ "sha.js": "^2.4.8" } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + } + } + }, "cryptiles": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", @@ -1029,8 +1151,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true, - "optional": true + "dev": true }, "defaults": { "version": "1.0.3", @@ -1163,6 +1284,15 @@ "randombytes": "^2.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dom-serializer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", @@ -1246,6 +1376,12 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "end-of-stream": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", @@ -1310,12 +1446,270 @@ } } }, + "eslint": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.14.1.tgz", + "integrity": "sha512-CyUMbmsjxedx8B0mr79mNOqetvkbij/zrXnFeK2zc3pGRn3/tibjiNAv/3UxFEyfMDjh+ZqTrJrEGBFiGfD5Og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", + "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "dev": true + } + } + }, "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", "dev": true }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, "estraverse": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", @@ -1327,8 +1721,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true, - "optional": true + "dev": true }, "events": { "version": "1.1.1", @@ -1419,6 +1812,17 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1562,8 +1966,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true, - "optional": true + "dev": true }, "fd-slicer": { "version": "1.0.1", @@ -1574,6 +1977,24 @@ "pend": "~1.2.0" } }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1640,6 +2061,23 @@ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1712,6 +2150,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gaze": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", @@ -1857,6 +2301,12 @@ "which": "^1.2.14" } }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, "globule": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", @@ -2305,12 +2755,43 @@ "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", "dev": true }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -2348,6 +2829,85 @@ "source-map": "~0.5.3" } }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "insert-module-globals": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", @@ -2435,6 +2995,12 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", @@ -2462,6 +3028,12 @@ "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", @@ -2591,6 +3163,12 @@ } } }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", @@ -2663,6 +3241,12 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2775,7 +3359,6 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, - "optional": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -3100,6 +3683,12 @@ "mime-db": "~1.30.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", @@ -3232,6 +3821,12 @@ } } }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -3284,6 +3879,18 @@ "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==", "dev": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -3377,6 +3984,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -3409,7 +4025,6 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, - "optional": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -3448,12 +4063,27 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "dev": true }, + "parent-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", + "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parents": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", @@ -3511,6 +4141,18 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -3850,6 +4492,12 @@ } } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -3926,12 +4574,28 @@ "global-modules": "^1.0.0" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -3948,6 +4612,31 @@ "align-text": "^0.1.1" } }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "ripemd160": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", @@ -3958,6 +4647,24 @@ "inherits": "^2.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -3973,6 +4680,12 @@ "ret": "~0.1.10" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", @@ -4028,6 +4741,21 @@ "sha.js": "~2.4.4" } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -4052,6 +4780,34 @@ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -4228,8 +4984,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true, - "optional": true + "dev": true }, "sshpk": { "version": "1.13.1", @@ -4317,6 +5072,33 @@ "readable-stream": "^2.0.2" } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -4378,6 +5160,82 @@ "acorn": "^4.0.3" } }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "string-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.0.0.tgz", + "integrity": "sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.0.0" + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -4424,6 +5282,15 @@ "process": "~0.11.0" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -4497,6 +5364,12 @@ "integrity": "sha1-bCZ4exhT8TcWNGIsHIC8RAJsXXA=", "dev": true }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -4658,6 +5531,23 @@ } } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -4891,6 +5781,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index fd6f1ac..c88ceba 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,17 @@ }, "devDependencies": { "browserify": "^13.1.1", + "eslint": "^5.14.1", "gulp": "^3.9.0", + "gulp-jshint": "^2.0.4", + "gulp-qunit": "^1.5.0", + "gulp-rename": "^1.2.2", "jshint": "^2.9.5", "qunit": "^1.0.0", - "gulp-jshint": "^2.0.4", - "gulp-rename": "^1.2.2", "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^1.1.0", - "gulp-qunit": "^1.5.0" + "vinyl-source-stream": "^1.1.0" + }, + "scripts": { + "lint": "eslint gulpfile.js 'examples/**/*.js' 'test/unit/**/*.js' 'src/**/*.js'" } } diff --git a/src/.eslintrc b/src/.eslintrc new file mode 100644 index 0000000..341b8b8 --- /dev/null +++ b/src/.eslintrc @@ -0,0 +1,7 @@ +{ + "rules": { + "no-console":[ + "error" + ] + } +} diff --git a/src/3dHandler.js b/src/3dHandler.js index 24bf526..0a9f72b 100644 --- a/src/3dHandler.js +++ b/src/3dHandler.js @@ -6,102 +6,102 @@ * @param {canvas} canvas */ function ThreeDHandler(canvas) { - var _overlay = new fabric.Group(); - var _image; + var _overlay = new fabric.Group(); + var _image; - function init() { - _overlay - .set({ - visible: false, - left: 0 - }) - .addWithUpdate(new fabric.Rect({ - // Width is made bigger as this works better with resizing the editor - width: canvas.width * 2, - height: canvas.height, - top: 0, - left: 0, - fill: canvas.backgroundColor, - })); + function init() { + _overlay + .set({ + visible: false, + left: 0 + }) + .addWithUpdate(new fabric.Rect({ + // Width is made bigger as this works better with resizing the editor + width: canvas.width * 2, + height: canvas.height, + top: 0, + left: 0, + fill: canvas.backgroundColor, + })); - canvas.add(_overlay); - } + canvas.add(_overlay); + } - init(); + init(); - /** + /** * Disables the 3d image by removing visibility * @return {ThreeDHandler} */ - this.disable = function () { - _overlay.setVisible(false).canvas.resize(); - return this; - }; + this.disable = function () { + _overlay.setVisible(false).canvas.resize(); + return this; + }; - /** + /** * Enables the 3d image by setting the width and visibility of the overlay and moving elements which * needs to be visible to the front. * @return {ThreeDHandler} */ - this.enable = function () { - _overlay - .set({ - width: canvas.width, - visible: true - }).bringToFront(); + this.enable = function () { + _overlay + .set({ + width: canvas.width, + visible: true + }).bringToFront(); - canvas.getButtonMenu().bringToFront(); - canvas.renderAll(); - return this; - }; + canvas.getButtonMenu().bringToFront(); + canvas.renderAll(); + return this; + }; - /** + /** * Checks if 3d mode is enabled/visible. * @returns {boolean} */ - this.isEnabled = function () { - return _overlay.visible; - }; + this.isEnabled = function () { + return _overlay.visible; + }; - /** + /** * Refreshes the image. This is mostly done upon resize of the window */ - this.refreshImage = function() { - _overlay.set({ - width: canvas.width, - }); + this.refreshImage = function() { + _overlay.set({ + width: canvas.width, + }); - this.applyImage(); - }; + this.applyImage(); + }; - /** + /** * (Re)adds the new/existing image with new configuration to the overlay. * @param {img} */ - this.applyImage = function(img) { - img = img || _image; + this.applyImage = function(img) { + img = img || _image; - _overlay - .remove(_image) - .add(_image = canvas.getResizedImage(img)); - }; + _overlay + .remove(_image) + .add(_image = canvas.getResizedImage(img)); + }; - /** + /** * Sets the image and enables 3d mode. * @param {img} * @return {ThreeDHandler} */ - this.setImage = function (img) { - img.set({ - // Image should be about 20px lower than the center (because of the buttons) - top: 20, - originX: 'center', - originY: 'center', - }); + this.setImage = function (img) { + img.set({ + // Image should be about 20px lower than the center (because of the buttons) + top: 20, + originX: 'center', + originY: 'center', + }); - this.applyImage(img); - return this.enable(); - }; + this.applyImage(img); + return this.enable(); + }; } diff --git a/src/ApertureHandler.js b/src/ApertureHandler.js index e193230..f3db066 100644 --- a/src/ApertureHandler.js +++ b/src/ApertureHandler.js @@ -6,94 +6,94 @@ * @param {canvas} canvas */ function ApertureHandler(canvas) { - var _items = {x: [], y: []}; + var _items = {x: [], y: []}; - function init() { - var bounds = canvas; - var xRect = new fabric.Rect({ - width: bounds.width, - height: bounds.height / 2, - fill: canvas.backgroundColor, - opacity: 0.7, - }); + function init() { + var bounds = canvas; + var xRect = new fabric.Rect({ + width: bounds.width, + height: bounds.height / 2, + fill: canvas.backgroundColor, + opacity: 0.7, + }); - var yRect = xRect.clone().set({ - width: bounds.width / 2, - height: bounds.height - }); + var yRect = xRect.clone().set({ + width: bounds.width / 2, + height: bounds.height + }); - _items.x = [].concat([xRect, xRect.clone()]); - _items.y= [].concat([yRect, yRect.clone()]); + _items.x = [].concat([xRect, xRect.clone()]); + _items.y= [].concat([yRect, yRect.clone()]); - [].concat(_items.x, _items.y).forEach(function (o) { - canvas.add(o); - }); - canvas.renderAll(); - } - init(); + [].concat(_items.x, _items.y).forEach(function (o) { + canvas.add(o); + }); + canvas.renderAll(); + } + init(); - /** + /** * Applies configuration to the apertures apertures on the viewport * @param {string} axis * @param {viewport} viewport */ - this.apply = function (axis, viewport) { - this.getApertures(axis).forEach(function (o) { - o.visible = false; - }); + this.apply = function (axis, viewport) { + this.getApertures(axis).forEach(function (o) { + o.visible = false; + }); - var active = this.getApertures(axis === 'x' ? 'y' : 'x'); + var active = this.getApertures(axis === 'x' ? 'y' : 'x'); - active.forEach(function (o) { - o.visible = true; - }); + active.forEach(function (o) { + o.visible = true; + }); - active[0].width= active[1].width = canvas.width; - active[0].height = active[1].height = canvas.height; + active[0].width= active[1].width = canvas.width; + active[0].height = active[1].height = canvas.height; - if (axis === 'y') { - active[0].top = viewport.top - active[0].height + 0.5; - active[1].top = viewport.top + viewport.height - 0.5; - } else { - active[0].left = viewport.left - active[0].width + 0.5; - active[1].left = viewport.left + viewport.width - 0.5; - } + if (axis === 'y') { + active[0].top = viewport.top - active[0].height + 0.5; + active[1].top = viewport.top + viewport.height - 0.5; + } else { + active[0].left = viewport.left - active[0].width + 0.5; + active[1].left = viewport.left + viewport.width - 0.5; + } - this.getApertures().forEach(function (o) { - o.setCoords(); - }); + this.getApertures().forEach(function (o) { + o.setCoords(); + }); - canvas.renderAll(); - }; + canvas.renderAll(); + }; - /** + /** * Gets the apertures on specified axis. If no axis is provided, both x and y are returned. * @param {string} axis * @returns {Array} */ - this.getApertures = function (axis) { - return axis ? _items[axis] : [].concat(_items.x, _items.y); - }; + this.getApertures = function (axis) { + return axis ? _items[axis] : [].concat(_items.x, _items.y); + }; - /** + /** * Sets transparency of the apertures depending on the crop status * @param {boolean} apply * @returns {ApertureHandler} */ - this.setTransparent = function (apply) { - this.getApertures().forEach(function (o) { - o.opacity = apply ? 0.7 : 1; - }); + this.setTransparent = function (apply) { + this.getApertures().forEach(function (o) { + o.opacity = apply ? 0.7 : 1; + }); - canvas.renderAll(); - return this; - }; + canvas.renderAll(); + return this; + }; - this.disable = function () { - this.getApertures().forEach(function (o) { - o.visible = false; - }); - }; + this.disable = function () { + this.getApertures().forEach(function (o) { + o.visible = false; + }); + }; } module.exports = ApertureHandler; diff --git a/src/ButtonMenu.js b/src/ButtonMenu.js index 3714b7c..a9bf6a2 100644 --- a/src/ButtonMenu.js +++ b/src/ButtonMenu.js @@ -9,143 +9,143 @@ var TextButton = require('./TextButton'); * @param {Object=} settings */ function ButtonMenu(canvas, settings) { - var _textButtons = []; - var _width = 0; + var _textButtons = []; + var _width = 0; - /** + /** * Calculates the width of all contained items * @return {Number} */ - function setWidth() { - var startWidth = 0; - _textButtons.forEach(function(textButton) { - startWidth += textButton.width; - }); - _width = startWidth += settings.margin * (_textButtons.length - 1); - } + function setWidth() { + var startWidth = 0; + _textButtons.forEach(function(textButton) { + startWidth += textButton.width; + }); + _width = startWidth += settings.margin * (_textButtons.length - 1); + } - /** + /** * Adds items to the button-menu. * @param {String} text * @param {Function} callback * @return {ButtonMenu} */ - this.addItem = function(id, text, callback, isActive) { - _textButtons.push( - new TextButton(id, text, settings, isActive) - .onClick(callback) - .set({__group: this}) - ); + this.addItem = function(id, text, callback, isActive) { + _textButtons.push( + new TextButton(id, text, settings, isActive) + .onClick(callback) + .set({__group: this}) + ); - return this; - }; + return this; + }; - /** + /** * Brings the buttons to the front inside the canvas * @return {ButtonMenu} */ - this.bringToFront = function() { - _textButtons.forEach(function(textButton) { - textButton.bringToFront(); - }); - return this; - }; + this.bringToFront = function() { + _textButtons.forEach(function(textButton) { + textButton.bringToFront(); + }); + return this; + }; - /** + /** * Gets all buttons inside the menu. * @return {Array} */ - this.getItems = function() { - return _textButtons; - }; + this.getItems = function() { + return _textButtons; + }; - /** + /** * Gets the full width of the buttonMenu. * @return {Number} */ - this.getWidth = function() { - return _width; - }; + this.getWidth = function() { + return _width; + }; - /** + /** * Sets the button with id=buttonId to active/not active mode */ - this.setButtonActive = function(buttonId, isActive) { - _textButtons.forEach(function (button) { - if (button.getId() === buttonId) { - button.setActive(isActive); - } - }); - }; + this.setButtonActive = function(buttonId, isActive) { + _textButtons.forEach(function (button) { + if (button.getId() === buttonId) { + button.setActive(isActive); + } + }); + }; - /** + /** * Sets the button with id=buttonId to disabled/enabled mode */ - this.setButtonDisabled = function(buttonId, isDisabled) { - _textButtons.forEach(function (button) { - if (button.getId() === buttonId) { - button.setDisabled(isDisabled); - } - }); - }; + this.setButtonDisabled = function(buttonId, isDisabled) { + _textButtons.forEach(function (button) { + if (button.getId() === buttonId) { + button.setDisabled(isDisabled); + } + }); + }; - /** + /** * Hides the buttons */ - this.hide = function() { - _textButtons.forEach(function(textButton) { - textButton.set({ - opacity: 0, - disabled: true - }); - }); - }; + this.hide = function() { + _textButtons.forEach(function(textButton) { + textButton.set({ + opacity: 0, + disabled: true + }); + }); + }; - /** + /** * Shows all the buttons */ - this.show = function() { - _textButtons.forEach(function(textButton) { - textButton.set({ - opacity: 1, - disabled: false - }); - }); - }; + this.show = function() { + _textButtons.forEach(function(textButton) { + textButton.set({ + opacity: 1, + disabled: false + }); + }); + }; - /** + /** * Recalculate boundaries and add all items to canvas if required * @return {ButtonMenu} */ - this.render = function() { - setWidth(); + this.render = function() { + setWidth(); - var start = canvas.width / 2 - this.getWidth() / 2; - var currPos = Math.round(start); + var start = canvas.width / 2 - this.getWidth() / 2; + var currPos = Math.round(start); - _textButtons.forEach(function(textButton) { - textButton - .set({ - top: 10, - left: currPos - }) - .setCoords(); + _textButtons.forEach(function(textButton) { + textButton + .set({ + top: 10, + left: currPos + }) + .setCoords(); - if (!textButton.canvas) { - textButton.addTo(canvas); - } - currPos += Math.round(textButton.width + settings.margin); + if (!textButton.canvas) { + textButton.addTo(canvas); + } + currPos += Math.round(textButton.width + settings.margin); - // Disable moving of text-buttons - textButton.lockMovementX = textButton.lockMovementY = true; - }); + // Disable moving of text-buttons + textButton.lockMovementX = textButton.lockMovementY = true; + }); - canvas.renderAll(); + canvas.renderAll(); - this.show(); + this.show(); - return this; - }; + return this; + }; } module.exports = ButtonMenu; diff --git a/src/Canvas.js b/src/Canvas.js index 6731b1a..ba061ed 100644 --- a/src/Canvas.js +++ b/src/Canvas.js @@ -19,221 +19,221 @@ var $document = $(document); * Fe. getDragbars method can be called from most places as the Canvas class is available in most places. */ var Canvas = fabric.util.createClass(fabric.Canvas, { - initialize: function (id, dimensions) { - this.callSuper('initialize', id, { - enableRetinaScaling: true, - renderOnAddRemove: false, - // Allow touch scrolling on touch-devices larger than mobile screen sizes. - allowTouchScrolling: !util.isMobile(), - stateful: false, - backgroundColor: '#ededed', - preserveObjectStacking: true, - selection: false, - width: dimensions.width, - height: dimensions.height - }); - }, + initialize: function (id, dimensions) { + this.callSuper('initialize', id, { + enableRetinaScaling: true, + renderOnAddRemove: false, + // Allow touch scrolling on touch-devices larger than mobile screen sizes. + allowTouchScrolling: !util.isMobile(), + stateful: false, + backgroundColor: '#ededed', + preserveObjectStacking: true, + selection: false, + width: dimensions.width, + height: dimensions.height + }); + }, - resize: function (args) { - args = args || { height: this.height, width: this.width}; - if (!args.width || !args.height) { - return; - } + resize: function (args) { + args = args || { height: this.height, width: this.width}; + if (!args.width || !args.height) { + return; + } - this.setHeight(args.height); - this.setWidth(args.width); - this.getButtonMenu().render(); - if (this.get3dHandler().isEnabled()) { - this.get3dHandler().refreshImage(); - } else { - this.refreshImage(this.getResizedImage(this.getImage())); - this.getViewport().reset(); - } - this.sendToBack(this.getImage()); - this.getImage().center(); - this.getDragbars().resetPosition(); - this.renderAll(); - }, + this.setHeight(args.height); + this.setWidth(args.width); + this.getButtonMenu().render(); + if (this.get3dHandler().isEnabled()) { + this.get3dHandler().refreshImage(); + } else { + this.refreshImage(this.getResizedImage(this.getImage())); + this.getViewport().reset(); + } + this.sendToBack(this.getImage()); + this.getImage().center(); + this.getDragbars().resetPosition(); + this.renderAll(); + }, - disableScroll: function() { - this.set({ - allowTouchScrolling: false - }); - return this; - }, + disableScroll: function() { + this.set({ + allowTouchScrolling: false + }); + return this; + }, - enableScroll: function() { - this.set({ - allowTouchScrolling: true - }); - return this; - }, + enableScroll: function() { + this.set({ + allowTouchScrolling: true + }); + return this; + }, - get3dHandler: function () { - return this.__3dHandler || + get3dHandler: function () { + return this.__3dHandler || (this.__3dHandler = new ThreeDHandler(this)); - }, + }, - /** + /** * @return {String} */ - get3dUrl: function () { - var imageData = this.getImageData().getData(); - var params = [ - 'h=400', - 'canvas[edge]=' + imageData.edge, - 'crop[w]=' + imageData.width, - 'crop[h]=' + imageData.height, - 'crop[x]=' + imageData.x, - 'crop[y]=' + imageData.y, - ]; + get3dUrl: function () { + var imageData = this.getImageData().getData(); + var params = [ + 'h=400', + 'canvas[edge]=' + imageData.edge, + 'crop[w]=' + imageData.width, + 'crop[h]=' + imageData.height, + 'crop[x]=' + imageData.x, + 'crop[y]=' + imageData.y, + ]; - if (imageData.mirrored) { - params.push('mirror=1'); - } + if (imageData.mirrored) { + params.push('mirror=1'); + } - return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&'); - }, + return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&'); + }, - getApertures: function () { - return this.__aperturehandler || + getApertures: function () { + return this.__aperturehandler || (this.__aperturehandler = new ApertureHandler(this)); - }, + }, - /** + /** * * @returns {DragbarHandler} */ - getDragbars: function () { - return this.__dragbars || + getDragbars: function () { + return this.__dragbars || (this.__dragbars = new DragbarHandler(this)); - }, + }, - /** + /** * @return {fabric.Image} */ - getImage: function () { - return this.__image; - }, + getImage: function () { + return this.__image; + }, - /** + /** * @return {MirrorHandler} */ - getMirror: function () { - return this.__mirror || + getMirror: function () { + return this.__mirror || (this.__mirror = new MirrorHandler(this.getImage())); - }, + }, - /** + /** * @return {MirrorHandler} */ - getImageData: function () { - return this.__imageData || + getImageData: function () { + return this.__imageData || (this.__imageData = new ImageDataHandler(this.getImage())); - }, + }, - /** + /** * @return {Viewport} */ - getViewport: function () { - return this.__viewport || + getViewport: function () { + return this.__viewport || (this.__viewport = new Viewport(this)); - }, + }, - /** + /** * Gets the menu for this instance * @returns {ButtonMenu} */ - getButtonMenu: function (settings) { - if (!this.__buttonMenu) { - var defaults = config.buttonMenu[this.__type]; - this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings)); - } - return this.__buttonMenu; - }, + getButtonMenu: function (settings) { + if (!this.__buttonMenu) { + var defaults = config.buttonMenu[this.__type]; + this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings)); + } + return this.__buttonMenu; + }, - /** + /** * Reloads the 3D view, if it is present * @return {Canvas} */ - refresh3dView: function () { - if (this.get3dHandler().isEnabled()) { - this.toggle3D(true); - } - return this; - }, + refresh3dView: function () { + if (this.get3dHandler().isEnabled()) { + this.toggle3D(true); + } + return this; + }, - /** + /** * @return {Canvas} */ - removeImage: function () { - if (!this.__image) { - return this; - } - this.__imageData = null; - return this.remove(this.__image); - }, + removeImage: function () { + if (!this.__image) { + return this; + } + this.__imageData = null; + return this.remove(this.__image); + }, - refreshImage: function(img) { - this.__image = img; - return this; - }, + refreshImage: function(img) { + this.__image = img; + return this; + }, - /** + /** * @param {fabric.Image} img * @return {Canvas} */ - setImage: function (img) { - this.removeImage(); - this.__image = img; - this.__image.__dragged = false; - this.__image.__cropped = false; - this.__image.addTo(this).center().on('mousedown', function () { - img.canvas.getApertures().setTransparent(true); - }).setCoords(); - this.getViewport().reset(); - return this; - }, + setImage: function (img) { + this.removeImage(); + this.__image = img; + this.__image.__dragged = false; + this.__image.__cropped = false; + this.__image.addTo(this).center().on('mousedown', function () { + img.canvas.getApertures().setTransparent(true); + }).setCoords(); + this.getViewport().reset(); + return this; + }, - getResizedImage: function(img) { - // Calculate maxHeight and maxWidth of the 3d image - // and scale the image accoring to those values - var maxHeight = this.getHeight() - 100; - var maxWidth = this.getWidth() - 100; + getResizedImage: function(img) { + // Calculate maxHeight and maxWidth of the 3d image + // and scale the image accoring to those values + var maxHeight = this.getHeight() - 100; + var maxWidth = this.getWidth() - 100; - img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height); - img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX); + img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height); + img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX); - return img; - }, + return img; + }, - toggle3D: function (showAs3d) { + toggle3D: function (showAs3d) { - this.getButtonMenu().setButtonActive('toggle3d', showAs3d); + this.getButtonMenu().setButtonActive('toggle3d', showAs3d); - if (!showAs3d) { - return this.get3dHandler().disable(); + if (!showAs3d) { + return this.get3dHandler().disable(); + } + + $document.trigger('PIE:image-start-load'); + + $.ajax({ + url: this.get3dUrl(), + crossDomain: true, + type: 'HEAD', + cache: true, + }).done(function() { + fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) { + if (!img._element) { + $document.trigger('PIE:image-error-load'); + return; } - $document.trigger('PIE:image-start-load'); - - $.ajax({ - url: this.get3dUrl(), - crossDomain: true, - type: "HEAD", - cache: true, - }).done(function() { - fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) { - if (!img._element) { - $document.trigger('PIE:image-error-load'); - return; - } - - this.get3dHandler().setImage(img); - $document.trigger('PIE:image-end-load'); - }.bind(this)); - }.bind(this)); - }, + this.get3dHandler().setImage(img); + $document.trigger('PIE:image-end-load'); + }.bind(this)); + }.bind(this)); + }, }); module.exports = Canvas; diff --git a/src/DragHandle.js b/src/DragHandle.js index be55c74..34a8c4e 100644 --- a/src/DragHandle.js +++ b/src/DragHandle.js @@ -5,145 +5,145 @@ var config = require('./config'); var util = require('./util'); var DragHandle = function (handler) { - var _currentAxis; - var _dragHandle; - var _clickHandle = false; - var _movedHandle; + var _currentAxis; + var _dragHandle; + var _clickHandle = false; + var _movedHandle; - // Event declarations - var events = { - mouseDown: function () { - if(handler.canvas.__type !== 'wallpaper') { - _dragHandle = true; - } + // Event declarations + var events = { + mouseDown: function () { + if(handler.canvas.__type !== 'wallpaper') { + _dragHandle = true; + } - _clickHandle = true; - _currentAxis = this.axis; - handler.canvas.getImage().trigger('mousedown'); - }, - mouseUp: function () { - if (!_dragHandle && !_clickHandle) { - return; - } + _clickHandle = true; + _currentAxis = this.axis; + handler.canvas.getImage().trigger('mousedown'); + }, + mouseUp: function () { + if (!_dragHandle && !_clickHandle) { + return; + } - if (_clickHandle) { - $(document).trigger('PIE:dragbar-click', { axis: _currentAxis }); - _clickHandle = false; - } + if (_clickHandle) { + $(document).trigger('PIE:dragbar-click', { axis: _currentAxis }); + _clickHandle = false; + } - _dragHandle = false; - _movedHandle = false; - _currentAxis = null; - util.MouseMetrics.deletePreviousMouseData(); - handler.canvas.getImage().trigger('mouseup'); - }, - mouseMove: function (e) { - if (!_dragHandle) { - return; - } + _dragHandle = false; + _movedHandle = false; + _currentAxis = null; + util.MouseMetrics.deletePreviousMouseData(); + handler.canvas.getImage().trigger('mouseup'); + }, + mouseMove: function (e) { + if (!_dragHandle) { + return; + } - //Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case - var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX); - var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY); + //Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case + var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX); + var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY); - // We're using a polyfill to calculate moude/touch movement if the browser/device - // does not support movementX/movementY. - var previousMouseData = util.MouseMetrics.previousMouseData; - var movement = { - x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0), - y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0) - }; - util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY}); - _movedHandle = true; + // We're using a polyfill to calculate moude/touch movement if the browser/device + // does not support movementX/movementY. + var previousMouseData = util.MouseMetrics.previousMouseData; + var movement = { + x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0), + y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0) + }; + util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY}); + _movedHandle = true; - if (_currentAxis === 'x') { - handler.canvas.getImage().left -= movement.x; - } else { - handler.canvas.getImage().top -= movement.y; - } - // Trigger moving for image, to stay within bounds - handler.canvas.getImage().setCoords().trigger('moving'); - handler.canvas.renderAll(); - } - }; + if (_currentAxis === 'x') { + handler.canvas.getImage().left -= movement.x; + } else { + handler.canvas.getImage().top -= movement.y; + } + // Trigger moving for image, to stay within bounds + handler.canvas.getImage().setCoords().trigger('moving'); + handler.canvas.renderAll(); + } + }; - function getRect(text, width) { - var txt = new fabric.Text(text, config.dragHandle.text); - var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, { - width: width, - })); + function getRect(text, width) { + var txt = new fabric.Text(text, config.dragHandle.text); + var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, { + width: width, + })); - return new fabric.Group([rect, txt]).set({ - evented: false, - }); + return new fabric.Group([rect, txt]).set({ + evented: false, + }); + } + + this.getCanvas = function () { + return handler.canvas; + }; + + this.getHandles = function () { + if (!this.__handles) { + return []; } - this.getCanvas = function () { - return handler.canvas; + return [].concat(this.__handles.x, this.__handles.y); + }; + + this.setHandlePosition = function() { + this.__handles.y.set({left: handler.getTracks().y.left}).setCoords(); + this.__handles.x.set({top: handler.getTracks().x.top}).setCoords(); + return this; + }; + + this.init = function () { + var canvas = this.getCanvas(); + var viewport = canvas.getViewport(); + var viewportData = viewport.getData(); + var frameHandler = viewport.getFrameHandler(); + var tracks = handler.getTracks(); + + if (this.__handles) { + this.getCanvas().remove(this.__handles.x); + this.getCanvas().remove(this.__handles.y); + } + + var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels. + var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm. + var frameType = frameHandler.getFrameType(); + + var handleWidth = viewportData.width; + var handleHeight = viewportData.height; + var widthToDisplay = viewportData.dim.width; + var heightToDisplay = viewportData.dim.height; + var unit = viewportData.dim.units; + + if (frameType == 'image') { + var doubleRealFrameWidth = realFrameWidth * 2; + handleWidth -= frameWidth * 2; + handleHeight -= frameWidth * 2; + widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; + heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; + } + + this.__handles = { + x: getRect(widthToDisplay + ' ' + unit, handleWidth), + y: getRect(heightToDisplay + ' ' + unit, handleHeight) }; - this.getHandles = function () { - if (!this.__handles) { - return []; - } + this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords(); + this.__handles.y.addTo(this.getCanvas()) + .setAngle(-90) + .centerV().set({ left: tracks.y.left }) + .setCoords(); - return [].concat(this.__handles.x, this.__handles.y); - }; + this.getCanvas() + .on('mouse:move', events.mouseMove) + .on('mouse:up', events.mouseUp); - this.setHandlePosition = function() { - this.__handles.y.set({left: handler.getTracks().y.left}).setCoords(); - this.__handles.x.set({top: handler.getTracks().x.top}).setCoords(); - return this; - }; - - this.init = function () { - var canvas = this.getCanvas(); - var viewport = canvas.getViewport(); - var viewportData = viewport.getData(); - var frameHandler = viewport.getFrameHandler(); - var tracks = handler.getTracks(); - - if (this.__handles) { - this.getCanvas().remove(this.__handles.x); - this.getCanvas().remove(this.__handles.y); - } - - var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels. - var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm. - var frameType = frameHandler.getFrameType(); - - var handleWidth = viewportData.width; - var handleHeight = viewportData.height; - var widthToDisplay = viewportData.dim.width; - var heightToDisplay = viewportData.dim.height; - var unit = viewportData.dim.units; - - if (frameType == 'image') { - var doubleRealFrameWidth = realFrameWidth * 2; - handleWidth -= frameWidth * 2; - handleHeight -= frameWidth * 2; - widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; - heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth; - } - - this.__handles = { - x: getRect(widthToDisplay + ' ' + unit, handleWidth), - y: getRect(heightToDisplay + ' ' + unit, handleHeight) - }; - - this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords(); - this.__handles.y.addTo(this.getCanvas()) - .setAngle(-90) - .centerV().set({ left: tracks.y.left }) - .setCoords(); - - this.getCanvas() - .on('mouse:move', events.mouseMove) - .on('mouse:up', events.mouseUp); - - tracks.x.on('mousedown', events.mouseDown.bind(tracks.x)); - tracks.y.on('mousedown', events.mouseDown.bind(tracks.y)); - }; + tracks.x.on('mousedown', events.mouseDown.bind(tracks.x)); + tracks.y.on('mousedown', events.mouseDown.bind(tracks.y)); + }; }; module.exports = DragHandle; diff --git a/src/DragbarHandler.js b/src/DragbarHandler.js index caeae2e..44bac3f 100644 --- a/src/DragbarHandler.js +++ b/src/DragbarHandler.js @@ -5,127 +5,127 @@ var DragHandle = require('./DragHandle'); var config = require('./config'); function DragbarHandler(canvas) { - var _dragbars = { - x: null, - y: null - }; + var _dragbars = { + x: null, + y: null + }; - /** + /** * @return {DragbarHandler} */ - this.apply = function () { - if (!canvas.__hasDragbars) { - this.init(); - canvas.__hasDragbars = true; - } - this.sync(); + this.apply = function () { + if (!canvas.__hasDragbars) { + this.init(); + canvas.__hasDragbars = true; + } + this.sync(); - if (!this.__handles) { - this.__handles = new DragHandle(this); - } + if (!this.__handles) { + this.__handles = new DragHandle(this); + } - this.__handles.init(); + this.__handles.init(); - this.bringToFront(); + this.bringToFront(); - canvas.renderAll(); - return this; - }; + canvas.renderAll(); + return this; + }; - this.canvas = canvas; + this.canvas = canvas; - this.bringToFront = function() { - [].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) { - dragbar.bringToFront(); - }); + this.bringToFront = function() { + [].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) { + dragbar.bringToFront(); + }); - this.__handles.getHandles().forEach(function (handle) { - handle.bringToFront(); - }); - }; - /** + this.__handles.getHandles().forEach(function (handle) { + handle.bringToFront(); + }); + }; + /** * Removes dragbars from canvas */ - this.clear = function () { - canvas - .remove(_dragbars.x) - .remove(_dragbars.y) - .renderAll(); - return this; - }; + this.clear = function () { + canvas + .remove(_dragbars.x) + .remove(_dragbars.y) + .renderAll(); + return this; + }; - this.getTracks = function () { - return _dragbars; - }; + this.getTracks = function () { + return _dragbars; + }; - this.resetPosition = function() { - if (!_dragbars.y || !_dragbars.x) { - return this; - } + this.resetPosition = function() { + if (!_dragbars.y || !_dragbars.x) { + return this; + } - _dragbars.y.set({ - left: canvas.width - 30, - height: canvas.getImage().height * canvas.getImage().scaleY, - }).setCoords(); + _dragbars.y.set({ + left: canvas.width - 30, + height: canvas.getImage().height * canvas.getImage().scaleY, + }).setCoords(); - _dragbars.x.set({ - top: canvas.height - 30, - width: canvas.getImage().width * canvas.getImage().scaleY, - }).setCoords(); + _dragbars.x.set({ + top: canvas.height - 30, + width: canvas.getImage().width * canvas.getImage().scaleY, + }).setCoords(); - this.__handles.setHandlePosition(); + this.__handles.setHandlePosition(); - return this; - }; + return this; + }; - /** + /** * @return {DragbarHandler} */ - this.init = function () { - this.clear(); - var typeIsWallpaper = canvas.__type === 'wallpaper'; + this.init = function () { + this.clear(); + var typeIsWallpaper = canvas.__type === 'wallpaper'; - _dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { - axis: 'x', - width: canvas.getImage().width * canvas.getImage().scaleY, - height: config.dragBar.size, - lockMovementY: true, - // Movement should also be disabled when the user is on wallpaper (repeating paterns) - lockMovementX: typeIsWallpaper, - selectable: true, - hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', - moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', - })) - .addTo(canvas) - .centerH().set({ top: canvas.height - 30 }).setCoords(); + _dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { + axis: 'x', + width: canvas.getImage().width * canvas.getImage().scaleY, + height: config.dragBar.size, + lockMovementY: true, + // Movement should also be disabled when the user is on wallpaper (repeating paterns) + lockMovementX: typeIsWallpaper, + selectable: true, + hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', + moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', + })) + .addTo(canvas) + .centerH().set({ top: canvas.height - 30 }).setCoords(); - _dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { - axis: 'y', - width: config.dragBar.size, - height: canvas.getImage().height * canvas.getImage().scaleY, - lockMovementX: true, - // Movement should also be disabled when the user is on wallpaper (repeating paterns) - lockMovementY: typeIsWallpaper, - selectable: true, - hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', - moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', - })) - .addTo(canvas) - .set({ left: canvas.width - 30 }).setCoords(); + _dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { + axis: 'y', + width: config.dragBar.size, + height: canvas.getImage().height * canvas.getImage().scaleY, + lockMovementX: true, + // Movement should also be disabled when the user is on wallpaper (repeating paterns) + lockMovementY: typeIsWallpaper, + selectable: true, + hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', + moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', + })) + .addTo(canvas) + .set({ left: canvas.width - 30 }).setCoords(); - canvas.getImage().on('moving', this.sync); + canvas.getImage().on('moving', this.sync); - return this; - }; + return this; + }; - /** + /** * @return {DragbarHandler} */ - this.sync = function () { - _dragbars.x.set({left: canvas.getImage().left}).setCoords(); - _dragbars.y.set({top: canvas.getImage().top}).setCoords(); - return this; - }; + this.sync = function () { + _dragbars.x.set({left: canvas.getImage().left}).setCoords(); + _dragbars.y.set({top: canvas.getImage().top}).setCoords(); + return this; + }; } module.exports = DragbarHandler; diff --git a/src/Draggable.js b/src/Draggable.js index 6d0a91f..47af763 100644 --- a/src/Draggable.js +++ b/src/Draggable.js @@ -7,69 +7,69 @@ var util = require('./util'); * @param {fabric.Rect} boundingRect */ function Draggable(img, boundingRect) { - var _bounds = boundingRect; - var _img = img; + var _bounds = boundingRect; + var _img = img; - /** + /** * Triggers when object is moved */ - function onMove() { - /*jshint validthis: true */ - if (!this.__dragging) { - //Trigger start-drag on first 'moving' trigger. - $(document).trigger('PIE:start-drag'); - this.__dragging = true; - } - this.canvas.disableScroll(); - - util.setPositionInside(this, _bounds); + function onMove() { + /*jshint validthis: true */ + if (!this.__dragging) { + //Trigger start-drag on first 'moving' trigger. + $(document).trigger('PIE:start-drag'); + this.__dragging = true; } + this.canvas.disableScroll(); - this.onMouseUp = function () { - if (this.__dragging) { - this.__dragged = true; - this.__dragging = false; - this.canvas.getImageData().setCropData(); - if (!util.isMobile()) { - this.canvas.enableScroll(); - } - // Trigger event to tell the image has been dragged. - $(document).trigger('PIE:dragged'); - } - if (this.__dragged) { - // Always set aperture transparency to false even if image hasn't been dragged this click. - this.canvas.getApertures().setTransparent(false); - } - this.canvas.renderAll(); - }; + util.setPositionInside(this, _bounds); + } - // Attach onMove event to image - _img.on('moving', onMove); + this.onMouseUp = function () { + if (this.__dragging) { + this.__dragged = true; + this.__dragging = false; + this.canvas.getImageData().setCropData(); + if (!util.isMobile()) { + this.canvas.enableScroll(); + } + // Trigger event to tell the image has been dragged. + $(document).trigger('PIE:dragged'); + } + if (this.__dragged) { + // Always set aperture transparency to false even if image hasn't been dragged this click. + this.canvas.getApertures().setTransparent(false); + } + this.canvas.renderAll(); + }; - // Attach mouse up event to canvas, can't do mouse up events on canvas objects. - _img.canvas.on('mouse:up', this.onMouseUp.bind(_img)); + // Attach onMove event to image + _img.on('moving', onMove); - /** + // Attach mouse up event to canvas, can't do mouse up events on canvas objects. + _img.canvas.on('mouse:up', this.onMouseUp.bind(_img)); + + /** * @param {fabric.Rect} localBoundingRect * @return {Draggable} */ - this.enable = function (localBoundingRect) { - if (localBoundingRect) { - _bounds = localBoundingRect; - } + this.enable = function (localBoundingRect) { + if (localBoundingRect) { + _bounds = localBoundingRect; + } - // @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect - if (_img.canvas.getViewport().getData().axis === 'x') { - _bounds.top.min = _bounds.top.max = _img.top; - } else { - _bounds.left.min = _bounds.left.max = _img.left; - } + // @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect + if (_img.canvas.getViewport().getData().axis === 'x') { + _bounds.top.min = _bounds.top.max = _img.top; + } else { + _bounds.left.min = _bounds.left.max = _img.left; + } - _img.lockMovementX = _img.lockMovementY = false; - _img.selectable = true; - _img.hoverCursor = 'move'; - return this; - }; + _img.lockMovementX = _img.lockMovementY = false; + _img.selectable = true; + _img.hoverCursor = 'move'; + return this; + }; } module.exports = Draggable; diff --git a/src/FrameHandler.js b/src/FrameHandler.js index 21f36a9..b676f39 100644 --- a/src/FrameHandler.js +++ b/src/FrameHandler.js @@ -4,146 +4,146 @@ var config = require('./config'); function FrameHandler(viewport) { - var _frames; - var _frameType = viewport.canvas.__canvasFrameType; - var _frameSize; + var _frames; + var _frameType = viewport.canvas.__canvasFrameType; + var _frameSize; - function getFramesAsArray() { - return [ - _frames.top, _frames.right, _frames.bottom, _frames.left - ]; - } + function getFramesAsArray() { + return [ + _frames.top, _frames.right, _frames.bottom, _frames.left + ]; + } - /** + /** * Sets the 4 rectangles which are used when current canvas should be framed */ - function initFrames() { - var frame = new fabric.Rect(config.frames.default); + function initFrames() { + var frame = new fabric.Rect(config.frames.default); - _frames = { - top: frame.clone(), - right: frame.clone(), - bottom: frame.clone(), - left: frame.clone() - }; + _frames = { + top: frame.clone(), + right: frame.clone(), + bottom: frame.clone(), + left: frame.clone() + }; - getFramesAsArray().forEach(function (o) { - viewport.canvas.add(o); - }); - } + getFramesAsArray().forEach(function (o) { + viewport.canvas.add(o); + }); + } - function init() { - initFrames(); - } + function init() { + initFrames(); + } - init(); + init(); - /** + /** * @return {String} */ - this.getFrameType = function () { - return _frameType; - }; + this.getFrameType = function () { + return _frameType; + }; - this.getFrameSize = function() { - return _frameSize; - }; + this.getFrameSize = function() { + return _frameSize; + }; - this.setVisible = function (isVisible) { - isVisible = typeof isVisible === 'undefined' ? true : !!isVisible; + this.setVisible = function (isVisible) { + isVisible = typeof isVisible === 'undefined' ? true : !!isVisible; - getFramesAsArray().forEach(function (frame) { - frame.set({ visible: isVisible }); - }); + getFramesAsArray().forEach(function (frame) { + frame.set({ visible: isVisible }); + }); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * Sets passed frametype to passed viewwport * @param {string} frameType none|image|black|white * @return {FrameHandler} */ - this.setFrames = function (frameType) { - var bounds = viewport.getBounds(); + this.setFrames = function (frameType) { + var bounds = viewport.getBounds(); - frameType = frameType || _frameType || 'image'; - _frameType = frameType; + frameType = frameType || _frameType || 'image'; + _frameType = frameType; - if (!frameType) { - return; - } + if (!frameType) { + return; + } - if (frameType === 'none') { - viewport.canvas.getDragbars().apply(); - return this.setVisible(false); - } + if (frameType === 'none') { + viewport.canvas.getDragbars().apply(); + return this.setVisible(false); + } - this.setVisible(true); + this.setVisible(true); - getFramesAsArray().forEach(function (o) { - o.set(config.frames[frameType]); - }); + getFramesAsArray().forEach(function (o) { + o.set(config.frames[frameType]); + }); - var vpData = viewport.getData(); - var realFrameSize = 29; // Actual real life frame size width in mm. + var vpData = viewport.getData(); + var realFrameSize = 29; // Actual real life frame size width in mm. - _frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX; + _frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX; - _frames.top.height = + _frames.top.height = _frames.bottom.height = _frames.right.width = _frames.left.width = _frameSize; - _frames.top.width = _frames.bottom.width = vpData.width; - _frames.right.height = _frames.left.height = vpData.height; + _frames.top.width = _frames.bottom.width = vpData.width; + _frames.right.height = _frames.left.height = vpData.height; - if (frameType === 'image') { - _frames.top.width -= _frameSize * 2; - _frames.bottom.width = _frames.top.width; - _frames.right.height -= _frameSize * 2; - _frames.left.height = _frames.right.height; + if (frameType === 'image') { + _frames.top.width -= _frameSize * 2; + _frames.bottom.width = _frames.top.width; + _frames.right.height -= _frameSize * 2; + _frames.left.height = _frames.right.height; - _frames.top.set({ - top: bounds.top, - }).centerH().setCoords(); + _frames.top.set({ + top: bounds.top, + }).centerH().setCoords(); - _frames.bottom.set({ - top: (bounds.top + bounds.height - _frames.bottom.height) - 1 - }).centerH().setCoords(); + _frames.bottom.set({ + top: (bounds.top + bounds.height - _frames.bottom.height) - 1 + }).centerH().setCoords(); - _frames.right.set({ - left: (bounds.left + bounds.width - _frames.right.width) - 1 - }).centerV().setCoords(); + _frames.right.set({ + left: (bounds.left + bounds.width - _frames.right.width) - 1 + }).centerV().setCoords(); - _frames.left.set({ - left: bounds.left - }).centerV().setCoords(); - } else { - _frames.top.set({ - top: (bounds.top - _frames.top.height) + 1, - }).centerH().setCoords(); + _frames.left.set({ + left: bounds.left + }).centerV().setCoords(); + } else { + _frames.top.set({ + top: (bounds.top - _frames.top.height) + 1, + }).centerH().setCoords(); - _frames.bottom.set({ - top: (bounds.top + bounds.height) - 1, - }).centerH().setCoords(); + _frames.bottom.set({ + top: (bounds.top + bounds.height) - 1, + }).centerH().setCoords(); - _frames.right.set({ - left: (bounds.left + bounds.width) - 1 - }).centerV().setCoords(); + _frames.right.set({ + left: (bounds.left + bounds.width) - 1 + }).centerV().setCoords(); - _frames.left.set({ - left: (bounds.left - _frames.left.width) + 1 - }).centerV().setCoords(); - } - viewport.canvas.getDragbars().apply(); - viewport.canvas.renderAll(); + _frames.left.set({ + left: (bounds.left - _frames.left.width) + 1 + }).centerV().setCoords(); + } + viewport.canvas.getDragbars().apply(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; } module.exports = FrameHandler; diff --git a/src/GoreHandler.js b/src/GoreHandler.js index 03b2f7b..9b89c72 100644 --- a/src/GoreHandler.js +++ b/src/GoreHandler.js @@ -2,78 +2,78 @@ /* globals fabric */ function GoreHandler(viewport) { - var _enabled = false; - var _lines = []; + var _enabled = false; + var _lines = []; - /** + /** * @return {fabric.Line} */ - function getLine(left) { - return new fabric.Line([0, 0, 0, viewport.getData().height], { - evented: false, - strokeDashArray: [5, 5], - stroke: '#F31FB3', - strokeWidth: 1, - left: left, - top: viewport.getBounds().top - }); - } + function getLine(left) { + return new fabric.Line([0, 0, 0, viewport.getData().height], { + evented: false, + strokeDashArray: [5, 5], + stroke: '#F31FB3', + strokeWidth: 1, + left: left, + top: viewport.getBounds().top + }); + } - /** + /** * @return {GoreHandler} */ - this.clear = function () { - _lines.forEach(function (line) { - viewport.canvas.remove(line); - }); - _lines = []; - return this; - }; + this.clear = function () { + _lines.forEach(function (line) { + viewport.canvas.remove(line); + }); + _lines = []; + return this; + }; - /** + /** * @param {Boolean} enabled * @return {GoreHandler} */ - this.enable = function (enabled) { - _enabled = enabled; - this.clear(); + this.enable = function (enabled) { + _enabled = enabled; + this.clear(); - if (!_enabled) { - viewport.canvas.renderAll(); - return this; - } + if (!_enabled) { + viewport.canvas.renderAll(); + return this; + } - var viewportData = viewport.getData(); - var bounds = viewport.getBounds(); - var step = viewportData.ppmm * viewportData.image.scaleX * 450; + var viewportData = viewport.getData(); + var bounds = viewport.getBounds(); + var step = viewportData.ppmm * viewportData.image.scaleX * 450; - /* + /* * First round to 5 digits to fix pixel rounding issues when requested width is an even multiplier of 450mm. * Could set precision higher but 5 decimals places should be enough, pixel rounding issues show somewhere * around 15 decimals places. * Then round up to get correct number of gores. */ - var count = Math.ceil((bounds.width / step).toFixed(5)); + var count = Math.ceil((bounds.width / step).toFixed(5)); - for (var i = 1; i < count; i++) { - _lines.push(getLine(bounds.left + step * i)); - } + for (var i = 1; i < count; i++) { + _lines.push(getLine(bounds.left + step * i)); + } - _lines.forEach(function (o) { - viewport.canvas.add(o); - }); + _lines.forEach(function (o) { + viewport.canvas.add(o); + }); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * @return {GoreHandler} */ - this.reset = function () { - return this.enable(_enabled); - }; + this.reset = function () { + return this.enable(_enabled); + }; } module.exports = GoreHandler; diff --git a/src/ImageDataHandler.js b/src/ImageDataHandler.js index 3656751..1297419 100644 --- a/src/ImageDataHandler.js +++ b/src/ImageDataHandler.js @@ -3,70 +3,70 @@ function ImageDataHandler(img) { - var _cropData; + var _cropData; - /** + /** * Gets information about how the cropped image is dragged * @return {Object} */ - this.getCropData = function () { - return _cropData; + this.getCropData = function () { + return _cropData; + }; + + this.setCropData = function() { + var viewportBounds = img.canvas.getViewport().getBounds(); + if (!viewportBounds) { + return; + } + + var dragAxis = img.canvas.getViewport().getData().axis; + + var leftDiff = viewportBounds.left - img.left; + var topDiff = viewportBounds.top - img.top; + + // Robustness measure to handle the extreme precision of shape positioning in canvas. + var countAsZeroLimit = 1e-5; + leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff; + topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff; + + _cropData = { + x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0, + y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0, + viewportWidth: viewportBounds.width, + viewportHeight: viewportBounds.height, }; + }; - this.setCropData = function() { - var viewportBounds = img.canvas.getViewport().getBounds(); - if (!viewportBounds) { - return; - } + this.removeCropData = function() { + _cropData = null; + }; - var dragAxis = img.canvas.getViewport().getData().axis; - - var leftDiff = viewportBounds.left - img.left; - var topDiff = viewportBounds.top - img.top; - - // Robustness measure to handle the extreme precision of shape positioning in canvas. - var countAsZeroLimit = 1e-5; - leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff; - topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff; - - _cropData = { - x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0, - y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0, - viewportWidth: viewportBounds.width, - viewportHeight: viewportBounds.height, - }; - }; - - this.removeCropData = function() { - _cropData = null; - }; - - /** + /** * Gets an object containing applied transformations for the Image and also * how it is cropped and dragged. * @return {Object} */ - this.getData = function () { - var viewportData = img.canvas.getViewport().getData(); + this.getData = function () { + var viewportData = img.canvas.getViewport().getData(); - var returnValue = $.extend( - {}, - { - mirrored: img.canvas.getMirror().getStatus(), - width: viewportData.dim.width, - height: viewportData.dim.height, - }, - this.getCropData() - ); + var returnValue = $.extend( + {}, + { + mirrored: img.canvas.getMirror().getStatus(), + width: viewportData.dim.width, + height: viewportData.dim.height, + }, + this.getCropData() + ); - if (img.canvas.__type === 'canvas') { - var frameHandler = img.canvas.getViewport().getFrameHandler(); - returnValue.edge = frameHandler.getFrameType(); - returnValue.framed = returnValue.edge !== 'none'; - } + if (img.canvas.__type === 'canvas') { + var frameHandler = img.canvas.getViewport().getFrameHandler(); + returnValue.edge = frameHandler.getFrameType(); + returnValue.framed = returnValue.edge !== 'none'; + } - return returnValue; - }; + return returnValue; + }; } module.exports = ImageDataHandler; diff --git a/src/ImageEditor.js b/src/ImageEditor.js index 2b1e190..5ac9245 100644 --- a/src/ImageEditor.js +++ b/src/ImageEditor.js @@ -5,198 +5,198 @@ var Canvas = require('./Canvas'); var util = require('./util'); function ImageEditor(canvasId, args) { - var _canvas; + var _canvas; - var _settings = $.extend({ - // Type defaults to wallpaper - type: 'wallpaper', - // canvasFrameType defaults to image on frame - canvasFrameType: 'image', - canvasFrameSize: 2.9, - // Default texts on the buttons - texts: { - showThreeD: '3d', - hideThreeD: 'Flat', - showMurals: 'Show Murals Panel', - hideMurals: 'Hide Murals Panel', - showRulers: 'Show Ruler', - hideRulers: 'Hide Ruler', - showFullscreen: 'Fullscreen', - exitFullscreen: 'Exit Fullscreen', - cm: 'cm', - inch: 'inch' - }, - // Default dimensions - dimensions: { - width: 800, - height: 600 - }, - // Default unit - unit: 'cm', - isVisibleFullscreenButton: true - }, args); + var _settings = $.extend({ + // Type defaults to wallpaper + type: 'wallpaper', + // canvasFrameType defaults to image on frame + canvasFrameType: 'image', + canvasFrameSize: 2.9, + // Default texts on the buttons + texts: { + showThreeD: '3d', + hideThreeD: 'Flat', + showMurals: 'Show Murals Panel', + hideMurals: 'Hide Murals Panel', + showRulers: 'Show Ruler', + hideRulers: 'Hide Ruler', + showFullscreen: 'Fullscreen', + exitFullscreen: 'Exit Fullscreen', + cm: 'cm', + inch: 'inch' + }, + // Default dimensions + dimensions: { + width: 800, + height: 600 + }, + // Default unit + unit: 'cm', + isVisibleFullscreenButton: true + }, args); - // Initialize canvas - _canvas = new Canvas(canvasId, _settings.dimensions); + // Initialize canvas + _canvas = new Canvas(canvasId, _settings.dimensions); - // Let Canvas know which type it is, canvas or wallpaper since it is - // accessible for all objects contained within. + // Let Canvas know which type it is, canvas or wallpaper since it is + // accessible for all objects contained within. + _canvas.set({ + __type: _settings.type, + __texts: _settings.texts + }); + + // Adding buttons to the canvas depending on which type is active. + // It might be better that this resides somewhere else, either in Canvas or + // during the initialization of the image editor. + if (_canvas.__type === 'canvas') { + _canvas.getButtonMenu() + .addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () { + _canvas.toggle3D(this.isActive()); + }); _canvas.set({ - __type: _settings.type, - __texts: _settings.texts + __canvasFrameType: _settings.canvasFrameType, + __canvasFrameSize: _settings.canvasFrameSize, }); + } else { + _canvas.getButtonMenu() + .addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () { + _canvas.getViewport().getGores().enable(this.isActive()); + }) + .addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () { + _canvas.getViewport().getRulers().enable(this.isActive()); + }); + } - // Adding buttons to the canvas depending on which type is active. - // It might be better that this resides somewhere else, either in Canvas or - // during the initialization of the image editor. - if (_canvas.__type === 'canvas') { - _canvas.getButtonMenu() - .addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () { - _canvas.toggle3D(this.isActive()); - }); - _canvas.set({ - __canvasFrameType: _settings.canvasFrameType, - __canvasFrameSize: _settings.canvasFrameSize, - }); - } else { - _canvas.getButtonMenu() - .addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () { - _canvas.getViewport().getGores().enable(this.isActive()); - }) - .addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () { - _canvas.getViewport().getRulers().enable(this.isActive()); - }); + if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) { + _canvas.getButtonMenu() + .addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () { + util.toggleFullscreen(_canvas.getSelectionElement().parentNode); + }); + } + + _canvas.getButtonMenu().render(); + + // Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active. + $(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() { + var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen; + + if (isFullscreen) { + return; } - if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) { - _canvas.getButtonMenu() - .addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () { - util.toggleFullscreen(_canvas.getSelectionElement().parentNode); - }); - } - - _canvas.getButtonMenu().render(); - - // Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active. - $(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() { - var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen; - - if (isFullscreen) { - return; - } - - _canvas.getButtonMenu().getItems().forEach(function(button) { - if (button.getId() === 'toggleFullscreen') { - button.setActive(false); - } - }); - + _canvas.getButtonMenu().getItems().forEach(function(button) { + if (button.getId() === 'toggleFullscreen') { + button.setActive(false); + } }); - /** + }); + + /** * Crops image to desired dimensions * @param {int} width [description] * @param {int} height [description] * @param {string} unit cm|inch * @return {ImageEditor} */ - this.crop = function (width, height, unit, removeTransparency) { - removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false; + this.crop = function (width, height, unit, removeTransparency) { + removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false; - if (!width || !height) { - return this; - } + if (!width || !height) { + return this; + } - unit = typeof unit !== 'undefined' ? unit : _settings.unit; - var viewport = _canvas.getViewport(); - var frameType = _canvas.__canvasFrameType; + unit = typeof unit !== 'undefined' ? unit : _settings.unit; + var viewport = _canvas.getViewport(); + var frameType = _canvas.__canvasFrameType; - if (frameType === 'image') { - var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize; - width += 2 * canvasFrameSize; - height += 2 * canvasFrameSize; - } - viewport.set(width, height, unit); + if (frameType === 'image') { + var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize; + width += 2 * canvasFrameSize; + height += 2 * canvasFrameSize; + } + viewport.set(width, height, unit); - var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height); - if (shouldBeCropped) { - _canvas.getImage().__dragged = false; - _canvas.getImage().__cropped = true; - } - else { - _canvas.getImage().__cropped = false; - } + var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height); + if (shouldBeCropped) { + _canvas.getImage().__dragged = false; + _canvas.getImage().__cropped = true; + } + else { + _canvas.getImage().__cropped = false; + } - if (removeTransparency) { - _canvas.getApertures().setTransparent(false); - } + if (removeTransparency) { + _canvas.getApertures().setTransparent(false); + } - return this; - }; + return this; + }; - this.getCropRatio = function () { - var image = _canvas.getImage(); - var cropData = _canvas.getImageData().getCropData(); - if (!cropData) { - return false; - } - var scaledImageWidth = image.width * image.scaleX; - var scaledImageHeight = image.height * image.scaleY; - var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100; - var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100; + this.getCropRatio = function () { + var image = _canvas.getImage(); + var cropData = _canvas.getImageData().getCropData(); + if (!cropData) { + return false; + } + var scaledImageWidth = image.width * image.scaleX; + var scaledImageHeight = image.height * image.scaleY; + var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100; + var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100; - return {width: ratioWidth, height: ratioHeight}; - }; + return {width: ratioWidth, height: ratioHeight}; + }; - /** + /** * @param {string|object} key * @param {object} defaultValue * @return {object} */ - this.get = function (key, defaultValue) { - var value = _settings[key]; - return typeof value === 'undefined' ? defaultValue : value; - }; + this.get = function (key, defaultValue) { + var value = _settings[key]; + return typeof value === 'undefined' ? defaultValue : value; + }; - /** + /** * Loads the image into the canvas. * @param {Number|String} url * @param {Function} callback * @return {ImageEditor} */ - this.loadImage = function (url, callback) { - callback = typeof callback === 'function' ? callback : function () {}; - fabric.util.loadImage(this._url = url, function (obj) { - if(obj === null) { - throw new Error('Error loading ' + url); - } - var img = new fabric.Image(obj); - _canvas.setImage(img); - img.__url = url; - img.sendToBack(); - callback(img); - }, { crossOrigin: 'anonymous' }); - return this; - }; + this.loadImage = function (url, callback) { + callback = typeof callback === 'function' ? callback : function () {}; + fabric.util.loadImage(this._url = url, function (obj) { + if(obj === null) { + throw new Error('Error loading ' + url); + } + var img = new fabric.Image(obj); + _canvas.setImage(img); + img.__url = url; + img.sendToBack(); + callback(img); + }, { crossOrigin: 'anonymous' }); + return this; + }; - /** + /** * @param {string|object} key * @param {object} value * @return {ImageEditor} */ - this.set = function (key, value) { - $.extend(_settings, util.assertKeyValuePair(key, value)); - return this; - }; + this.set = function (key, value) { + $.extend(_settings, util.assertKeyValuePair(key, value)); + return this; + }; - util.setProperties(this, { - canvas: { - get: function () { - return _canvas; - } - } - }); + util.setProperties(this, { + canvas: { + get: function () { + return _canvas; + } + } + }); } module.exports = ImageEditor; diff --git a/src/MirrorHandler.js b/src/MirrorHandler.js index f849b73..6a4c3c9 100644 --- a/src/MirrorHandler.js +++ b/src/MirrorHandler.js @@ -2,22 +2,22 @@ function MirrorHandler(img) { - var _mirrored = 0; + var _mirrored = 0; - /** + /** * @param {Boolean} checked * @return {MirrorHandler} */ - this.set = function(checked) { - _mirrored = (img.flipX = checked) ? 1 : 0; - img.setCoords().canvas.renderAll(); + this.set = function(checked) { + _mirrored = (img.flipX = checked) ? 1 : 0; + img.setCoords().canvas.renderAll(); - return this; - }; + return this; + }; - this.getStatus = function() { - return _mirrored; - }; + this.getStatus = function() { + return _mirrored; + }; } diff --git a/src/RulerHandler.js b/src/RulerHandler.js index 9a797ec..8841b9b 100644 --- a/src/RulerHandler.js +++ b/src/RulerHandler.js @@ -6,130 +6,130 @@ var TextButton = require('./TextButton'); var config = require('./config'); function RulerHandler(viewport) { - var _enabled = false; - var _lines = { x: null, y: null }; - var _rect = { x: null, y: null }; + var _enabled = false; + var _lines = { x: null, y: null }; + var _rect = { x: null, y: null }; - function updateRulerText(ruler) { - var axis = ruler.axis; - var bounds = viewport.getBounds(); - var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]); - ruler.marker[axis] = ruler[axis] = pos; - var posWithinBounds = ruler[axis] - bounds[axis]; - var viewportData = viewport.getData(); - var imageData = viewport.canvas.getImage(); - var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX; - var dim = posWithinBounds / pixelsPerCm; - var units = viewportData.dim.units; + function updateRulerText(ruler) { + var axis = ruler.axis; + var bounds = viewport.getBounds(); + var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]); + ruler.marker[axis] = ruler[axis] = pos; + var posWithinBounds = ruler[axis] - bounds[axis]; + var viewportData = viewport.getData(); + var imageData = viewport.canvas.getImage(); + var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX; + var dim = posWithinBounds / pixelsPerCm; + var units = viewportData.dim.units; - if (units === 'inch') { - dim /= 2.54; - } - if (axis === 'top') { - dim = viewportData.dim.height - dim; - } - var value = Math.round(dim * 100) / 100; - if(units === 'cm') { - value = Math.round(value); - } - var label = viewport.canvas.__texts[units] || 'cm'; - ruler.setText(value + ' ' + label); + if (units === 'inch') { + dim /= 2.54; } + if (axis === 'top') { + dim = viewportData.dim.height - dim; + } + var value = Math.round(dim * 100) / 100; + if(units === 'cm') { + value = Math.round(value); + } + var label = viewport.canvas.__texts[units] || 'cm'; + ruler.setText(value + ' ' + label); + } - var Event = { - /** + var Event = { + /** * Triggers when handlebar is moved */ - onMove: function () { - updateRulerText(this); - } - }; + onMove: function () { + updateRulerText(this); + } + }; - /** + /** * @return {fabric.Line} */ - function getLine(axis) { - var bounds = viewport.getBounds(); - return new fabric.Line([ - 0, 0, - axis === 'x' ? bounds.width : 0, - axis === 'y' ? bounds.height : 0 - ], { - evented: false, - strokeDashArray: [5, 5], - stroke: '#000', - strokeWidth: 1, - top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, - left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left - }); - } + function getLine(axis) { + var bounds = viewport.getBounds(); + return new fabric.Line([ + 0, 0, + axis === 'x' ? bounds.width : 0, + axis === 'y' ? bounds.height : 0 + ], { + evented: false, + strokeDashArray: [5, 5], + stroke: '#000', + strokeWidth: 1, + top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, + left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left + }); + } - /** + /** * @return {RulerHandler} */ - this.clear = function () { - [].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) { - viewport.canvas.remove(o); - }); - return this; - }; + this.clear = function () { + [].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) { + viewport.canvas.remove(o); + }); + return this; + }; - /** + /** * @param {Boolean} enabled * @return {RulerHandler} */ - this.enable = function (enabled) { - var bounds = viewport.getBounds(); + this.enable = function (enabled) { + var bounds = viewport.getBounds(); - var keepPosition = ( - enabled && (_enabled === enabled) && + var keepPosition = ( + enabled && (_enabled === enabled) && _lines.x && (Math.abs(_lines.x.width - bounds.width) < 1) && _lines.y && (Math.abs(_lines.y.height - bounds.height) < 1) - ); + ); - if (keepPosition) { - updateRulerText(_rect.x); - updateRulerText(_rect.y); - return this; - } + if (keepPosition) { + updateRulerText(_rect.x); + updateRulerText(_rect.y); + return this; + } - _enabled = enabled; + _enabled = enabled; - this.clear(); + this.clear(); - if (!_enabled) { - viewport.canvas.renderAll(); - return this; - } + if (!_enabled) { + viewport.canvas.renderAll(); + return this; + } - _lines = { x: getLine('x'), y: getLine('y') }; + _lines = { x: getLine('x'), y: getLine('y') }; - viewport.canvas.add(_lines.x); - viewport.canvas.add(_lines.y); + viewport.canvas.add(_lines.x); + viewport.canvas.add(_lines.y); - _rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true) - .set(config.rulerHandle.x(_lines, bounds)) - .addTo(viewport.canvas) - .on('moving', Event.onMove) - .trigger('moving'); + _rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true) + .set(config.rulerHandle.x(_lines, bounds)) + .addTo(viewport.canvas) + .on('moving', Event.onMove) + .trigger('moving'); - _rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true) - .set(config.rulerHandle.y(_lines, bounds)) - .addTo(viewport.canvas) - .on('moving', Event.onMove) - .trigger('moving'); + _rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true) + .set(config.rulerHandle.y(_lines, bounds)) + .addTo(viewport.canvas) + .on('moving', Event.onMove) + .trigger('moving'); - viewport.canvas.renderAll(); + viewport.canvas.renderAll(); - return this; - }; + return this; + }; - /** + /** * @return {RulerHandler} */ - this.reset = function () { - return this.enable(_enabled); - }; + this.reset = function () { + return this.enable(_enabled); + }; } module.exports = RulerHandler; diff --git a/src/TextButton.js b/src/TextButton.js index a99cebd..af5e53e 100644 --- a/src/TextButton.js +++ b/src/TextButton.js @@ -11,113 +11,113 @@ var config = require('./config'); * @param {bool} isActive */ function TextButton(id, text, settings, isActive) { - /* jshint unused:false */ + /* jshint unused:false */ - fabric.Group.call(this); + fabric.Group.call(this); - var __active = isActive || false; - var _callback = null; - var _rect = null; - var _text = null; - var _id = id; - var width = settings.rect ? settings.rect.width : 0; - var height = settings.rect ? settings.rect.height : 0; + var __active = isActive || false; + var _callback = null; + var _rect = null; + var _text = null; + var _id = id; + var width = settings.rect ? settings.rect.width : 0; + var height = settings.rect ? settings.rect.height : 0; - var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect); - var _textSettings = $.extend({}, config.textButton.text, settings.text, { - text: Array.isArray(text) ? text[0] : text, - textActive: Array.isArray(text) ? text[1] : text, - }); + var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect); + var _textSettings = $.extend({}, config.textButton.text, settings.text, { + text: Array.isArray(text) ? text[0] : text, + textActive: Array.isArray(text) ? text[1] : text, + }); - this.selectable = true; + this.selectable = true; - // Make sure we're interactive - this.disabled = false; - this.hoverCursor = config.textButton.cursor; + // Make sure we're interactive + this.disabled = false; + this.hoverCursor = config.textButton.cursor; - // Initialize text and rectangle - _text = new fabric.Text('', _textSettings); - _rect = new fabric.Rect(_rectSettings); + // Initialize text and rectangle + _text = new fabric.Text('', _textSettings); + _rect = new fabric.Rect(_rectSettings); - this.addWithUpdate(_rect).addWithUpdate(_text); + this.addWithUpdate(_rect).addWithUpdate(_text); - /** + /** * @param {String} text * @return {TextButton} */ - this.setText = function(text) { - _text.setText((text || '').toString()).setCoords(); + this.setText = function(text) { + _text.setText((text || '').toString()).setCoords(); - if (_rectSettings.dynamicW) { - this.width = _rect.width = _text.width + config.textButton.padding; - } + if (_rectSettings.dynamicW) { + this.width = _rect.width = _text.width + config.textButton.padding; + } - if (_rectSettings.dynamicH) { - this.height = _rect.height = _text.height + config.textButton.padding; - } + if (_rectSettings.dynamicH) { + this.height = _rect.height = _text.height + config.textButton.padding; + } - return this.setCoords(); - }; + return this.setCoords(); + }; - this.getId = function() { - return _id; - }; + this.getId = function() { + return _id; + }; - /** + /** * @return {Boolean} */ - this.isActive = function() { - return this.__active; - }; + this.isActive = function() { + return this.__active; + }; - function toggleActiveStyle() { - /*jshint validthis: true */ - _rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']); - _text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']); - this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']); + function toggleActiveStyle() { + /*jshint validthis: true */ + _rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']); + _text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']); + this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']); + } + + function handleMouseDown(e) { + /*jshint validthis: true */ + toggleActiveStyle.call(this); + _callback.call(this, e); + + if (this.__group) { + this.__group.render(); } + } - function handleMouseDown(e) { - /*jshint validthis: true */ - toggleActiveStyle.call(this); - _callback.call(this, e); + this.onClick = function(callback) { + _callback = callback || function() {}; + this.on('mousedown', function (e) { + // As inactive buttons are still clickable, we first check if the button is disabled. + // Only then we should do stuff. + if (!this.disabled) { + this.__active = !this.__active; + handleMouseDown.call(this, e); + } + }.bind(this)); + return this; + }; - if (this.__group) { - this.__group.render(); - } - } + this.setActive = function (isActive) { + this.__active = typeof isActive === 'undefined' ? true : !!isActive; + toggleActiveStyle.call(this); + }; - this.onClick = function(callback) { - _callback = callback || function() {}; - this.on('mousedown', function (e) { - // As inactive buttons are still clickable, we first check if the button is disabled. - // Only then we should do stuff. - if (!this.disabled) { - this.__active = !this.__active; - handleMouseDown.call(this, e); - } - }.bind(this)); - return this; - }; + this.setDisabled = function (isDisabled) + { + this.disabled = isDisabled; - this.setActive = function (isActive) { - this.__active = typeof isActive === 'undefined' ? true : !!isActive; - toggleActiveStyle.call(this); - }; + _rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']); + _text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']); - this.setDisabled = function (isDisabled) - { - this.disabled = isDisabled; + this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor; + }; - _rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']); - _text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']); - - this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor; - }; - - if (_textSettings.text) { - this.setText(_textSettings.text); - } + if (_textSettings.text) { + this.setText(_textSettings.text); + } } TextButton.prototype = Object.create(fabric.Group.prototype); diff --git a/src/Viewport.js b/src/Viewport.js index e732f35..388cbf0 100644 --- a/src/Viewport.js +++ b/src/Viewport.js @@ -7,203 +7,203 @@ var RulerHandler = require('./RulerHandler'); var util = require('./util'); function Viewport(canvas) { - var _beams = []; - var _borderWidth = 2; - var _data = null; - var _rect; - var self = this; + var _beams = []; + var _borderWidth = 2; + var _data = null; + var _rect; + var self = this; - /** + /** * Render the diagonal lines from viewport to edge of the canvas */ - function drawBeams() { - _beams.forEach(function (beam) { - canvas.remove(beam); - }); + function drawBeams() { + _beams.forEach(function (beam) { + canvas.remove(beam); + }); - _beams = []; + _beams = []; - // TOP LEFT - _beams.push(new fabric.Line( - [_rect.left, _rect.top, _rect.left - _rect.top, -1], { - stroke: '#fff', - strokeWidth: 2, - } - )); + // TOP LEFT + _beams.push(new fabric.Line( + [_rect.left, _rect.top, _rect.left - _rect.top, -1], { + stroke: '#fff', + strokeWidth: 2, + } + )); - // TOP RIGHT - _beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width })); - // BOTTOM RIGHT - _beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height })); - // BOTTOM LEFT - _beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height })); + // TOP RIGHT + _beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width })); + // BOTTOM RIGHT + _beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height })); + // BOTTOM LEFT + _beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height })); - _beams.forEach(function (o) { - canvas.add(o); - o.bringToFront(); - }); - } + _beams.forEach(function (o) { + canvas.add(o); + o.bringToFront(); + }); + } - /** + /** * Gets an object with min / max values for each axis, based on the bounds * of passed fabric.Rect * @param {fabric.Rect} rect * @return {Object} */ - function calcMinMaxBoundsForRect(rect, img) { - return { - left: { - min: rect.left + rect.width - (img.width * img.scaleX), - max: rect.left - }, - top: { - min: rect.top + rect.height - (img.height * img.scaleY), - max: rect.top - } - }; - } + function calcMinMaxBoundsForRect(rect, img) { + return { + left: { + min: rect.left + rect.width - (img.width * img.scaleX), + max: rect.left + }, + top: { + min: rect.top + rect.height - (img.height * img.scaleY), + max: rect.top + } + }; + } - /** + /** * Applies viewport to page */ - function apply() { - var cropData = canvas.getImageData().getCropData(); - canvas.remove(_rect); + function apply() { + var cropData = canvas.getImageData().getCropData(); + canvas.remove(_rect); - _rect = new fabric.Rect({ - evented: false, - fill: 'transparent', - width: _data.width, - height: _data.height, - stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff', - strokeWidth: _borderWidth, - }); + _rect = new fabric.Rect({ + evented: false, + fill: 'transparent', + width: _data.width, + height: _data.height, + stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff', + strokeWidth: _borderWidth, + }); - _rect.width += _borderWidth; - _rect.height += _borderWidth; - _rect.addTo(canvas).center().setCoords(); + _rect.width += _borderWidth; + _rect.height += _borderWidth; + _rect.addTo(canvas).center().setCoords(); - if (cropData) { - var viewportBounds = _rect.getInsideBoundingRect(); + if (cropData) { + var viewportBounds = _rect.getInsideBoundingRect(); - // Calculate the new position after screenresize and when the - // image already has been cropped to a certain position. - var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x); - var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y); + // Calculate the new position after screenresize and when the + // image already has been cropped to a certain position. + var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x); + var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y); - canvas.getImage().set({ left: left, top: top }).setCoords(); - } else { - canvas.getImage().center().setCoords(); - canvas.getImageData().setCropData(); - } - - if(canvas.__type !== 'wallpaper') { - canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage())); - canvas.getApertures().apply(_data.axis, _rect.getBoundingRect()); - } else { - canvas.getApertures().disable(); - } - - if (canvas.__type !== 'canvas') { - drawBeams(); - } else { - self.setFrame(canvas.__canvasFrameType); - } - - canvas.getDragbars().apply(); - // Apertures sometimes overlaps the viewports bounding rect. - // Solve this by bringing it to the front after apertures are applied. - _rect.bringToFront(); + canvas.getImage().set({ left: left, top: top }).setCoords(); + } else { + canvas.getImage().center().setCoords(); + canvas.getImageData().setCropData(); } - this.canvas = canvas; + if(canvas.__type !== 'wallpaper') { + canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage())); + canvas.getApertures().apply(_data.axis, _rect.getBoundingRect()); + } else { + canvas.getApertures().disable(); + } - this.getBounds = function () { - return _rect ? _rect.getInsideBoundingRect() : null; - }; + if (canvas.__type !== 'canvas') { + drawBeams(); + } else { + self.setFrame(canvas.__canvasFrameType); + } - /** + canvas.getDragbars().apply(); + // Apertures sometimes overlaps the viewports bounding rect. + // Solve this by bringing it to the front after apertures are applied. + _rect.bringToFront(); + } + + this.canvas = canvas; + + this.getBounds = function () { + return _rect ? _rect.getInsideBoundingRect() : null; + }; + + /** * @return {Viewport} */ - this.reset = function () { - if (_data) { - return this.set(_data.dim.width, _data.dim.height, _data.dim.units); - } - return this; - }; + this.reset = function () { + if (_data) { + return this.set(_data.dim.width, _data.dim.height, _data.dim.units); + } + return this; + }; - /** + /** * @param {Number} width * @param {Number} height * @param {string} units * @return {Viewport} */ - this.set = function (width, height, units) { - if (!width || !height) { - return this; - } + this.set = function (width, height, units) { + if (!width || !height) { + return this; + } - _data = util.calcCrop(canvas.getImage(), width, height, units); + _data = util.calcCrop(canvas.getImage(), width, height, units); - var cropData = canvas.getImageData().getCropData(); - var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); + var cropData = canvas.getImageData().getCropData(); + var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); - if (!isAspectTheSame) { - canvas.getImageData().removeCropData(); - } + if (!isAspectTheSame) { + canvas.getImageData().removeCropData(); + } - apply(); - this.getGores().reset(); - this.getRulers().reset(); + apply(); + this.getGores().reset(); + this.getRulers().reset(); - if (canvas.getImage().__cropped && !isAspectTheSame) { - canvas.getApertures().setTransparent(true); + if (canvas.getImage().__cropped && !isAspectTheSame) { + canvas.getApertures().setTransparent(true); - // Trigger event to tell the image needs to be dragged. - $(document).trigger('PIE:needs-dragging', { axis: _data.axis }); - } + // Trigger event to tell the image needs to be dragged. + $(document).trigger('PIE:needs-dragging', { axis: _data.axis }); + } - canvas.getButtonMenu().bringToFront(); + canvas.getButtonMenu().bringToFront(); - return this; - }; + return this; + }; - /** + /** * @param {string} frameType white|black|image|none * @return {Viewport} */ - this.setFrame = function (frameType) { - this.getFrameHandler().setFrames(frameType); + this.setFrame = function (frameType) { + this.getFrameHandler().setFrames(frameType); - var buttons = canvas.getButtonMenu().getItems(); - if (frameType === 'none') { - buttons[0].setDisabled(true); - } - else { - buttons[0].setDisabled(false); - } - canvas.getButtonMenu().bringToFront(); + var buttons = canvas.getButtonMenu().getItems(); + if (frameType === 'none') { + buttons[0].setDisabled(true); + } + else { + buttons[0].setDisabled(false); + } + canvas.getButtonMenu().bringToFront(); - canvas.refresh3dView(); - }; + canvas.refresh3dView(); + }; - this.getData = function () { - return _data; - }; + this.getData = function () { + return _data; + }; - var _frameHandler = null; + var _frameHandler = null; - this.getFrameHandler = function () { - return _frameHandler || (_frameHandler = new FrameHandler(this)); - }; + this.getFrameHandler = function () { + return _frameHandler || (_frameHandler = new FrameHandler(this)); + }; - this.getGores = function () { - return this.__goreHandler || (this.__goreHandler = new GoreHandler(this)); - }; + this.getGores = function () { + return this.__goreHandler || (this.__goreHandler = new GoreHandler(this)); + }; - this.getRulers = function () { - return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this)); - }; + this.getRulers = function () { + return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this)); + }; } diff --git a/src/config.js b/src/config.js index 63b4b73..38fa303 100644 --- a/src/config.js +++ b/src/config.js @@ -1,10 +1,10 @@ 'use strict'; module.exports = { - frames: require('./config/frames'), - textButton: require('./config/text-button'), - buttonMenu: require('./config/button-menu'), - rulerHandle: require('./config/ruler-handle'), - dragHandle: require('./config/drag-handle'), - dragBar: require('./config/drag-bar') + frames: require('./config/frames'), + textButton: require('./config/text-button'), + buttonMenu: require('./config/button-menu'), + rulerHandle: require('./config/ruler-handle'), + dragHandle: require('./config/drag-handle'), + dragBar: require('./config/drag-bar') }; diff --git a/src/config/button-menu.js b/src/config/button-menu.js index 29c7392..b82bfa8 100644 --- a/src/config/button-menu.js +++ b/src/config/button-menu.js @@ -2,40 +2,40 @@ module.exports = { - canvas: { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#343434', - activeFill: '#494949', - }, + canvas: { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', }, - - 'photo-wallpaper': { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#000000', - activeFill: '#444444', - }, + rect: { + fill: '#343434', + activeFill: '#494949', }, + }, - wallpaper: { - margin: 5, - text: { - fill: '#ffffff', - activeFill: '#ffffff', - }, - rect: { - fill: '#343434', - activeFill: '#494949', - }, - } + 'photo-wallpaper': { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', + }, + rect: { + fill: '#000000', + activeFill: '#444444', + }, + }, + + wallpaper: { + margin: 5, + text: { + fill: '#ffffff', + activeFill: '#ffffff', + }, + rect: { + fill: '#343434', + activeFill: '#494949', + }, + } }; diff --git a/src/config/drag-bar.js b/src/config/drag-bar.js index 092e0ee..b9121cd 100644 --- a/src/config/drag-bar.js +++ b/src/config/drag-bar.js @@ -1,6 +1,6 @@ 'use strict'; module.exports = { - fill: '#bbbbbb', - size: 20, + fill: '#bbbbbb', + size: 20, }; diff --git a/src/config/drag-handle.js b/src/config/drag-handle.js index af78eb5..6727679 100644 --- a/src/config/drag-handle.js +++ b/src/config/drag-handle.js @@ -1,16 +1,16 @@ 'use strict'; module.exports = { - text: { - fontFamily: 'breuer', - fontSize: 12, - fill: '#ffffff', - originX: 'center', - top: 2, - }, - rect: { - fill: '#666666', - height: 20, - originX: 'center', - }, + text: { + fontFamily: 'breuer', + fontSize: 12, + fill: '#ffffff', + originX: 'center', + top: 2, + }, + rect: { + fill: '#666666', + height: 20, + originX: 'center', + }, }; diff --git a/src/config/frames.js b/src/config/frames.js index 2667838..c16d703 100644 --- a/src/config/frames.js +++ b/src/config/frames.js @@ -2,26 +2,26 @@ module.exports = { - default: { - fill: '#000000', - stroke: '#f31fb3', - width: 1, - height: 1, - }, + default: { + fill: '#000000', + stroke: '#f31fb3', + width: 1, + height: 1, + }, - image: { - fill: 'rgba(0,0,0,0.2)', - strokeWidth: 1, - }, + image: { + fill: 'rgba(0,0,0,0.2)', + strokeWidth: 1, + }, - black: { - fill: '#000000', - strokeWidth: 0, - }, + black: { + fill: '#000000', + strokeWidth: 0, + }, - white: { - fill: '#ffffff', - strokeWidth: 0, - }, + white: { + fill: '#ffffff', + strokeWidth: 0, + }, }; diff --git a/src/config/ruler-handle.js b/src/config/ruler-handle.js index 717ab8f..a38bdda 100644 --- a/src/config/ruler-handle.js +++ b/src/config/ruler-handle.js @@ -2,46 +2,46 @@ module.exports = { - line: function(axis, bounds) { - return { - evented: false, - strokeDashArray: [5, 5], - stroke: '#000', - strokeWidth: 1, - top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, - left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left - }; - }, + line: function(axis, bounds) { + return { + evented: false, + strokeDashArray: [5, 5], + stroke: '#000', + strokeWidth: 1, + top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, + left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left + }; + }, - text: { - fontSize: 12, - width: 75, - height: 20, - fill: '#FFFFFF', - }, + text: { + fontSize: 12, + width: 75, + height: 20, + fill: '#FFFFFF', + }, - x: function(lines, bounds) { - return { - axis: 'left', - marker: lines.y, - top: Math.ceil(bounds.top + bounds.height + 5), - left: lines.y.left, - originX: 'center', - lockMovementY: true, - moveCursor: 'ew-resize', - hoverCursor: 'ew-resize', - }; - }, - y: function(lines, bounds) { - return { - axis: 'top', - marker: lines.x, - top: lines.x.top, - left: Math.ceil(bounds.left + bounds.width + 5), - originY: 'center', - lockMovementX: true, - moveCursor: 'ns-resize', - hoverCursor: 'ns-resize', - }; - } + x: function(lines, bounds) { + return { + axis: 'left', + marker: lines.y, + top: Math.ceil(bounds.top + bounds.height + 5), + left: lines.y.left, + originX: 'center', + lockMovementY: true, + moveCursor: 'ew-resize', + hoverCursor: 'ew-resize', + }; + }, + y: function(lines, bounds) { + return { + axis: 'top', + marker: lines.x, + top: lines.x.top, + left: Math.ceil(bounds.left + bounds.width + 5), + originY: 'center', + lockMovementX: true, + moveCursor: 'ns-resize', + hoverCursor: 'ns-resize', + }; + } }; diff --git a/src/config/text-button.js b/src/config/text-button.js index 2f2a1a5..09e3cbc 100644 --- a/src/config/text-button.js +++ b/src/config/text-button.js @@ -2,30 +2,30 @@ module.exports = { - rect: function(width, height) { - return { - fill: '#343434', - activeFill: '#494949', - disabledFill: '#494949', - originX: 'center', - originY: 'center', - width: width || 1, - dynamicW: !width, - height: height || 1, - dynamicH: !height, - }; - }, + rect: function(width, height) { + return { + fill: '#343434', + activeFill: '#494949', + disabledFill: '#494949', + originX: 'center', + originY: 'center', + width: width || 1, + dynamicW: !width, + height: height || 1, + dynamicH: !height, + }; + }, - text: { - fill: '#ffffff', - disabledFill: '#999999', - fontFamily: 'breuer', - fontSize: 14, - originX: 'center', - originY: 'center', - }, + text: { + fill: '#ffffff', + disabledFill: '#999999', + fontFamily: 'breuer', + fontSize: 14, + originX: 'center', + originY: 'center', + }, - cursor: 'pointer', - disabledCursor: 'default', - padding: 20, + cursor: 'pointer', + disabledCursor: 'default', + padding: 20, }; diff --git a/src/extend-fabric-functionality.js b/src/extend-fabric-functionality.js index b5bc513..fc19c1f 100644 --- a/src/extend-fabric-functionality.js +++ b/src/extend-fabric-functionality.js @@ -6,59 +6,59 @@ var util = require('./util'); function ExtendFabricFunctionality() { - // Set default values for the fabric canvas - $.extend(fabric.Object.prototype, { - cornerSize: 0, - hasBorders: false, - hasControls: false, - padding: 0, - selectable: false, - strokeWidth: 0, - addTo: function(canvas) { - canvas.add(this); - return this; - }, - }); + // Set default values for the fabric canvas + $.extend(fabric.Object.prototype, { + cornerSize: 0, + hasBorders: false, + hasControls: false, + padding: 0, + selectable: false, + strokeWidth: 0, + addTo: function(canvas) { + canvas.add(this); + return this; + }, + }); - util.setProperties(fabric.Image.prototype, { - drag: { - get: function() { - return this.__draggable || (this.__draggable = new Draggable(this)); - } - } - }); + util.setProperties(fabric.Image.prototype, { + drag: { + get: function() { + return this.__draggable || (this.__draggable = new Draggable(this)); + } + } + }); - $.extend(fabric.Rect.prototype, { - /** + $.extend(fabric.Rect.prototype, { + /** * Gets the inner bounds of this fabric.Rect * @return {Object} */ - getInsideBoundingRect: function() { - var bounds = this.getBoundingRect(); - var returnValue = { - left: bounds.left + this.strokeWidth, - top: bounds.top + this.strokeWidth, - width: bounds.width - this.strokeWidth * 2, - height: bounds.height - this.strokeWidth * 2 - }; + getInsideBoundingRect: function() { + var bounds = this.getBoundingRect(); + var returnValue = { + left: bounds.left + this.strokeWidth, + top: bounds.top + this.strokeWidth, + width: bounds.width - this.strokeWidth * 2, + height: bounds.height - this.strokeWidth * 2 + }; - returnValue.right = returnValue.left + returnValue.width; - returnValue.bottom = returnValue.top + returnValue.height; + returnValue.right = returnValue.left + returnValue.width; + returnValue.bottom = returnValue.top + returnValue.height; - returnValue.min = { - left: returnValue.left, - top: returnValue.top - }; + returnValue.min = { + left: returnValue.left, + top: returnValue.top + }; - returnValue.max = { - left: returnValue.left + returnValue.width, - top: returnValue.top + returnValue.height - }; + returnValue.max = { + left: returnValue.left + returnValue.width, + top: returnValue.top + returnValue.height + }; - return returnValue; - } - }); + return returnValue; + } + }); } module.exports = ExtendFabricFunctionality; diff --git a/src/main.js b/src/main.js index 02c79d4..2867b20 100644 --- a/src/main.js +++ b/src/main.js @@ -3,17 +3,17 @@ (function() { - /** + /** * Fabric functionality is extended with some custom functionality. This is done before * we do anything else. */ - require('./extend-fabric-functionality')(); + require('./extend-fabric-functionality')(); - /** + /** * ImageEditor is the starting point of all files. Here the image editor is created and * it receives attributes from the initialisation. As this is done from outside of this file, * the ImageEditor should be available on globally. */ - window.ImageEditor = require('./ImageEditor'); + window.ImageEditor = require('./ImageEditor'); }()); diff --git a/src/util.js b/src/util.js index b47d640..f436acd 100644 --- a/src/util.js +++ b/src/util.js @@ -2,15 +2,15 @@ module.exports = { - assertKeyValuePair: require('./utils/assert-key-value-pair'), - assertBetween: require('./utils/assert-between'), - calcCrop: require('./utils/calc-crop'), - setPositionInside: require('./utils/set-position-inside'), - setProperties: require('./utils/set-properties'), - toggleFullscreen: require('./utils/toggle-fullscreen'), - isMobile: require('./utils/is-mobile'), - MouseMetrics: require('./utils/mouse-metrics'), - supportsFullscreen: require('./utils/supports-fullscreen'), - isFullscreen: require('./utils/is-fullscreen'), - isAspectChanged: require('./utils/is-aspect-changed'), + assertKeyValuePair: require('./utils/assert-key-value-pair'), + assertBetween: require('./utils/assert-between'), + calcCrop: require('./utils/calc-crop'), + setPositionInside: require('./utils/set-position-inside'), + setProperties: require('./utils/set-properties'), + toggleFullscreen: require('./utils/toggle-fullscreen'), + isMobile: require('./utils/is-mobile'), + MouseMetrics: require('./utils/mouse-metrics'), + supportsFullscreen: require('./utils/supports-fullscreen'), + isFullscreen: require('./utils/is-fullscreen'), + isAspectChanged: require('./utils/is-aspect-changed'), }; diff --git a/src/utils/assert-between.js b/src/utils/assert-between.js index 3d70a1b..9bad98d 100644 --- a/src/utils/assert-between.js +++ b/src/utils/assert-between.js @@ -1,13 +1,13 @@ 'use strict'; function assertBetween(value, min, max) { - if (value < min) { - return min; - } - if (value > max) { - return max; - } - return value; + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; } module.exports = assertBetween; diff --git a/src/utils/assert-key-value-pair.js b/src/utils/assert-key-value-pair.js index e793059..c4220d5 100644 --- a/src/utils/assert-key-value-pair.js +++ b/src/utils/assert-key-value-pair.js @@ -1,14 +1,14 @@ 'use strict'; function assertKeyValuePair(key, value) { - if (typeof key === 'object') { - return key; - } + if (typeof key === 'object') { + return key; + } - var returnValue = {}; - returnValue[key] = value; + var returnValue = {}; + returnValue[key] = value; - return returnValue; + return returnValue; } module.exports = assertKeyValuePair; diff --git a/src/utils/calc-crop.js b/src/utils/calc-crop.js index 0eec85b..dcec34f 100644 --- a/src/utils/calc-crop.js +++ b/src/utils/calc-crop.js @@ -13,38 +13,38 @@ * ppmm: NUMBER */ function calcCrop(obj, width, height, units) { - var cropRatio = width / height; - var objRatio = obj.width / obj.height; - var inchToCm = units === "inch" ? 2.54 : 1; + var cropRatio = width / height; + var objRatio = obj.width / obj.height; + var inchToCm = units === 'inch' ? 2.54 : 1; - var returnValue = { - image: obj, - axis: objRatio > cropRatio ? 'x' : 'y', - dim: { - width: Number(width), - height: Number(height), - units: units - }, - width: obj.width * obj.scaleX, - height: obj.height * obj.scaleY, - objectRatio: objRatio, - cropRatio: cropRatio - }; + var returnValue = { + image: obj, + axis: objRatio > cropRatio ? 'x' : 'y', + dim: { + width: Number(width), + height: Number(height), + units: units + }, + width: obj.width * obj.scaleX, + height: obj.height * obj.scaleY, + objectRatio: objRatio, + cropRatio: cropRatio + }; - if (objRatio > cropRatio) { - returnValue.width *= cropRatio / objRatio; - } else { - returnValue.height /= cropRatio / objRatio; - } + if (objRatio > cropRatio) { + returnValue.width *= cropRatio / objRatio; + } else { + returnValue.height /= cropRatio / objRatio; + } - // Pixels per millimeter - var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10); + // Pixels per millimeter + var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10); - //Round to four decimal places to avoid precision issues. At least 4 decimals is needed though - //for correct calculation of number of gores on wide wallpaperes in editor. - returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4; + //Round to four decimal places to avoid precision issues. At least 4 decimals is needed though + //for correct calculation of number of gores on wide wallpaperes in editor. + returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4; - return returnValue; + return returnValue; } module.exports = calcCrop; diff --git a/src/utils/is-aspect-changed.js b/src/utils/is-aspect-changed.js index 09179c4..91f71b7 100644 --- a/src/utils/is-aspect-changed.js +++ b/src/utils/is-aspect-changed.js @@ -1,7 +1,7 @@ 'use strict'; function isAspectChanged(x1, y1, x2, y2) { - return (Math.abs(x1 / y1 - x2 / y2) > 0.005); + return (Math.abs(x1 / y1 - x2 / y2) > 0.005); } module.exports = isAspectChanged; diff --git a/src/utils/is-fullscreen.js b/src/utils/is-fullscreen.js index a007904..c646325 100644 --- a/src/utils/is-fullscreen.js +++ b/src/utils/is-fullscreen.js @@ -1,7 +1,7 @@ 'use strict'; function isFullscreen() { - return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; } module.exports = isFullscreen; diff --git a/src/utils/is-mobile.js b/src/utils/is-mobile.js index 4b0a9ce..6d3c5e9 100644 --- a/src/utils/is-mobile.js +++ b/src/utils/is-mobile.js @@ -2,7 +2,7 @@ /* globals $, window */ function isMobile() { - return $(window).width() < 768; + return $(window).width() < 768; } module.exports = isMobile; diff --git a/src/utils/mouse-metrics.js b/src/utils/mouse-metrics.js index 04659f6..26008c3 100644 --- a/src/utils/mouse-metrics.js +++ b/src/utils/mouse-metrics.js @@ -1,24 +1,24 @@ 'use strict'; var MouseMetrics = { - previousMouseData: { - x: null, - y: null - }, + previousMouseData: { + x: null, + y: null + }, - deletePreviousMouseData: function() { - MouseMetrics.previousMouseData = { - x: null, - y: null - }; - }, + deletePreviousMouseData: function() { + MouseMetrics.previousMouseData = { + x: null, + y: null + }; + }, - setPreviousMouseData: function(values) { - MouseMetrics.previousMouseData = { - x: values.x || null, - y: values.y || null, - }; - }, + setPreviousMouseData: function(values) { + MouseMetrics.previousMouseData = { + x: values.x || null, + y: values.y || null, + }; + }, }; module.exports = MouseMetrics; diff --git a/src/utils/set-position-inside.js b/src/utils/set-position-inside.js index 06c2115..948c5b8 100644 --- a/src/utils/set-position-inside.js +++ b/src/utils/set-position-inside.js @@ -6,16 +6,16 @@ * @return {fabric.Object} */ function setPositionInside(obj, bounds) { - ['left', 'top'].forEach(function (v) { - if (obj[v] < bounds[v].min) { - obj.set(v, bounds[v].min).setCoords(); - } + ['left', 'top'].forEach(function (v) { + if (obj[v] < bounds[v].min) { + obj.set(v, bounds[v].min).setCoords(); + } - if (obj[v] > bounds[v].max) { - obj.set(v, bounds[v].max).setCoords(); - } - }); - return obj; + if (obj[v] > bounds[v].max) { + obj.set(v, bounds[v].max).setCoords(); + } + }); + return obj; } module.exports = setPositionInside; diff --git a/src/utils/set-properties.js b/src/utils/set-properties.js index 078b63a..5cf88e2 100644 --- a/src/utils/set-properties.js +++ b/src/utils/set-properties.js @@ -5,11 +5,11 @@ * @param {Object} properties */ function setProperties(obj, properties) { - for (var o in properties) { - if (properties.hasOwnProperty(o)) { - Object.defineProperty(obj, o, properties[o]); - } + for (var o in properties) { + if (properties.hasOwnProperty(o)) { + Object.defineProperty(obj, o, properties[o]); } + } } module.exports = setProperties; diff --git a/src/utils/supports-fullscreen.js b/src/utils/supports-fullscreen.js index 2025486..bd7f23e 100644 --- a/src/utils/supports-fullscreen.js +++ b/src/utils/supports-fullscreen.js @@ -2,7 +2,7 @@ function supportsFullscreen() { - return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen; + return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen; } diff --git a/src/utils/toggle-fullscreen.js b/src/utils/toggle-fullscreen.js index f97df1e..eb4f0ed 100644 --- a/src/utils/toggle-fullscreen.js +++ b/src/utils/toggle-fullscreen.js @@ -6,28 +6,28 @@ var isFullscreen = require('./is-fullscreen'); * @param {HTMLElement} elem */ function toggleFullscreen(elem) { - if (isFullscreen()) { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitCancelFullScreen) { - document.webkitCancelFullScreen(); - } - return; + if (isFullscreen()) { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitCancelFullScreen) { + document.webkitCancelFullScreen(); } + return; + } - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if (elem.webkitRequestFullScreen) { - elem.webkitRequestFullScreen(); - } else if (elem.mozRequestFullScreen) { - elem.mozRequestFullScreen(); - } else if (elem.msRequestFullscreen) { - elem.msRequestFullscreen(); - } + if (elem.requestFullscreen) { + elem.requestFullscreen(); + } else if (elem.webkitRequestFullScreen) { + elem.webkitRequestFullScreen(); + } else if (elem.mozRequestFullScreen) { + elem.mozRequestFullScreen(); + } else if (elem.msRequestFullscreen) { + elem.msRequestFullscreen(); + } } module.exports = toggleFullscreen; diff --git a/test/.eslintrc b/test/.eslintrc new file mode 100644 index 0000000..f1fa1dc --- /dev/null +++ b/test/.eslintrc @@ -0,0 +1,6 @@ +{ + "globals": { + "QUnit": false, + "ImageEditor": false + } +} diff --git a/test/unit/image-editor.js b/test/unit/image-editor.js index 4699a6a..ef9c170 100644 --- a/test/unit/image-editor.js +++ b/test/unit/image-editor.js @@ -1,28 +1,28 @@ (function() { - QUnit.module('ImageEditor'); + QUnit.module('ImageEditor'); - QUnit.test('load image', function(assert) { - var done = assert.async(); - var editor = new ImageEditor('canvas'); - editor.loadImage('fixtures/dog.jpg', function() { - assert.ok(editor.canvas.getImage(), 'image loaded'); - done(); - }); + QUnit.test('load image', function(assert) { + var done = assert.async(); + var editor = new ImageEditor('canvas'); + editor.loadImage('fixtures/dog.jpg', function() { + assert.ok(editor.canvas.getImage(), 'image loaded'); + done(); }); + }); - QUnit.test('crop image', function(assert) { - var done = assert.async(); - var editor = new ImageEditor('canvas'); - editor.loadImage('fixtures/dog.jpg', function() { - editor.crop(400, 200, 'cm'); - var data = editor.canvas.getImageData().getData(); - assert.strictEqual(data.width, 400, 'sets image width'); - assert.strictEqual(data.height, 200, 'sets image height'); - assert.strictEqual(data.x, 0, 'sets crop x'); - assert.strictEqual(data.y.toFixed(7), (0.12482117310443483).toFixed(7), 'sets crop y'); - done(); - }); + QUnit.test('crop image', function(assert) { + var done = assert.async(); + var editor = new ImageEditor('canvas'); + editor.loadImage('fixtures/dog.jpg', function() { + editor.crop(400, 200, 'cm'); + var data = editor.canvas.getImageData().getData(); + assert.strictEqual(data.width, 400, 'sets image width'); + assert.strictEqual(data.height, 200, 'sets image height'); + assert.strictEqual(data.x, 0, 'sets crop x'); + assert.strictEqual(data.y.toFixed(7), (0.12482117310443483).toFixed(7), 'sets crop y'); + done(); }); + }); })();