remove 3d toggle button in canvas product page (#12)

* Max changes from f0ecf9dd4c7503c1562fcadb54ce61873b1f7c6f in photowall repo

* Erik's changes from 50af018a07dcea44d755bcc23e84537db90f321a in photowall repo

* Update image-editor.js in README.md

* Prettify

* Max changes from f0ecf9dd4c7503c1562fcadb54ce61873b1f7c6f in photowall repo in output

* Erik's changes from 50af018a07dcea44d755bcc23e84537db90f321a in photowall repo in output

* Remove "Show 3d image" button and functionality

* Output image-editor.js file

* Rename the outputted file from image-editor.js to generated-image-editor.js

* Output again the file that time as generated-image-editor.js

* Update README.md

* Remove comma / lint
This commit is contained in:
Balthazar Berling Kelpe
2026-03-25 10:43:59 +01:00
committed by GitHub
parent 96b4064986
commit 37fd36275a
14 changed files with 242 additions and 495 deletions
+7 -6
View File
@@ -1,16 +1,17 @@
Photowall Image Editor # Photowall Image Editor
======================
Image editor for the Photowall web project Image editor for the Photowall web project
# Working with image-editor integrated in photowall site # Working with image-editor integrated in photowall site
A suggested workflow is replacing `src/js/legacy/legacyVendor/image-editor.js` in photowall project with a symlink to
`dist/image-editor.js` in this project. That way you can have `gulp watch` running to build on change in this project 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. which will trigger `npm run watch` (webpack) in photowall project.
Symlink should be removed and new copy of `dist/image-editor.js` copied to photowall project when work 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. is done however to not force all team members to have same file structure for projects.
# Linting # Linting
Linting can be run manually with Linting can be run manually with
`npm run lint` `npm run lint`
+133 -259
View File
@@ -2,116 +2,6 @@
'use strict'; 'use strict';
/* globals fabric */ /* 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){
'use strict';
/* globals fabric */
/** /**
* ApertureHandler takes care of the bars around the image to show what area has been/will be cropped. * ApertureHandler takes care of the bars around the image to show what area has been/will be cropped.
* @param {canvas} canvas * @param {canvas} canvas
@@ -209,7 +99,7 @@ function ApertureHandler(canvas) {
module.exports = ApertureHandler; module.exports = ApertureHandler;
},{}],3:[function(require,module,exports){ },{}],2:[function(require,module,exports){
'use strict'; 'use strict';
var TextButton = require('./TextButton'); var TextButton = require('./TextButton');
@@ -362,7 +252,7 @@ function ButtonMenu(canvas, settings) {
module.exports = ButtonMenu; module.exports = ButtonMenu;
},{"./TextButton":14}],4:[function(require,module,exports){ },{"./TextButton":13}],3:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -372,10 +262,10 @@ var ApertureHandler = require('./ApertureHandler');
var ButtonMenu = require('./ButtonMenu'); var ButtonMenu = require('./ButtonMenu');
var DragbarHandler = require('./DragbarHandler'); var DragbarHandler = require('./DragbarHandler');
var Viewport = require('./Viewport'); var Viewport = require('./Viewport');
var ThreeDHandler = require('./3dHandler');
var MirrorHandler = require('./MirrorHandler'); var MirrorHandler = require('./MirrorHandler');
var ImageDataHandler = require('./ImageDataHandler'); var ImageDataHandler = require('./ImageDataHandler');
// eslint-disable-next-line no-unused-vars
var $document = $(document); 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. // Allow touch scrolling on touch-devices larger than mobile screen sizes.
allowTouchScrolling: !util.isMobile(), allowTouchScrolling: !util.isMobile(),
stateful: false, stateful: false,
backgroundColor: '#ededed', backgroundColor: '#ffffff',
preserveObjectStacking: true, preserveObjectStacking: true,
selection: false, selection: false,
width: dimensions.width, width: dimensions.width,
height: dimensions.height height: dimensions.height,
}); });
}, },
@@ -405,15 +295,13 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return; return;
} }
// hello
this.setHeight(args.height); this.setHeight(args.height);
this.setWidth(args.width); this.setWidth(args.width);
this.getButtonMenu().render(); this.getButtonMenu().render();
if (this.get3dHandler().isEnabled()) { this.refreshImage(this.getResizedImage(this.getImage()));
this.get3dHandler().refreshImage(); this.getViewport().reset();
} else {
this.refreshImage(this.getResizedImage(this.getImage()));
this.getViewport().reset();
}
this.sendToBack(this.getImage()); this.sendToBack(this.getImage());
this.getImage().center(); this.getImage().center();
this.getDragbars().resetPosition(); this.getDragbars().resetPosition();
@@ -434,33 +322,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return this; 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 () { getApertures: function () {
return this.__aperturehandler || return this.__aperturehandler ||
(this.__aperturehandler = new ApertureHandler(this)); (this.__aperturehandler = new ApertureHandler(this));
@@ -518,17 +379,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return this.__buttonMenu; 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} * @return {Canvas}
*/ */
@@ -562,8 +412,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
}, },
getResizedImage: function(img) { 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 maxHeight = this.getHeight() - 100;
var maxWidth = this.getWidth() - 100; var maxWidth = this.getWidth() - 100;
@@ -572,32 +420,11 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return img; 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; 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'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -748,7 +575,7 @@ var DragHandle = function (handler) {
module.exports = DragHandle; module.exports = DragHandle;
},{"./config":16,"./util":25}],6:[function(require,module,exports){ },{"./config":15,"./util":24}],5:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -835,34 +662,42 @@ function DragbarHandler(canvas) {
this.init = function () { this.init = function () {
this.clear(); this.clear();
var typeIsWallpaper = canvas.__type === 'wallpaper'; var typeIsWallpaper = canvas.__type === 'wallpaper';
var image = canvas.getImage();
_dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.x = new fabric.Rect(
axis: 'x', $.extend({}, config.dragBar, {
width: canvas.getImage().width * canvas.getImage().scaleY, axis: 'x',
height: config.dragBar.size, width: image.width * image.scaleY,
lockMovementY: true, height: config.dragBar.size,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) lockMovementY: true,
lockMovementX: typeIsWallpaper, // Movement should also be disabled when the user is on wallpaper (repeating paterns)
selectable: true, lockMovementX: typeIsWallpaper,
hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', selectable: true,
moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
})) moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
})
)
.addTo(canvas) .addTo(canvas)
.centerH().set({ top: canvas.height - 30 }).setCoords(); .centerH()
.set({ top: image.height + 10 })
.setCoords();
_dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.y = new fabric.Rect(
axis: 'y', $.extend({}, config.dragBar, {
width: config.dragBar.size, axis: 'y',
height: canvas.getImage().height * canvas.getImage().scaleY, width: config.dragBar.size,
lockMovementX: true, height: image.height * image.scaleY,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) lockMovementX: true,
lockMovementY: typeIsWallpaper, // Movement should also be disabled when the user is on wallpaper (repeating paterns)
selectable: true, lockMovementY: typeIsWallpaper,
hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', selectable: true,
moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', hoverCursor: typeIsWallpaper ? 'pointer' : 'ns-resize',
})) moveCursor: typeIsWallpaper ? 'pointer' : 'ns-resize',
})
)
.addTo(canvas) .addTo(canvas)
.set({ left: canvas.width - 30 }).setCoords(); .set({ left: canvas.width - 30 })
.setCoords();
canvas.getImage().on('moving', this.sync); canvas.getImage().on('moving', this.sync);
@@ -881,7 +716,7 @@ function DragbarHandler(canvas) {
module.exports = DragbarHandler; module.exports = DragbarHandler;
},{"./DragHandle":5,"./config":16}],7:[function(require,module,exports){ },{"./DragHandle":4,"./config":15}],6:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $ */ /* globals $ */
var util = require('./util'); var util = require('./util');
@@ -958,7 +793,7 @@ function Draggable(img, boundingRect) {
module.exports = Draggable; module.exports = Draggable;
},{"./util":25}],8:[function(require,module,exports){ },{"./util":24}],7:[function(require,module,exports){
'use strict'; 'use strict';
/* globals fabric */ /* globals fabric */
@@ -1109,7 +944,7 @@ function FrameHandler(viewport) {
module.exports = FrameHandler; module.exports = FrameHandler;
},{"./config":16}],9:[function(require,module,exports){ },{"./config":15}],8:[function(require,module,exports){
'use strict'; 'use strict';
/* globals fabric */ /* globals fabric */
@@ -1190,7 +1025,7 @@ function GoreHandler(viewport) {
module.exports = GoreHandler; module.exports = GoreHandler;
},{}],10:[function(require,module,exports){ },{}],9:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $ */ /* globals $ */
@@ -1268,7 +1103,7 @@ function ImageDataHandler(img) {
module.exports = ImageDataHandler; module.exports = ImageDataHandler;
},{}],11:[function(require,module,exports){ },{}],10:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -1286,8 +1121,6 @@ function ImageEditor(canvasId, args) {
canvasFrameSize: 2, //cm canvasFrameSize: 2, //cm
// Default texts on the buttons // Default texts on the buttons
texts: { texts: {
showThreeD: '3d',
hideThreeD: 'Flat',
showMurals: 'Show Murals Panel', showMurals: 'Show Murals Panel',
hideMurals: 'Hide Murals Panel', hideMurals: 'Hide Murals Panel',
showRulers: 'Show Ruler', showRulers: 'Show Ruler',
@@ -1322,10 +1155,6 @@ function ImageEditor(canvasId, args) {
// It might be better that this resides somewhere else, either in Canvas or // It might be better that this resides somewhere else, either in Canvas or
// during the initialization of the image editor. // during the initialization of the image editor.
if (_canvas.__type === 'canvas') { if (_canvas.__type === 'canvas') {
_canvas.getButtonMenu()
.addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () {
_canvas.toggle3D(this.isActive());
});
_canvas.set({ _canvas.set({
__canvasFrameType: _settings.canvasFrameType, __canvasFrameType: _settings.canvasFrameType,
__canvasFrameSize: _settings.canvasFrameSize, __canvasFrameSize: _settings.canvasFrameSize,
@@ -1403,6 +1232,8 @@ function ImageEditor(canvasId, args) {
_canvas.getApertures().setTransparent(false); _canvas.getApertures().setTransparent(false);
} }
_canvas.getDragbars().resetPosition();
return this; return this;
}; };
@@ -1472,7 +1303,7 @@ function ImageEditor(canvasId, args) {
module.exports = ImageEditor; module.exports = ImageEditor;
},{"./Canvas":4,"./util":25}],12:[function(require,module,exports){ },{"./Canvas":3,"./util":24}],11:[function(require,module,exports){
'use strict'; 'use strict';
function MirrorHandler(img) { function MirrorHandler(img) {
@@ -1500,7 +1331,7 @@ function MirrorHandler(img) {
module.exports = MirrorHandler; module.exports = MirrorHandler;
},{}],13:[function(require,module,exports){ },{}],12:[function(require,module,exports){
'use strict'; 'use strict';
/* globals fabric */ /* globals fabric */
@@ -1637,7 +1468,7 @@ function RulerHandler(viewport) {
module.exports = RulerHandler; 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'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -1765,7 +1596,7 @@ TextButton.prototype.constructor = TextButton;
module.exports = TextButton; module.exports = TextButton;
},{"./config":16}],15:[function(require,module,exports){ },{"./config":15}],14:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -1779,7 +1610,23 @@ function Viewport(canvas) {
var _borderWidth = 2; var _borderWidth = 2;
var _data = null; var _data = null;
var _rect; var _rect;
var _baseImageScale = null; // Store the original image scale to avoid cumulative scaling
var self = this; var self = this;
var viewportMargins = {
vertical: 200,
horizontal: 90,
};
/**
* Calculate available canvas dimensions after margins
* @return {Object} { width, height }
*/
function getAvailableCanvasDimensions() {
return {
width: canvas.width - viewportMargins.horizontal,
height: canvas.height - viewportMargins.vertical,
};
}
/** /**
* Render the diagonal lines from viewport to edge of the canvas * Render the diagonal lines from viewport to edge of the canvas
@@ -1911,7 +1758,44 @@ function Viewport(canvas) {
return this; 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 cropData = canvas.getImageData().getCropData();
var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height));
@@ -1942,17 +1826,7 @@ function Viewport(canvas) {
*/ */
this.setFrame = function (frameType) { this.setFrame = function (frameType) {
this.getFrameHandler().setFrames(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.getButtonMenu().bringToFront();
canvas.refresh3dView();
}; };
this.getData = function () { this.getData = function () {
@@ -1977,7 +1851,7 @@ function Viewport(canvas) {
module.exports = Viewport; 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'; 'use strict';
module.exports = { module.exports = {
@@ -1989,7 +1863,7 @@ module.exports = {
dragBar: require('./config/drag-bar') 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'; 'use strict';
module.exports = { module.exports = {
@@ -2032,7 +1906,7 @@ module.exports = {
}; };
},{}],18:[function(require,module,exports){ },{}],17:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
@@ -2040,12 +1914,12 @@ module.exports = {
size: 20, size: 20,
}; };
},{}],19:[function(require,module,exports){ },{}],18:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
text: { text: {
fontFamily: 'breuer', fontFamily: 'Urbanist',
fontSize: 12, fontSize: 12,
fill: '#ffffff', fill: '#ffffff',
originX: 'center', originX: 'center',
@@ -2058,7 +1932,7 @@ module.exports = {
}, },
}; };
},{}],20:[function(require,module,exports){ },{}],19:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
@@ -2087,7 +1961,7 @@ module.exports = {
}; };
},{}],21:[function(require,module,exports){ },{}],20:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
@@ -2136,7 +2010,7 @@ module.exports = {
} }
}; };
},{}],22:[function(require,module,exports){ },{}],21:[function(require,module,exports){
'use strict'; 'use strict';
module.exports = { module.exports = {
@@ -2158,7 +2032,7 @@ module.exports = {
text: { text: {
fill: '#ffffff', fill: '#ffffff',
disabledFill: '#999999', disabledFill: '#999999',
fontFamily: 'breuer', fontFamily: 'Urbanist',
fontSize: 14, fontSize: 14,
originX: 'center', originX: 'center',
originY: 'center', originY: 'center',
@@ -2166,10 +2040,10 @@ module.exports = {
cursor: 'pointer', cursor: 'pointer',
disabledCursor: 'default', disabledCursor: 'default',
padding: 20, padding: 17,
}; };
},{}],23:[function(require,module,exports){ },{}],22:[function(require,module,exports){
'use strict'; 'use strict';
/* globals $, fabric */ /* globals $, fabric */
@@ -2235,7 +2109,7 @@ function ExtendFabricFunctionality() {
module.exports = ExtendFabricFunctionality; module.exports = ExtendFabricFunctionality;
},{"./Draggable":7,"./util":25}],24:[function(require,module,exports){ },{"./Draggable":6,"./util":24}],23:[function(require,module,exports){
'use strict'; 'use strict';
(function() { (function() {
@@ -2255,7 +2129,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'; 'use strict';
module.exports = { module.exports = {
@@ -2273,7 +2147,7 @@ module.exports = {
isAspectChanged: require('./utils/is-aspect-changed'), 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'; 'use strict';
function assertBetween(value, min, max) { function assertBetween(value, min, max) {
@@ -2288,7 +2162,7 @@ function assertBetween(value, min, max) {
module.exports = assertBetween; module.exports = assertBetween;
},{}],27:[function(require,module,exports){ },{}],26:[function(require,module,exports){
'use strict'; 'use strict';
function assertKeyValuePair(key, value) { function assertKeyValuePair(key, value) {
@@ -2304,7 +2178,7 @@ function assertKeyValuePair(key, value) {
module.exports = assertKeyValuePair; module.exports = assertKeyValuePair;
},{}],28:[function(require,module,exports){ },{}],27:[function(require,module,exports){
'use strict'; 'use strict';
/** /**
@@ -2356,7 +2230,7 @@ function calcCrop(obj, width, height, units) {
module.exports = calcCrop; module.exports = calcCrop;
},{}],29:[function(require,module,exports){ },{}],28:[function(require,module,exports){
'use strict'; 'use strict';
function isAspectChanged(x1, y1, x2, y2) { function isAspectChanged(x1, y1, x2, y2) {
@@ -2365,7 +2239,7 @@ function isAspectChanged(x1, y1, x2, y2) {
module.exports = isAspectChanged; module.exports = isAspectChanged;
},{}],30:[function(require,module,exports){ },{}],29:[function(require,module,exports){
'use strict'; 'use strict';
function isFullscreen() { function isFullscreen() {
@@ -2374,7 +2248,7 @@ function isFullscreen() {
module.exports = isFullscreen; module.exports = isFullscreen;
},{}],31:[function(require,module,exports){ },{}],30:[function(require,module,exports){
'use strict'; 'use strict';
function isMobile() { function isMobile() {
@@ -2383,7 +2257,7 @@ function isMobile() {
module.exports = isMobile; module.exports = isMobile;
},{}],32:[function(require,module,exports){ },{}],31:[function(require,module,exports){
'use strict'; 'use strict';
var MouseMetrics = { var MouseMetrics = {
@@ -2409,7 +2283,7 @@ var MouseMetrics = {
module.exports = MouseMetrics; module.exports = MouseMetrics;
},{}],33:[function(require,module,exports){ },{}],32:[function(require,module,exports){
'use strict'; 'use strict';
/** /**
@@ -2432,7 +2306,7 @@ function setPositionInside(obj, bounds) {
module.exports = setPositionInside; module.exports = setPositionInside;
},{}],34:[function(require,module,exports){ },{}],33:[function(require,module,exports){
'use strict'; 'use strict';
/** /**
@@ -2449,7 +2323,7 @@ function setProperties(obj, properties) {
module.exports = setProperties; module.exports = setProperties;
},{}],35:[function(require,module,exports){ },{}],34:[function(require,module,exports){
'use strict'; 'use strict';
function supportsFullscreen() { function supportsFullscreen() {
@@ -2460,7 +2334,7 @@ function supportsFullscreen() {
module.exports = supportsFullscreen; module.exports = supportsFullscreen;
},{}],36:[function(require,module,exports){ },{}],35:[function(require,module,exports){
'use strict'; 'use strict';
var isFullscreen = require('./is-fullscreen'); var isFullscreen = require('./is-fullscreen');
@@ -2495,4 +2369,4 @@ function toggleFullscreen(elem) {
module.exports = toggleFullscreen; module.exports = toggleFullscreen;
},{"./is-fullscreen":30}]},{},[24]); },{"./is-fullscreen":29}]},{},[23]);
+1 -1
View File
@@ -39,7 +39,7 @@
</div> </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/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="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> <script src="/examples/basic/app.js"></script>
</body> </body>
</html> </html>
+1 -1
View File
@@ -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/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="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"> <script type="text/javascript">
var width = document.getElementById('width'); var width = document.getElementById('width');
var height = document.getElementById('height'); var height = document.getElementById('height');
+1 -1
View File
@@ -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/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="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"> <script type="text/javascript">
var width = document.getElementById('width'); var width = document.getElementById('width');
var height = document.getElementById('height'); var height = document.getElementById('height');
+2 -4
View File
@@ -31,7 +31,7 @@ gulp.task('compile', function() {
.bundle() .bundle()
.pipe(source('main.js')) .pipe(source('main.js'))
.pipe(buffer()) .pipe(buffer())
.pipe(rename('image-editor.js')) .pipe(rename('generated-image-editor.js'))
.pipe(gulp.dest(outputPath)); .pipe(gulp.dest(outputPath));
}); });
@@ -51,6 +51,4 @@ gulp.task('watch', function() {
gulp.watch('./src/**/*.js', gulp.series('lint', 'compile')); gulp.watch('./src/**/*.js', gulp.series('lint', 'compile'));
}); });
gulp.task('default', gulp.series( gulp.task('default', gulp.series('build'));
'build',
));
-108
View File
@@ -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
View File
@@ -7,10 +7,10 @@ var ApertureHandler = require('./ApertureHandler');
var ButtonMenu = require('./ButtonMenu'); var ButtonMenu = require('./ButtonMenu');
var DragbarHandler = require('./DragbarHandler'); var DragbarHandler = require('./DragbarHandler');
var Viewport = require('./Viewport'); var Viewport = require('./Viewport');
var ThreeDHandler = require('./3dHandler');
var MirrorHandler = require('./MirrorHandler'); var MirrorHandler = require('./MirrorHandler');
var ImageDataHandler = require('./ImageDataHandler'); var ImageDataHandler = require('./ImageDataHandler');
// eslint-disable-next-line no-unused-vars
var $document = $(document); 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. // Allow touch scrolling on touch-devices larger than mobile screen sizes.
allowTouchScrolling: !util.isMobile(), allowTouchScrolling: !util.isMobile(),
stateful: false, stateful: false,
backgroundColor: '#ededed', backgroundColor: '#ffffff',
preserveObjectStacking: true, preserveObjectStacking: true,
selection: false, selection: false,
width: dimensions.width, 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.setHeight(args.height);
this.setWidth(args.width); this.setWidth(args.width);
this.getButtonMenu().render(); this.getButtonMenu().render();
if (this.get3dHandler().isEnabled()) { this.refreshImage(this.getResizedImage(this.getImage()));
this.get3dHandler().refreshImage(); this.getViewport().reset();
} else {
this.refreshImage(this.getResizedImage(this.getImage()));
this.getViewport().reset();
}
this.sendToBack(this.getImage()); this.sendToBack(this.getImage());
this.getImage().center(); this.getImage().center();
this.getDragbars().resetPosition(); this.getDragbars().resetPosition();
@@ -69,33 +65,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return this; 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 () { getApertures: function () {
return this.__aperturehandler || return this.__aperturehandler ||
(this.__aperturehandler = new ApertureHandler(this)); (this.__aperturehandler = new ApertureHandler(this));
@@ -153,17 +122,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return this.__buttonMenu; 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} * @return {Canvas}
*/ */
@@ -197,8 +155,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
}, },
getResizedImage: function(img) { 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 maxHeight = this.getHeight() - 100;
var maxWidth = this.getWidth() - 100; var maxWidth = this.getWidth() - 100;
@@ -207,27 +163,6 @@ var Canvas = fabric.util.createClass(fabric.Canvas, {
return img; 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; module.exports = Canvas;
+32 -24
View File
@@ -84,34 +84,42 @@ function DragbarHandler(canvas) {
this.init = function () { this.init = function () {
this.clear(); this.clear();
var typeIsWallpaper = canvas.__type === 'wallpaper'; var typeIsWallpaper = canvas.__type === 'wallpaper';
var image = canvas.getImage();
_dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.x = new fabric.Rect(
axis: 'x', $.extend({}, config.dragBar, {
width: canvas.getImage().width * canvas.getImage().scaleY, axis: 'x',
height: config.dragBar.size, width: image.width * image.scaleY,
lockMovementY: true, height: config.dragBar.size,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) lockMovementY: true,
lockMovementX: typeIsWallpaper, // Movement should also be disabled when the user is on wallpaper (repeating paterns)
selectable: true, lockMovementX: typeIsWallpaper,
hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', selectable: true,
moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
})) moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
})
)
.addTo(canvas) .addTo(canvas)
.centerH().set({ top: canvas.height - 30 }).setCoords(); .centerH()
.set({ top: image.height + 10 })
.setCoords();
_dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.y = new fabric.Rect(
axis: 'y', $.extend({}, config.dragBar, {
width: config.dragBar.size, axis: 'y',
height: canvas.getImage().height * canvas.getImage().scaleY, width: config.dragBar.size,
lockMovementX: true, height: image.height * image.scaleY,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) lockMovementX: true,
lockMovementY: typeIsWallpaper, // Movement should also be disabled when the user is on wallpaper (repeating paterns)
selectable: true, lockMovementY: typeIsWallpaper,
hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', selectable: true,
moveCursor: typeIsWallpaper ? 'pointer': 'ns-resize', hoverCursor: typeIsWallpaper ? 'pointer' : 'ns-resize',
})) moveCursor: typeIsWallpaper ? 'pointer' : 'ns-resize',
})
)
.addTo(canvas) .addTo(canvas)
.set({ left: canvas.width - 30 }).setCoords(); .set({ left: canvas.width - 30 })
.setCoords();
canvas.getImage().on('moving', this.sync); canvas.getImage().on('moving', this.sync);
+2 -6
View File
@@ -15,8 +15,6 @@ function ImageEditor(canvasId, args) {
canvasFrameSize: 2, //cm canvasFrameSize: 2, //cm
// Default texts on the buttons // Default texts on the buttons
texts: { texts: {
showThreeD: '3d',
hideThreeD: 'Flat',
showMurals: 'Show Murals Panel', showMurals: 'Show Murals Panel',
hideMurals: 'Hide Murals Panel', hideMurals: 'Hide Murals Panel',
showRulers: 'Show Ruler', showRulers: 'Show Ruler',
@@ -51,10 +49,6 @@ function ImageEditor(canvasId, args) {
// It might be better that this resides somewhere else, either in Canvas or // It might be better that this resides somewhere else, either in Canvas or
// during the initialization of the image editor. // during the initialization of the image editor.
if (_canvas.__type === 'canvas') { if (_canvas.__type === 'canvas') {
_canvas.getButtonMenu()
.addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () {
_canvas.toggle3D(this.isActive());
});
_canvas.set({ _canvas.set({
__canvasFrameType: _settings.canvasFrameType, __canvasFrameType: _settings.canvasFrameType,
__canvasFrameSize: _settings.canvasFrameSize, __canvasFrameSize: _settings.canvasFrameSize,
@@ -132,6 +126,8 @@ function ImageEditor(canvasId, args) {
_canvas.getApertures().setTransparent(false); _canvas.getApertures().setTransparent(false);
} }
_canvas.getDragbars().resetPosition();
return this; return this;
}; };
+54 -11
View File
@@ -11,7 +11,23 @@ function Viewport(canvas) {
var _borderWidth = 2; var _borderWidth = 2;
var _data = null; var _data = null;
var _rect; var _rect;
var _baseImageScale = null; // Store the original image scale to avoid cumulative scaling
var self = this; var self = this;
var viewportMargins = {
vertical: 200,
horizontal: 90,
};
/**
* Calculate available canvas dimensions after margins
* @return {Object} { width, height }
*/
function getAvailableCanvasDimensions() {
return {
width: canvas.width - viewportMargins.horizontal,
height: canvas.height - viewportMargins.vertical,
};
}
/** /**
* Render the diagonal lines from viewport to edge of the canvas * Render the diagonal lines from viewport to edge of the canvas
@@ -143,7 +159,44 @@ function Viewport(canvas) {
return this; 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 cropData = canvas.getImageData().getCropData();
var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height)); var isAspectTheSame = !!(cropData && !util.isAspectChanged(cropData.viewportWidth, cropData.viewportHeight, width, height));
@@ -174,17 +227,7 @@ function Viewport(canvas) {
*/ */
this.setFrame = function (frameType) { this.setFrame = function (frameType) {
this.getFrameHandler().setFrames(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.getButtonMenu().bringToFront();
canvas.refresh3dView();
}; };
this.getData = function () { this.getData = function () {
+1 -1
View File
@@ -2,7 +2,7 @@
module.exports = { module.exports = {
text: { text: {
fontFamily: 'breuer', fontFamily: 'Urbanist',
fontSize: 12, fontSize: 12,
fill: '#ffffff', fill: '#ffffff',
originX: 'center', originX: 'center',
+2 -2
View File
@@ -19,7 +19,7 @@ module.exports = {
text: { text: {
fill: '#ffffff', fill: '#ffffff',
disabledFill: '#999999', disabledFill: '#999999',
fontFamily: 'breuer', fontFamily: 'Urbanist',
fontSize: 14, fontSize: 14,
originX: 'center', originX: 'center',
originY: 'center', originY: 'center',
@@ -27,5 +27,5 @@ module.exports = {
cursor: 'pointer', cursor: 'pointer',
disabledCursor: 'default', disabledCursor: 'default',
padding: 20, padding: 17,
}; };
+1 -1
View File
@@ -14,7 +14,7 @@
<script src="vendor/qunit.js"></script> <script src="vendor/qunit.js"></script>
<script src="vendor/fabric.js"></script> <script src="vendor/fabric.js"></script>
<script src="vendor/jquery.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> <script src="unit/image-editor.js"></script>
</body> </body>
</html> </html>