Compare commits
10
Commits
176d45b8db
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84ed7d8c23 | ||
|
|
37fd36275a | ||
|
|
96b4064986 | ||
|
|
ec81c5dd3a | ||
|
|
b88b4c7993 | ||
|
|
d70fb7ae6c | ||
|
|
3a3da21bba | ||
|
|
63d18dc295 | ||
|
|
8c97a33735 | ||
|
|
f9fbc8d34f |
@@ -1,8 +1,17 @@
|
||||
Photowall Image Editor
|
||||
======================
|
||||
# Photowall Image Editor
|
||||
|
||||
Image editor for the Photowall web project
|
||||
|
||||
# Working with image-editor integrated in photowall site
|
||||
|
||||
A suggested workflow is replacing `src/js/legacy/vendor-js/generated-image-editor.js` in photowall project with a symlink to
|
||||
`dist/generated-image-editor.js` in this project. That way you can have `gulp watch` running to build on change in this project
|
||||
which will trigger `npm run watch` (webpack) in photowall project.
|
||||
|
||||
Symlink should be removed and new copy of `dist/generated-image-editor.js` copied to photowall project when work
|
||||
is done however to not force all team members to have same file structure for projects.
|
||||
|
||||
# Linting
|
||||
|
||||
Linting can be run manually with
|
||||
`npm run lint`
|
||||
|
||||
|
||||
+143
-303
@@ -1,114 +1,4 @@
|
||||
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
/**
|
||||
* Handles 3d image of canvas products.
|
||||
* @param {canvas} canvas
|
||||
*/
|
||||
function ThreeDHandler(canvas) {
|
||||
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,
|
||||
}));
|
||||
|
||||
canvas.add(_overlay);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
/**
|
||||
* Disables the 3d image by removing visibility
|
||||
* @return {ThreeDHandler}
|
||||
*/
|
||||
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();
|
||||
|
||||
canvas.getButtonMenu().bringToFront();
|
||||
canvas.renderAll();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if 3d mode is enabled/visible.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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.applyImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* (Re)adds the new/existing image with new configuration to the overlay.
|
||||
* @param {img}
|
||||
*/
|
||||
this.applyImage = function(img) {
|
||||
img = img || _image;
|
||||
|
||||
_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.applyImage(img);
|
||||
return this.enable();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = ThreeDHandler;
|
||||
|
||||
},{}],2:[function(require,module,exports){
|
||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
@@ -209,7 +99,7 @@ function ApertureHandler(canvas) {
|
||||
|
||||
module.exports = ApertureHandler;
|
||||
|
||||
},{}],3:[function(require,module,exports){
|
||||
},{}],2:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var TextButton = require('./TextButton');
|
||||
@@ -362,7 +252,7 @@ function ButtonMenu(canvas, settings) {
|
||||
|
||||
module.exports = ButtonMenu;
|
||||
|
||||
},{"./TextButton":14}],4:[function(require,module,exports){
|
||||
},{"./TextButton":13}],3:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -372,10 +262,10 @@ var ApertureHandler = require('./ApertureHandler');
|
||||
var ButtonMenu = require('./ButtonMenu');
|
||||
var DragbarHandler = require('./DragbarHandler');
|
||||
var Viewport = require('./Viewport');
|
||||
var ThreeDHandler = require('./3dHandler');
|
||||
var MirrorHandler = require('./MirrorHandler');
|
||||
var ImageDataHandler = require('./ImageDataHandler');
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var $document = $(document);
|
||||
|
||||
/**
|
||||
@@ -391,11 +281,11 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
// Allow touch scrolling on touch-devices larger than mobile screen sizes.
|
||||
allowTouchScrolling: !util.isMobile(),
|
||||
stateful: false,
|
||||
backgroundColor: '#ededed',
|
||||
backgroundColor: '#ffffff',
|
||||
preserveObjectStacking: true,
|
||||
selection: false,
|
||||
width: dimensions.width,
|
||||
height: dimensions.height
|
||||
height: dimensions.height,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -408,12 +298,8 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
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.refreshImage(this.getResizedImage(this.getImage()));
|
||||
this.getViewport().reset();
|
||||
this.sendToBack(this.getImage());
|
||||
this.getImage().center();
|
||||
this.getDragbars().resetPosition();
|
||||
@@ -434,33 +320,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
return this;
|
||||
},
|
||||
|
||||
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,
|
||||
'no-cache=1',
|
||||
];
|
||||
|
||||
if (imageData.mirrored) {
|
||||
params.push('mirror=1');
|
||||
}
|
||||
|
||||
return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&');
|
||||
},
|
||||
|
||||
getApertures: function () {
|
||||
return this.__aperturehandler ||
|
||||
(this.__aperturehandler = new ApertureHandler(this));
|
||||
@@ -518,17 +377,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
return this.__buttonMenu;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads the 3D view, if it is present
|
||||
* @return {Canvas}
|
||||
*/
|
||||
refresh3dView: function () {
|
||||
if (this.get3dHandler().isEnabled()) {
|
||||
this.toggle3D(true);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {Canvas}
|
||||
*/
|
||||
@@ -562,8 +410,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
},
|
||||
|
||||
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;
|
||||
|
||||
@@ -572,32 +418,11 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
|
||||
return img;
|
||||
},
|
||||
|
||||
toggle3D: function (showAs3d) {
|
||||
|
||||
this.getButtonMenu().setButtonActive('toggle3d', showAs3d);
|
||||
|
||||
if (!showAs3d) {
|
||||
return this.get3dHandler().disable();
|
||||
}
|
||||
|
||||
$document.trigger('PIE:image-start-load');
|
||||
|
||||
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));
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Canvas;
|
||||
|
||||
},{"./3dHandler":1,"./ApertureHandler":2,"./ButtonMenu":3,"./DragbarHandler":6,"./ImageDataHandler":10,"./MirrorHandler":12,"./Viewport":15,"./config":16,"./util":25}],5:[function(require,module,exports){
|
||||
},{"./ApertureHandler":1,"./ButtonMenu":2,"./DragbarHandler":5,"./ImageDataHandler":9,"./MirrorHandler":11,"./Viewport":14,"./config":15,"./util":24}],4:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -723,6 +548,9 @@ var DragHandle = function (handler) {
|
||||
heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
|
||||
}
|
||||
|
||||
widthToDisplay = Math.round((widthToDisplay + Number.EPSILON) * 10) / 10;
|
||||
heightToDisplay = Math.round((heightToDisplay + Number.EPSILON) * 10) / 10;
|
||||
|
||||
this.__handles = {
|
||||
x: getRect(widthToDisplay + ' ' + unit, handleWidth),
|
||||
y: getRect(heightToDisplay + ' ' + unit, handleHeight)
|
||||
@@ -745,7 +573,7 @@ var DragHandle = function (handler) {
|
||||
|
||||
module.exports = DragHandle;
|
||||
|
||||
},{"./config":16,"./util":25}],6:[function(require,module,exports){
|
||||
},{"./config":15,"./util":24}],5:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -832,34 +660,42 @@ function DragbarHandler(canvas) {
|
||||
this.init = function () {
|
||||
this.clear();
|
||||
var typeIsWallpaper = canvas.__type === 'wallpaper';
|
||||
var image = canvas.getImage();
|
||||
|
||||
_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',
|
||||
}))
|
||||
_dragbars.x = new fabric.Rect(
|
||||
$.extend({}, config.dragBar, {
|
||||
axis: 'x',
|
||||
width: image.width * image.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();
|
||||
.centerH()
|
||||
.set({ top: image.height + 10 })
|
||||
.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',
|
||||
}))
|
||||
_dragbars.y = new fabric.Rect(
|
||||
$.extend({}, config.dragBar, {
|
||||
axis: 'y',
|
||||
width: config.dragBar.size,
|
||||
height: image.height * image.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();
|
||||
.set({ left: canvas.width - 30 })
|
||||
.setCoords();
|
||||
|
||||
canvas.getImage().on('moving', this.sync);
|
||||
|
||||
@@ -878,7 +714,7 @@ function DragbarHandler(canvas) {
|
||||
|
||||
module.exports = DragbarHandler;
|
||||
|
||||
},{"./DragHandle":5,"./config":16}],7:[function(require,module,exports){
|
||||
},{"./DragHandle":4,"./config":15}],6:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $ */
|
||||
var util = require('./util');
|
||||
@@ -955,7 +791,7 @@ function Draggable(img, boundingRect) {
|
||||
|
||||
module.exports = Draggable;
|
||||
|
||||
},{"./util":25}],8:[function(require,module,exports){
|
||||
},{"./util":24}],7:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
@@ -964,6 +800,7 @@ var config = require('./config');
|
||||
function FrameHandler(viewport) {
|
||||
var _frames;
|
||||
var _frameType = viewport.canvas.__canvasFrameType;
|
||||
var _realFrameSizeCm = viewport.canvas.__canvasFrameSize;
|
||||
var _frameSize;
|
||||
|
||||
function getFramesAsArray() {
|
||||
@@ -1042,14 +879,13 @@ function FrameHandler(viewport) {
|
||||
this.setVisible(true);
|
||||
|
||||
getFramesAsArray().forEach(function (o) {
|
||||
o.dirty = true; // force objects cache to be rendered on next render http://fabricjs.com/docs/fabric.Object.html#dirty
|
||||
o.set(config.frames[frameType]);
|
||||
});
|
||||
|
||||
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 * _realFrameSizeCm * 10 * viewport.canvas.getImage().scaleX;
|
||||
|
||||
_frames.top.height =
|
||||
_frames.bottom.height =
|
||||
@@ -1106,7 +942,7 @@ function FrameHandler(viewport) {
|
||||
|
||||
module.exports = FrameHandler;
|
||||
|
||||
},{"./config":16}],9:[function(require,module,exports){
|
||||
},{"./config":15}],8:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
@@ -1187,7 +1023,7 @@ function GoreHandler(viewport) {
|
||||
|
||||
module.exports = GoreHandler;
|
||||
|
||||
},{}],10:[function(require,module,exports){
|
||||
},{}],9:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $ */
|
||||
|
||||
@@ -1265,7 +1101,7 @@ function ImageDataHandler(img) {
|
||||
|
||||
module.exports = ImageDataHandler;
|
||||
|
||||
},{}],11:[function(require,module,exports){
|
||||
},{}],10:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -1280,11 +1116,9 @@ function ImageEditor(canvasId, args) {
|
||||
type: 'wallpaper',
|
||||
// canvasFrameType defaults to image on frame
|
||||
canvasFrameType: 'image',
|
||||
canvasFrameSize: 2.9,
|
||||
canvasFrameSize: 2, //cm
|
||||
// Default texts on the buttons
|
||||
texts: {
|
||||
showThreeD: '3d',
|
||||
hideThreeD: 'Flat',
|
||||
showMurals: 'Show Murals Panel',
|
||||
hideMurals: 'Hide Murals Panel',
|
||||
showRulers: 'Show Ruler',
|
||||
@@ -1319,10 +1153,6 @@ function ImageEditor(canvasId, args) {
|
||||
// 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,
|
||||
@@ -1347,7 +1177,7 @@ function ImageEditor(canvasId, args) {
|
||||
_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() {
|
||||
$(_canvas.getSelectionElement().parentNode).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
|
||||
var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
|
||||
|
||||
if (isFullscreen) {
|
||||
@@ -1400,6 +1230,8 @@ function ImageEditor(canvasId, args) {
|
||||
_canvas.getApertures().setTransparent(false);
|
||||
}
|
||||
|
||||
_canvas.getDragbars().resetPosition();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -1469,7 +1301,7 @@ function ImageEditor(canvasId, args) {
|
||||
|
||||
module.exports = ImageEditor;
|
||||
|
||||
},{"./Canvas":4,"./util":25}],12:[function(require,module,exports){
|
||||
},{"./Canvas":3,"./util":24}],11:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function MirrorHandler(img) {
|
||||
@@ -1497,7 +1329,7 @@ function MirrorHandler(img) {
|
||||
|
||||
module.exports = MirrorHandler;
|
||||
|
||||
},{}],13:[function(require,module,exports){
|
||||
},{}],12:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
@@ -1634,7 +1466,7 @@ function RulerHandler(viewport) {
|
||||
|
||||
module.exports = RulerHandler;
|
||||
|
||||
},{"./TextButton":14,"./config":16,"./util":25}],14:[function(require,module,exports){
|
||||
},{"./TextButton":13,"./config":15,"./util":24}],13:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -1762,7 +1594,7 @@ TextButton.prototype.constructor = TextButton;
|
||||
|
||||
module.exports = TextButton;
|
||||
|
||||
},{"./config":16}],15:[function(require,module,exports){
|
||||
},{"./config":15}],14:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -1772,41 +1604,25 @@ var RulerHandler = require('./RulerHandler');
|
||||
var util = require('./util');
|
||||
|
||||
function Viewport(canvas) {
|
||||
var _beams = [];
|
||||
var _borderWidth = 2;
|
||||
var _borderWidth = 1;
|
||||
var _data = null;
|
||||
var _rect;
|
||||
var _baseImageScale = null; // Store the original image scale to avoid cumulative scaling
|
||||
var self = this;
|
||||
var viewportMargins = {
|
||||
vertical: 200,
|
||||
horizontal: 90,
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the diagonal lines from viewport to edge of the canvas
|
||||
*/
|
||||
function drawBeams() {
|
||||
_beams.forEach(function (beam) {
|
||||
canvas.remove(beam);
|
||||
});
|
||||
|
||||
_beams = [];
|
||||
|
||||
// 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 }));
|
||||
|
||||
_beams.forEach(function (o) {
|
||||
canvas.add(o);
|
||||
o.bringToFront();
|
||||
});
|
||||
* Calculate available canvas dimensions after margins
|
||||
* @return {Object} { width, height }
|
||||
*/
|
||||
function getAvailableCanvasDimensions() {
|
||||
return {
|
||||
width: canvas.width - viewportMargins.horizontal,
|
||||
height: canvas.height - viewportMargins.vertical,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1840,8 +1656,9 @@ function Viewport(canvas) {
|
||||
fill: 'transparent',
|
||||
width: _data.width,
|
||||
height: _data.height,
|
||||
stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff',
|
||||
stroke: canvas.__type === 'canvas' ? 'transparent' : '#343434',
|
||||
strokeWidth: _borderWidth,
|
||||
strokeUniform: true,
|
||||
});
|
||||
|
||||
_rect.width += _borderWidth;
|
||||
@@ -1869,9 +1686,7 @@ function Viewport(canvas) {
|
||||
canvas.getApertures().disable();
|
||||
}
|
||||
|
||||
if (canvas.__type !== 'canvas') {
|
||||
drawBeams();
|
||||
} else {
|
||||
if (canvas.__type === 'canvas') {
|
||||
self.setFrame(canvas.__canvasFrameType);
|
||||
}
|
||||
|
||||
@@ -1908,7 +1723,44 @@ function Viewport(canvas) {
|
||||
return this;
|
||||
}
|
||||
|
||||
_data = util.calcCrop(canvas.getImage(), width, height, units);
|
||||
var image = canvas.getImage();
|
||||
|
||||
// Store the base image scale on first call
|
||||
if (_baseImageScale === null) {
|
||||
_baseImageScale = {
|
||||
x: image.scaleX,
|
||||
y: image.scaleY,
|
||||
};
|
||||
}
|
||||
|
||||
// Reset image to base scale before calculating
|
||||
image.scaleX = _baseImageScale.x;
|
||||
image.scaleY = _baseImageScale.y;
|
||||
image.setCoords();
|
||||
|
||||
// First, calculate viewport with base image scale
|
||||
_data = util.calcCrop(image, width, height, units);
|
||||
|
||||
// Now calculate if we can scale up the image to better fill the canvas
|
||||
var availableDimensions = getAvailableCanvasDimensions();
|
||||
|
||||
// Calculate how much we can scale the viewport to fit within available space
|
||||
var scaleX = availableDimensions.width / _data.width;
|
||||
var scaleY = availableDimensions.height / _data.height;
|
||||
|
||||
// Use the smaller scale to ensure the viewport fits within the canvas
|
||||
var scaleFactor = Math.min(scaleX, scaleY);
|
||||
|
||||
// Apply scaling if needed (scale up to use more space, or scale down to fit)
|
||||
if (Math.abs(scaleFactor - 1.0) > 0.01) {
|
||||
// Apply the scale to the base scale (not multiplying current scale)
|
||||
image.scaleX = _baseImageScale.x * scaleFactor;
|
||||
image.scaleY = _baseImageScale.y * scaleFactor;
|
||||
image.setCoords();
|
||||
|
||||
// Recalculate viewport with the new image scale
|
||||
_data = util.calcCrop(image, width, height, units);
|
||||
}
|
||||
|
||||
var cropData = canvas.getImageData().getCropData();
|
||||
var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height));
|
||||
@@ -1939,17 +1791,7 @@ function Viewport(canvas) {
|
||||
*/
|
||||
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();
|
||||
|
||||
canvas.refresh3dView();
|
||||
};
|
||||
|
||||
this.getData = function () {
|
||||
@@ -1974,7 +1816,7 @@ function Viewport(canvas) {
|
||||
|
||||
module.exports = Viewport;
|
||||
|
||||
},{"./FrameHandler":8,"./GoreHandler":9,"./RulerHandler":13,"./util":25}],16:[function(require,module,exports){
|
||||
},{"./FrameHandler":7,"./GoreHandler":8,"./RulerHandler":12,"./util":24}],15:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -1986,7 +1828,7 @@ module.exports = {
|
||||
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){
|
||||
},{"./config/button-menu":16,"./config/drag-bar":17,"./config/drag-handle":18,"./config/frames":19,"./config/ruler-handle":20,"./config/text-button":21}],16:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2029,7 +1871,7 @@ module.exports = {
|
||||
|
||||
};
|
||||
|
||||
},{}],18:[function(require,module,exports){
|
||||
},{}],17:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2037,12 +1879,12 @@ module.exports = {
|
||||
size: 20,
|
||||
};
|
||||
|
||||
},{}],19:[function(require,module,exports){
|
||||
},{}],18:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
text: {
|
||||
fontFamily: 'breuer',
|
||||
fontFamily: 'Urbanist',
|
||||
fontSize: 12,
|
||||
fill: '#ffffff',
|
||||
originX: 'center',
|
||||
@@ -2055,7 +1897,7 @@ module.exports = {
|
||||
},
|
||||
};
|
||||
|
||||
},{}],20:[function(require,module,exports){
|
||||
},{}],19:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2084,7 +1926,7 @@ module.exports = {
|
||||
|
||||
};
|
||||
|
||||
},{}],21:[function(require,module,exports){
|
||||
},{}],20:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2133,7 +1975,7 @@ module.exports = {
|
||||
}
|
||||
};
|
||||
|
||||
},{}],22:[function(require,module,exports){
|
||||
},{}],21:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2155,7 +1997,7 @@ module.exports = {
|
||||
text: {
|
||||
fill: '#ffffff',
|
||||
disabledFill: '#999999',
|
||||
fontFamily: 'breuer',
|
||||
fontFamily: 'Urbanist',
|
||||
fontSize: 14,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
@@ -2163,10 +2005,10 @@ module.exports = {
|
||||
|
||||
cursor: 'pointer',
|
||||
disabledCursor: 'default',
|
||||
padding: 20,
|
||||
padding: 17,
|
||||
};
|
||||
|
||||
},{}],23:[function(require,module,exports){
|
||||
},{}],22:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, fabric */
|
||||
|
||||
@@ -2232,9 +2074,8 @@ function ExtendFabricFunctionality() {
|
||||
|
||||
module.exports = ExtendFabricFunctionality;
|
||||
|
||||
},{"./Draggable":7,"./util":25}],24:[function(require,module,exports){
|
||||
},{"./Draggable":6,"./util":24}],23:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals window */
|
||||
|
||||
(function() {
|
||||
|
||||
@@ -2253,7 +2094,7 @@ module.exports = ExtendFabricFunctionality;
|
||||
|
||||
}());
|
||||
|
||||
},{"./ImageEditor":11,"./extend-fabric-functionality":23}],25:[function(require,module,exports){
|
||||
},{"./ImageEditor":10,"./extend-fabric-functionality":22}],24:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
@@ -2271,7 +2112,7 @@ module.exports = {
|
||||
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){
|
||||
},{"./utils/assert-between":25,"./utils/assert-key-value-pair":26,"./utils/calc-crop":27,"./utils/is-aspect-changed":28,"./utils/is-fullscreen":29,"./utils/is-mobile":30,"./utils/mouse-metrics":31,"./utils/set-position-inside":32,"./utils/set-properties":33,"./utils/supports-fullscreen":34,"./utils/toggle-fullscreen":35}],25:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function assertBetween(value, min, max) {
|
||||
@@ -2286,7 +2127,7 @@ function assertBetween(value, min, max) {
|
||||
|
||||
module.exports = assertBetween;
|
||||
|
||||
},{}],27:[function(require,module,exports){
|
||||
},{}],26:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function assertKeyValuePair(key, value) {
|
||||
@@ -2302,7 +2143,7 @@ function assertKeyValuePair(key, value) {
|
||||
|
||||
module.exports = assertKeyValuePair;
|
||||
|
||||
},{}],28:[function(require,module,exports){
|
||||
},{}],27:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
@@ -2354,7 +2195,7 @@ function calcCrop(obj, width, height, units) {
|
||||
|
||||
module.exports = calcCrop;
|
||||
|
||||
},{}],29:[function(require,module,exports){
|
||||
},{}],28:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function isAspectChanged(x1, y1, x2, y2) {
|
||||
@@ -2363,7 +2204,7 @@ function isAspectChanged(x1, y1, x2, y2) {
|
||||
|
||||
module.exports = isAspectChanged;
|
||||
|
||||
},{}],30:[function(require,module,exports){
|
||||
},{}],29:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function isFullscreen() {
|
||||
@@ -2372,17 +2213,16 @@ function isFullscreen() {
|
||||
|
||||
module.exports = isFullscreen;
|
||||
|
||||
},{}],31:[function(require,module,exports){
|
||||
},{}],30:[function(require,module,exports){
|
||||
'use strict';
|
||||
/* globals $, window */
|
||||
|
||||
function isMobile() {
|
||||
return $(window).width() < 768;
|
||||
return window.innerWidth < 768;
|
||||
}
|
||||
|
||||
module.exports = isMobile;
|
||||
|
||||
},{}],32:[function(require,module,exports){
|
||||
},{}],31:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var MouseMetrics = {
|
||||
@@ -2408,7 +2248,7 @@ var MouseMetrics = {
|
||||
|
||||
module.exports = MouseMetrics;
|
||||
|
||||
},{}],33:[function(require,module,exports){
|
||||
},{}],32:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
@@ -2431,7 +2271,7 @@ function setPositionInside(obj, bounds) {
|
||||
|
||||
module.exports = setPositionInside;
|
||||
|
||||
},{}],34:[function(require,module,exports){
|
||||
},{}],33:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
@@ -2440,7 +2280,7 @@ module.exports = setPositionInside;
|
||||
*/
|
||||
function setProperties(obj, properties) {
|
||||
for (var o in properties) {
|
||||
if (properties.hasOwnProperty(o)) {
|
||||
if (Object.prototype.hasOwnProperty.call(properties, o) ) {
|
||||
Object.defineProperty(obj, o, properties[o]);
|
||||
}
|
||||
}
|
||||
@@ -2448,7 +2288,7 @@ function setProperties(obj, properties) {
|
||||
|
||||
module.exports = setProperties;
|
||||
|
||||
},{}],35:[function(require,module,exports){
|
||||
},{}],34:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
function supportsFullscreen() {
|
||||
@@ -2459,7 +2299,7 @@ function supportsFullscreen() {
|
||||
|
||||
module.exports = supportsFullscreen;
|
||||
|
||||
},{}],36:[function(require,module,exports){
|
||||
},{}],35:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var isFullscreen = require('./is-fullscreen');
|
||||
@@ -2494,4 +2334,4 @@ function toggleFullscreen(elem) {
|
||||
|
||||
module.exports = toggleFullscreen;
|
||||
|
||||
},{"./is-fullscreen":30}]},{},[24]);
|
||||
},{"./is-fullscreen":29}]},{},[23]);
|
||||
@@ -98,9 +98,9 @@
|
||||
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();
|
||||
var isMobile = window.innerWidth <= 767;
|
||||
var windowHeight = window.innerHeight;
|
||||
var windowWidth = window.innerWidth;
|
||||
|
||||
return {
|
||||
width: isFullScreen ? windowWidth : (isMobile ? windowWidth : $wrapper.width()),
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
|
||||
<script src="/dist/image-editor.js"></script>
|
||||
<script src="/dist/generated-image-editor.js"></script>
|
||||
<script src="/examples/basic/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
|
||||
<script src="../../dist/image-editor.js"></script>
|
||||
<script src="../../dist/generated-image-editor.js"></script>
|
||||
<script type="text/javascript">
|
||||
var width = document.getElementById('width');
|
||||
var height = document.getElementById('height');
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
|
||||
<script src="../../dist/image-editor.js"></script>
|
||||
<script src="../../dist/generated-image-editor.js"></script>
|
||||
<script type="text/javascript">
|
||||
var width = document.getElementById('width');
|
||||
var height = document.getElementById('height');
|
||||
|
||||
+7
-7
@@ -9,7 +9,7 @@ var eslint = require('gulp-eslint');
|
||||
var qunit = require('gulp-qunit');
|
||||
var mkdirp = require('mkdirp');
|
||||
var del = require('del');
|
||||
var runSequence = require('run-sequence');
|
||||
var runSequence = require('gulp4-run-sequence');
|
||||
|
||||
var outputPath = './dist';
|
||||
|
||||
@@ -24,21 +24,21 @@ gulp.task('build', function (done) {
|
||||
|
||||
gulp.task('clean-dist', function () { return del(outputPath); });
|
||||
|
||||
gulp.task('create-dist', function () { return mkdirp(outputPath); });
|
||||
gulp.task('create-dist', function (done) { return mkdirp(outputPath, done); });
|
||||
|
||||
gulp.task('compile', function() {
|
||||
return browserify('./src/main.js')
|
||||
.bundle()
|
||||
.pipe(source('main.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(rename('image-editor.js'))
|
||||
.pipe(rename('generated-image-editor.js'))
|
||||
.pipe(gulp.dest(outputPath));
|
||||
});
|
||||
|
||||
gulp.task('test', ['compile'], function() {
|
||||
gulp.task('test', gulp.series('compile', function() {
|
||||
return gulp.src('./test/index.html')
|
||||
.pipe(qunit({timeout: 1}));
|
||||
});
|
||||
}));
|
||||
|
||||
gulp.task('lint', function() {
|
||||
return gulp.src(['./src/**/*.js', './test/unit/*.js'])
|
||||
@@ -48,7 +48,7 @@ gulp.task('lint', function() {
|
||||
});
|
||||
|
||||
gulp.task('watch', function() {
|
||||
gulp.watch('./src/**/*.js', ['lint', 'compile']);
|
||||
gulp.watch('./src/**/*.js', gulp.series('lint', 'compile'));
|
||||
});
|
||||
|
||||
gulp.task('default', ['build']);
|
||||
gulp.task('default', gulp.series('build'));
|
||||
|
||||
Generated
+3134
-1312
File diff suppressed because it is too large
Load Diff
+15
-9
@@ -7,21 +7,27 @@
|
||||
"url": "git@github.com:Photowall/image-editor.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^13.1.1",
|
||||
"browserify": "^16.5.1",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^5.14.1",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-eslint": "^5.0.0",
|
||||
"gulp-qunit": "^1.5.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-eslint": "^6.0.0",
|
||||
"gulp-qunit": "^2.1.1",
|
||||
"gulp-rename": "^2.0.0",
|
||||
"gulp4-run-sequence": "^1.0.1",
|
||||
"jshint": "^2.9.5",
|
||||
"live-server": "^1.2.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"qunit": "^1.0.0",
|
||||
"run-sequence": "^2.2.1",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"vinyl-source-stream": "^2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint gulpfile.js 'examples/**/*.js' 'test/unit/**/*.js' 'src/**/*.js'"
|
||||
"lint": "eslint gulpfile.js 'examples/**/*.js' 'test/unit/**/*.js' 'src/**/*.js'",
|
||||
"serve": "live-server --ignore=node_modules --port=50994 ./",
|
||||
"watch": "gulp watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"jquery": "^2.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
'use strict';
|
||||
/* globals fabric */
|
||||
|
||||
/**
|
||||
* Handles 3d image of canvas products.
|
||||
* @param {canvas} canvas
|
||||
*/
|
||||
function ThreeDHandler(canvas) {
|
||||
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,
|
||||
}));
|
||||
|
||||
canvas.add(_overlay);
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
/**
|
||||
* Disables the 3d image by removing visibility
|
||||
* @return {ThreeDHandler}
|
||||
*/
|
||||
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();
|
||||
|
||||
canvas.getButtonMenu().bringToFront();
|
||||
canvas.renderAll();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if 3d mode is enabled/visible.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
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.applyImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* (Re)adds the new/existing image with new configuration to the overlay.
|
||||
* @param {img}
|
||||
*/
|
||||
this.applyImage = function(img) {
|
||||
img = img || _image;
|
||||
|
||||
_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.applyImage(img);
|
||||
return this.enable();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
module.exports = ThreeDHandler;
|
||||
+5
-70
@@ -7,10 +7,10 @@ var ApertureHandler = require('./ApertureHandler');
|
||||
var ButtonMenu = require('./ButtonMenu');
|
||||
var DragbarHandler = require('./DragbarHandler');
|
||||
var Viewport = require('./Viewport');
|
||||
var ThreeDHandler = require('./3dHandler');
|
||||
var MirrorHandler = require('./MirrorHandler');
|
||||
var ImageDataHandler = require('./ImageDataHandler');
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var $document = $(document);
|
||||
|
||||
/**
|
||||
@@ -26,11 +26,11 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
// Allow touch scrolling on touch-devices larger than mobile screen sizes.
|
||||
allowTouchScrolling: !util.isMobile(),
|
||||
stateful: false,
|
||||
backgroundColor: '#ededed',
|
||||
backgroundColor: '#ffffff',
|
||||
preserveObjectStacking: true,
|
||||
selection: false,
|
||||
width: dimensions.width,
|
||||
height: dimensions.height
|
||||
height: dimensions.height,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -43,12 +43,8 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
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.refreshImage(this.getResizedImage(this.getImage()));
|
||||
this.getViewport().reset();
|
||||
this.sendToBack(this.getImage());
|
||||
this.getImage().center();
|
||||
this.getDragbars().resetPosition();
|
||||
@@ -69,33 +65,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
return this;
|
||||
},
|
||||
|
||||
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,
|
||||
'no-cache=1',
|
||||
];
|
||||
|
||||
if (imageData.mirrored) {
|
||||
params.push('mirror=1');
|
||||
}
|
||||
|
||||
return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&');
|
||||
},
|
||||
|
||||
getApertures: function () {
|
||||
return this.__aperturehandler ||
|
||||
(this.__aperturehandler = new ApertureHandler(this));
|
||||
@@ -153,17 +122,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
return this.__buttonMenu;
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads the 3D view, if it is present
|
||||
* @return {Canvas}
|
||||
*/
|
||||
refresh3dView: function () {
|
||||
if (this.get3dHandler().isEnabled()) {
|
||||
this.toggle3D(true);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {Canvas}
|
||||
*/
|
||||
@@ -197,8 +155,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
},
|
||||
|
||||
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;
|
||||
|
||||
@@ -207,27 +163,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
|
||||
|
||||
return img;
|
||||
},
|
||||
|
||||
toggle3D: function (showAs3d) {
|
||||
|
||||
this.getButtonMenu().setButtonActive('toggle3d', showAs3d);
|
||||
|
||||
if (!showAs3d) {
|
||||
return this.get3dHandler().disable();
|
||||
}
|
||||
|
||||
$document.trigger('PIE:image-start-load');
|
||||
|
||||
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));
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Canvas;
|
||||
|
||||
@@ -123,6 +123,9 @@ var DragHandle = function (handler) {
|
||||
heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
|
||||
}
|
||||
|
||||
widthToDisplay = Math.round((widthToDisplay + Number.EPSILON) * 10) / 10;
|
||||
heightToDisplay = Math.round((heightToDisplay + Number.EPSILON) * 10) / 10;
|
||||
|
||||
this.__handles = {
|
||||
x: getRect(widthToDisplay + ' ' + unit, handleWidth),
|
||||
y: getRect(heightToDisplay + ' ' + unit, handleHeight)
|
||||
|
||||
+32
-24
@@ -84,34 +84,42 @@ function DragbarHandler(canvas) {
|
||||
this.init = function () {
|
||||
this.clear();
|
||||
var typeIsWallpaper = canvas.__type === 'wallpaper';
|
||||
var image = canvas.getImage();
|
||||
|
||||
_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',
|
||||
}))
|
||||
_dragbars.x = new fabric.Rect(
|
||||
$.extend({}, config.dragBar, {
|
||||
axis: 'x',
|
||||
width: image.width * image.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();
|
||||
.centerH()
|
||||
.set({ top: image.height + 10 })
|
||||
.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',
|
||||
}))
|
||||
_dragbars.y = new fabric.Rect(
|
||||
$.extend({}, config.dragBar, {
|
||||
axis: 'y',
|
||||
width: config.dragBar.size,
|
||||
height: image.height * image.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();
|
||||
.set({ left: canvas.width - 30 })
|
||||
.setCoords();
|
||||
|
||||
canvas.getImage().on('moving', this.sync);
|
||||
|
||||
|
||||
+3
-3
@@ -6,6 +6,7 @@ var config = require('./config');
|
||||
function FrameHandler(viewport) {
|
||||
var _frames;
|
||||
var _frameType = viewport.canvas.__canvasFrameType;
|
||||
var _realFrameSizeCm = viewport.canvas.__canvasFrameSize;
|
||||
var _frameSize;
|
||||
|
||||
function getFramesAsArray() {
|
||||
@@ -84,14 +85,13 @@ function FrameHandler(viewport) {
|
||||
this.setVisible(true);
|
||||
|
||||
getFramesAsArray().forEach(function (o) {
|
||||
o.dirty = true; // force objects cache to be rendered on next render http://fabricjs.com/docs/fabric.Object.html#dirty
|
||||
o.set(config.frames[frameType]);
|
||||
});
|
||||
|
||||
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 * _realFrameSizeCm * 10 * viewport.canvas.getImage().scaleX;
|
||||
|
||||
_frames.top.height =
|
||||
_frames.bottom.height =
|
||||
|
||||
@@ -63,6 +63,10 @@ function ImageDataHandler(img) {
|
||||
var frameHandler = img.canvas.getViewport().getFrameHandler();
|
||||
returnValue.edge = frameHandler.getFrameType();
|
||||
returnValue.framed = returnValue.edge !== 'none';
|
||||
} else if (img.canvas.__type === 'wallpaper') {
|
||||
// repeating wallpapers should not have any cropping
|
||||
returnValue.x = 0;
|
||||
returnValue.y = 0;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
|
||||
+4
-8
@@ -12,11 +12,9 @@ function ImageEditor(canvasId, args) {
|
||||
type: 'wallpaper',
|
||||
// canvasFrameType defaults to image on frame
|
||||
canvasFrameType: 'image',
|
||||
canvasFrameSize: 2.9,
|
||||
canvasFrameSize: 2, //cm
|
||||
// Default texts on the buttons
|
||||
texts: {
|
||||
showThreeD: '3d',
|
||||
hideThreeD: 'Flat',
|
||||
showMurals: 'Show Murals Panel',
|
||||
hideMurals: 'Hide Murals Panel',
|
||||
showRulers: 'Show Ruler',
|
||||
@@ -51,10 +49,6 @@ function ImageEditor(canvasId, args) {
|
||||
// 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,
|
||||
@@ -79,7 +73,7 @@ function ImageEditor(canvasId, args) {
|
||||
_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() {
|
||||
$(_canvas.getSelectionElement().parentNode).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
|
||||
var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
|
||||
|
||||
if (isFullscreen) {
|
||||
@@ -132,6 +126,8 @@ function ImageEditor(canvasId, args) {
|
||||
_canvas.getApertures().setTransparent(false);
|
||||
}
|
||||
|
||||
_canvas.getDragbars().resetPosition();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
+55
-45
@@ -7,41 +7,25 @@ var RulerHandler = require('./RulerHandler');
|
||||
var util = require('./util');
|
||||
|
||||
function Viewport(canvas) {
|
||||
var _beams = [];
|
||||
var _borderWidth = 2;
|
||||
var _borderWidth = 1;
|
||||
var _data = null;
|
||||
var _rect;
|
||||
var _baseImageScale = null; // Store the original image scale to avoid cumulative scaling
|
||||
var self = this;
|
||||
var viewportMargins = {
|
||||
vertical: 200,
|
||||
horizontal: 90,
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the diagonal lines from viewport to edge of the canvas
|
||||
*/
|
||||
function drawBeams() {
|
||||
_beams.forEach(function (beam) {
|
||||
canvas.remove(beam);
|
||||
});
|
||||
|
||||
_beams = [];
|
||||
|
||||
// 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 }));
|
||||
|
||||
_beams.forEach(function (o) {
|
||||
canvas.add(o);
|
||||
o.bringToFront();
|
||||
});
|
||||
* Calculate available canvas dimensions after margins
|
||||
* @return {Object} { width, height }
|
||||
*/
|
||||
function getAvailableCanvasDimensions() {
|
||||
return {
|
||||
width: canvas.width - viewportMargins.horizontal,
|
||||
height: canvas.height - viewportMargins.vertical,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,8 +59,9 @@ function Viewport(canvas) {
|
||||
fill: 'transparent',
|
||||
width: _data.width,
|
||||
height: _data.height,
|
||||
stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff',
|
||||
stroke: canvas.__type === 'canvas' ? 'transparent' : '#343434',
|
||||
strokeWidth: _borderWidth,
|
||||
strokeUniform: true,
|
||||
});
|
||||
|
||||
_rect.width += _borderWidth;
|
||||
@@ -104,9 +89,7 @@ function Viewport(canvas) {
|
||||
canvas.getApertures().disable();
|
||||
}
|
||||
|
||||
if (canvas.__type !== 'canvas') {
|
||||
drawBeams();
|
||||
} else {
|
||||
if (canvas.__type === 'canvas') {
|
||||
self.setFrame(canvas.__canvasFrameType);
|
||||
}
|
||||
|
||||
@@ -143,7 +126,44 @@ function Viewport(canvas) {
|
||||
return this;
|
||||
}
|
||||
|
||||
_data = util.calcCrop(canvas.getImage(), width, height, units);
|
||||
var image = canvas.getImage();
|
||||
|
||||
// Store the base image scale on first call
|
||||
if (_baseImageScale === null) {
|
||||
_baseImageScale = {
|
||||
x: image.scaleX,
|
||||
y: image.scaleY,
|
||||
};
|
||||
}
|
||||
|
||||
// Reset image to base scale before calculating
|
||||
image.scaleX = _baseImageScale.x;
|
||||
image.scaleY = _baseImageScale.y;
|
||||
image.setCoords();
|
||||
|
||||
// First, calculate viewport with base image scale
|
||||
_data = util.calcCrop(image, width, height, units);
|
||||
|
||||
// Now calculate if we can scale up the image to better fill the canvas
|
||||
var availableDimensions = getAvailableCanvasDimensions();
|
||||
|
||||
// Calculate how much we can scale the viewport to fit within available space
|
||||
var scaleX = availableDimensions.width / _data.width;
|
||||
var scaleY = availableDimensions.height / _data.height;
|
||||
|
||||
// Use the smaller scale to ensure the viewport fits within the canvas
|
||||
var scaleFactor = Math.min(scaleX, scaleY);
|
||||
|
||||
// Apply scaling if needed (scale up to use more space, or scale down to fit)
|
||||
if (Math.abs(scaleFactor - 1.0) > 0.01) {
|
||||
// Apply the scale to the base scale (not multiplying current scale)
|
||||
image.scaleX = _baseImageScale.x * scaleFactor;
|
||||
image.scaleY = _baseImageScale.y * scaleFactor;
|
||||
image.setCoords();
|
||||
|
||||
// Recalculate viewport with the new image scale
|
||||
_data = util.calcCrop(image, width, height, units);
|
||||
}
|
||||
|
||||
var cropData = canvas.getImageData().getCropData();
|
||||
var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height));
|
||||
@@ -174,17 +194,7 @@ function Viewport(canvas) {
|
||||
*/
|
||||
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();
|
||||
|
||||
canvas.refresh3dView();
|
||||
};
|
||||
|
||||
this.getData = function () {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
module.exports = {
|
||||
text: {
|
||||
fontFamily: 'breuer',
|
||||
fontFamily: 'Urbanist',
|
||||
fontSize: 12,
|
||||
fill: '#ffffff',
|
||||
originX: 'center',
|
||||
|
||||
@@ -19,7 +19,7 @@ module.exports = {
|
||||
text: {
|
||||
fill: '#ffffff',
|
||||
disabledFill: '#999999',
|
||||
fontFamily: 'breuer',
|
||||
fontFamily: 'Urbanist',
|
||||
fontSize: 14,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
@@ -27,5 +27,5 @@ module.exports = {
|
||||
|
||||
cursor: 'pointer',
|
||||
disabledCursor: 'default',
|
||||
padding: 20,
|
||||
padding: 17,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
'use strict';
|
||||
/* globals window */
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
/* globals $, window */
|
||||
|
||||
function isMobile() {
|
||||
return $(window).width() < 768;
|
||||
return window.innerWidth < 768;
|
||||
}
|
||||
|
||||
module.exports = isMobile;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
function setProperties(obj, properties) {
|
||||
for (var o in properties) {
|
||||
if (properties.hasOwnProperty(o)) {
|
||||
if (Object.prototype.hasOwnProperty.call(properties, o) ) {
|
||||
Object.defineProperty(obj, o, properties[o]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
<script src="vendor/qunit.js"></script>
|
||||
<script src="vendor/fabric.js"></script>
|
||||
<script src="vendor/jquery.js"></script>
|
||||
<script src="../dist/image-editor.js"></script>
|
||||
<script src="../dist/generated-image-editor.js"></script>
|
||||
<script src="unit/image-editor.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
QUnit.test('crop image', function(assert) {
|
||||
var done = assert.async();
|
||||
var editor = new ImageEditor('canvas');
|
||||
var editor = new ImageEditor('canvas', {type: 'photo-wallpaper'});
|
||||
editor.loadImage('fixtures/dog.jpg', function() {
|
||||
editor.crop(400, 200, 'cm');
|
||||
var data = editor.canvas.getImageData().getData();
|
||||
@@ -27,4 +27,18 @@
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('repeating wallpaper has x and y set to 0', function(assert) {
|
||||
var done = assert.async();
|
||||
var editor = new ImageEditor('canvas', {type: 'wallpaper'});
|
||||
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, 0, 'sets crop y');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user