P5-3564 - Add eslint and run with --fix

This commit is contained in:
Anders Gustafsson
2019-02-22 14:25:19 +01:00
parent 8c1fc65d72
commit c89c1ce609
47 changed files with 4355 additions and 3393 deletions
+34
View File
@@ -0,0 +1,34 @@
{
"env": {
"browser": true,
"commonjs": true
},
"extends": ["eslint:recommended"],
"rules": {
"no-console": 0,
"strict": [
"error",
"safe"
],
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"comma-dangle": [
"error",
"only-multiline"
]
}
}
+6 -1
View File
@@ -1,3 +1,8 @@
Photowall Image Editor Photowall Image Editor
====================== ======================
Image editor for the Photowall web project Image editor for the Photowall web project
# Linting
Linting can be run manually with
`npm run lint`
+1598 -1598
View File
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
{
"globals": {
"$": false,
"ImageEditor": false,
"QUnit": false
}
}
+151 -151
View File
@@ -8,174 +8,174 @@
(function() { (function() {
var $document = $(document); var $document = $(document);
var $window = $(window); var $window = $(window);
var $wrapper = $('#wrapper'); var $wrapper = $('#wrapper');
var $formControl = $('#form-control'); var $formControl = $('#form-control');
var editor = null; var editor = null;
var widthInCm, heightInCm; var widthInCm, heightInCm;
// Inputs for the editor // Inputs for the editor
var $input = { var $input = {
w: $formControl.find('input[name="w"]'), w: $formControl.find('input[name="w"]'),
h: $formControl.find('input[name="h"]'), h: $formControl.find('input[name="h"]'),
units: $formControl.find('select[name="units"]'), units: $formControl.find('select[name="units"]'),
image_id: $formControl.find('input[name="image_id"]'), image_id: $formControl.find('input[name="image_id"]'),
mirror: $formControl.find('input[name="mirror"]'), mirror: $formControl.find('input[name="mirror"]'),
noCrop: $formControl.find('input[name="no-crop"]'), noCrop: $formControl.find('input[name="no-crop"]'),
border: $formControl.find('select[name="canvas-border"]'), border: $formControl.find('select[name="canvas-border"]'),
};
var imageUrl = '//images.photowall.com/products/' + $input.image_id.val() + '.jpg?h=450';
widthInCm = $input.w.val();
heightInCm = $input.h.val();
function isFullscreen() {
return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
}
function getOptimalDimension(values, currentDimension, ratio) {
if (currentDimension === 'h') {
values.width = Math.round(values.height * ratio);
} else {
values.height = Math.round(values.width / ratio);
}
return values;
}
function handleDimensionChange() {
var noCropIsChecked = $input.noCrop.is(':checked');
var data = editor.canvas.getViewport().getData();
var values = {
width: $input.w.val(),
height: $input.h.val(),
}; };
var imageUrl = '//images.photowall.com/products/' + $input.image_id.val() + '.jpg?h=450';
widthInCm = $input.w.val(); if (noCropIsChecked) {
heightInCm = $input.h.val(); var currentDimension = $(this).attr('name') === 'h' ? 'h' : 'w';
values = getOptimalDimension(values, currentDimension, data.objectRatio);
function isFullscreen() {
return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
} }
function getOptimalDimension(values, currentDimension, ratio) { $input.w.val(values.width);
if (currentDimension === 'h') { $input.h.val(values.height);
values.width = Math.round(values.height * ratio);
} else {
values.height = Math.round(values.width / ratio);
}
return values; if ($input.units.val() == 'inch') {
widthInCm = Math.round(values.width * 2.54);
heightInCm = Math.round(values.height * 2.54);
}
else {
widthInCm = values.width;
heightInCm = values.height;
} }
function handleDimensionChange() { editor.crop(values.width, values.height, $input.units.val());
var noCropIsChecked = $input.noCrop.is(':checked'); }
var data = editor.canvas.getViewport().getData();
var values = {
width: $input.w.val(),
height: $input.h.val(),
};
if (noCropIsChecked) { function handleMirrorChange() {
var currentDimension = $(this).attr('name') === 'h' ? 'h' : 'w'; editor.canvas.getMirror().set(this.checked);
values = getOptimalDimension(values, currentDimension, data.objectRatio); }
}
$input.w.val(values.width); function handleNoCropChange() {
$input.h.val(values.height); $input.w.trigger('input');
}
if ($input.units.val() == 'inch') { function handleFrameChange() {
widthInCm = Math.round(values.width * 2.54);
heightInCm = Math.round(values.height * 2.54);
}
else {
widthInCm = values.width;
heightInCm = values.height;
}
editor.crop(values.width, values.height, $input.units.val()); if ($(this).val() === 'none') {
editor.canvas.toggle3D(false);
} }
function handleMirrorChange() { editor.canvas.getViewport().setFrame($(this).val());
editor.canvas.getMirror().set(this.checked); }
}
function handleNoCropChange() { function handleResize() {
var width = $wrapper.width();
var height = isFullscreen() ? $window.height() : $wrapper.height();
editor.canvas.resize({width: width, height: height});
}
function getWrapperData() {
var $navbar = $('.image-editor__navbar');
var isFullScreen = isFullscreen();
var isMobile = $window.width() <= 767;
var windowHeight = window.innerHeight ? window.innerHeight : $window.height();
var windowWidth = window.innerWidth ? window.innerWidth : $window.width();
return {
width: isFullScreen ? windowWidth : (isMobile ? windowWidth : $wrapper.width()),
height: isFullScreen ? windowHeight : (isMobile ? windowHeight - $navbar.height() : $wrapper.height())
};
}
function handleUnitsChange() {
switch ($input.units.val()) {
case 'inch':
$input.w.val(Math.round(widthInCm / 2.54 * 100) / 100);
$input.h.val(Math.round(heightInCm / 2.54 * 100) / 100);
break;
case 'cm':
default:
$input.w.val(widthInCm);
$input.h.val(heightInCm);
break;
}
handleDimensionChange();
}
function eventHandlers() {
$input.w.on('input', handleDimensionChange);
$input.h.on('input', handleDimensionChange);
$input.mirror.on('change', handleMirrorChange);
$input.noCrop.on('change', handleNoCropChange);
$input.border.on('change', handleFrameChange);
$input.units.on('change', handleUnitsChange);
$document
.on('PIE:dragged', function() {
console.log('Dragged the image/dragbar!');
})
.on('PIE:needs-dragging', function(e, data) {
console.log('Image needs dragging on: ' + data.axis);
})
.on('PIE:dragbar-click', function(e, data) {
console.log('Clicked on a dragbar! Axis: ' + data.axis);
})
.on('PIE:image-start-load', function() {
console.log('Start loading image');
})
.on('PIE:image-end-load', function() {
console.log('Image loaded');
});
$window.on('resize', handleResize);
}
function init() {
editor = new ImageEditor('canvas-editor', {
type: 'wallpaper',
buttons: {
showThreeD: '3d',
hideThreeD: 'Flat',
showMurals: 'show-murals',
hideMurals: 'hide-murals',
showRulers: 'show-rulers',
hideRulers: 'hide-rulers',
showFullscreen: 'show-fullscreen',
exitFullscreen: 'exit-fullscreen',
},
dimensions: getWrapperData()
})
.loadImage(imageUrl, function() {
$input.w.trigger('input'); $input.w.trigger('input');
} handleResize();
});
function handleFrameChange() { eventHandlers();
}
if ($(this).val() === 'none') { init();
editor.canvas.toggle3D(false);
}
editor.canvas.getViewport().setFrame($(this).val());
}
function handleResize() {
var width = $wrapper.width();
var height = isFullscreen() ? $window.height() : $wrapper.height();
editor.canvas.resize({width: width, height: height});
}
function getWrapperData() {
var $navbar = $('.image-editor__navbar');
var isFullScreen = isFullscreen();
var isMobile = $window.width() <= 767;
var windowHeight = window.innerHeight ? window.innerHeight : $window.height();
var windowWidth = window.innerWidth ? window.innerWidth : $window.width();
return {
width: isFullScreen ? windowWidth : (isMobile ? windowWidth : $wrapper.width()),
height: isFullScreen ? windowHeight : (isMobile ? windowHeight - $navbar.height() : $wrapper.height())
};
}
function handleUnitsChange() {
switch ($input.units.val()) {
case 'inch':
$input.w.val(Math.round(widthInCm / 2.54 * 100) / 100);
$input.h.val(Math.round(heightInCm / 2.54 * 100) / 100);
break;
case 'cm':
default:
$input.w.val(widthInCm);
$input.h.val(heightInCm);
break;
}
handleDimensionChange();
}
function eventHandlers() {
$input.w.on('input', handleDimensionChange);
$input.h.on('input', handleDimensionChange);
$input.mirror.on('change', handleMirrorChange);
$input.noCrop.on('change', handleNoCropChange);
$input.border.on('change', handleFrameChange);
$input.units.on('change', handleUnitsChange);
$document
.on('PIE:dragged', function() {
console.log('Dragged the image/dragbar!');
})
.on('PIE:needs-dragging', function(e, data) {
console.log('Image needs dragging on: ' + data.axis);
})
.on('PIE:dragbar-click', function(e, data) {
console.log('Clicked on a dragbar! Axis: ' + data.axis);
})
.on('PIE:image-start-load', function() {
console.log('Start loading image');
})
.on('PIE:image-end-load', function() {
console.log('Image loaded');
});
$window.on('resize', handleResize);
}
function init() {
editor = new ImageEditor('canvas-editor', {
type: 'wallpaper',
buttons: {
showThreeD: '3d',
hideThreeD: 'Flat',
showMurals: 'show-murals',
hideMurals: 'hide-murals',
showRulers: 'show-rulers',
hideRulers: 'hide-rulers',
showFullscreen: 'show-fullscreen',
exitFullscreen: 'exit-fullscreen',
},
dimensions: getWrapperData()
})
.loadImage(imageUrl, function() {
$input.w.trigger('input');
handleResize();
});
eventHandlers();
}
init();
}()); }());
+10 -10
View File
@@ -1,5 +1,5 @@
var gulp = require('gulp'); var gulp = require('gulp');
var browserify = require('browserify') var browserify = require('browserify');
var buffer = require('vinyl-buffer'); var buffer = require('vinyl-buffer');
var rename = require('gulp-rename'); var rename = require('gulp-rename');
var source = require('vinyl-source-stream'); var source = require('vinyl-source-stream');
@@ -7,17 +7,17 @@ var jshint = require('gulp-jshint');
var qunit = require('gulp-qunit'); var qunit = require('gulp-qunit');
gulp.task('build', function() { gulp.task('build', function() {
return browserify('./src/main.js') return browserify('./src/main.js')
.bundle() .bundle()
.pipe(source('main.js')) .pipe(source('main.js'))
.pipe(buffer()) .pipe(buffer())
.pipe(rename('image-editor.js')) .pipe(rename('image-editor.js'))
.pipe(gulp.dest('./dist')); .pipe(gulp.dest('./dist'));
}); });
gulp.task('test', ['build'], function() { gulp.task('test', ['build'], function() {
return gulp.src('./test/index.html') return gulp.src('./test/index.html')
.pipe(qunit({timeout: 1})); .pipe(qunit({timeout: 1}));
}); });
gulp.task('lint', function() { gulp.task('lint', function() {
@@ -27,7 +27,7 @@ gulp.task('lint', function() {
}); });
gulp.task('watch', function() { gulp.task('watch', function() {
gulp.watch('./src/**/*.js', ['build']); gulp.watch('./src/**/*.js', ['build']);
}); });
gulp.task('default', ['lint', 'build']); gulp.task('default', ['lint', 'build']);
+910 -11
View File
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -8,13 +8,17 @@
}, },
"devDependencies": { "devDependencies": {
"browserify": "^13.1.1", "browserify": "^13.1.1",
"eslint": "^5.14.1",
"gulp": "^3.9.0", "gulp": "^3.9.0",
"gulp-jshint": "^2.0.4",
"gulp-qunit": "^1.5.0",
"gulp-rename": "^1.2.2",
"jshint": "^2.9.5", "jshint": "^2.9.5",
"qunit": "^1.0.0", "qunit": "^1.0.0",
"gulp-jshint": "^2.0.4",
"gulp-rename": "^1.2.2",
"vinyl-buffer": "^1.0.0", "vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0", "vinyl-source-stream": "^1.1.0"
"gulp-qunit": "^1.5.0" },
"scripts": {
"lint": "eslint gulpfile.js 'examples/**/*.js' 'test/unit/**/*.js' 'src/**/*.js'"
} }
} }
+7
View File
@@ -0,0 +1,7 @@
{
"rules": {
"no-console":[
"error"
]
}
}
+64 -64
View File
@@ -6,102 +6,102 @@
* @param {canvas} canvas * @param {canvas} canvas
*/ */
function ThreeDHandler(canvas) { function ThreeDHandler(canvas) {
var _overlay = new fabric.Group(); var _overlay = new fabric.Group();
var _image; var _image;
function init() { function init() {
_overlay _overlay
.set({ .set({
visible: false, visible: false,
left: 0 left: 0
}) })
.addWithUpdate(new fabric.Rect({ .addWithUpdate(new fabric.Rect({
// Width is made bigger as this works better with resizing the editor // Width is made bigger as this works better with resizing the editor
width: canvas.width * 2, width: canvas.width * 2,
height: canvas.height, height: canvas.height,
top: 0, top: 0,
left: 0, left: 0,
fill: canvas.backgroundColor, fill: canvas.backgroundColor,
})); }));
canvas.add(_overlay); canvas.add(_overlay);
} }
init(); init();
/** /**
* Disables the 3d image by removing visibility * Disables the 3d image by removing visibility
* @return {ThreeDHandler} * @return {ThreeDHandler}
*/ */
this.disable = function () { this.disable = function () {
_overlay.setVisible(false).canvas.resize(); _overlay.setVisible(false).canvas.resize();
return this; return this;
}; };
/** /**
* Enables the 3d image by setting the width and visibility of the overlay and moving elements which * Enables the 3d image by setting the width and visibility of the overlay and moving elements which
* needs to be visible to the front. * needs to be visible to the front.
* @return {ThreeDHandler} * @return {ThreeDHandler}
*/ */
this.enable = function () { this.enable = function () {
_overlay _overlay
.set({ .set({
width: canvas.width, width: canvas.width,
visible: true visible: true
}).bringToFront(); }).bringToFront();
canvas.getButtonMenu().bringToFront(); canvas.getButtonMenu().bringToFront();
canvas.renderAll(); canvas.renderAll();
return this; return this;
}; };
/** /**
* Checks if 3d mode is enabled/visible. * Checks if 3d mode is enabled/visible.
* @returns {boolean} * @returns {boolean}
*/ */
this.isEnabled = function () { this.isEnabled = function () {
return _overlay.visible; return _overlay.visible;
}; };
/** /**
* Refreshes the image. This is mostly done upon resize of the window * Refreshes the image. This is mostly done upon resize of the window
*/ */
this.refreshImage = function() { this.refreshImage = function() {
_overlay.set({ _overlay.set({
width: canvas.width, width: canvas.width,
}); });
this.applyImage(); this.applyImage();
}; };
/** /**
* (Re)adds the new/existing image with new configuration to the overlay. * (Re)adds the new/existing image with new configuration to the overlay.
* @param {img} * @param {img}
*/ */
this.applyImage = function(img) { this.applyImage = function(img) {
img = img || _image; img = img || _image;
_overlay _overlay
.remove(_image) .remove(_image)
.add(_image = canvas.getResizedImage(img)); .add(_image = canvas.getResizedImage(img));
}; };
/** /**
* Sets the image and enables 3d mode. * Sets the image and enables 3d mode.
* @param {img} * @param {img}
* @return {ThreeDHandler} * @return {ThreeDHandler}
*/ */
this.setImage = function (img) { this.setImage = function (img) {
img.set({ img.set({
// Image should be about 20px lower than the center (because of the buttons) // Image should be about 20px lower than the center (because of the buttons)
top: 20, top: 20,
originX: 'center', originX: 'center',
originY: 'center', originY: 'center',
}); });
this.applyImage(img); this.applyImage(img);
return this.enable(); return this.enable();
}; };
} }
+61 -61
View File
@@ -6,94 +6,94 @@
* @param {canvas} canvas * @param {canvas} canvas
*/ */
function ApertureHandler(canvas) { function ApertureHandler(canvas) {
var _items = {x: [], y: []}; var _items = {x: [], y: []};
function init() { function init() {
var bounds = canvas; var bounds = canvas;
var xRect = new fabric.Rect({ var xRect = new fabric.Rect({
width: bounds.width, width: bounds.width,
height: bounds.height / 2, height: bounds.height / 2,
fill: canvas.backgroundColor, fill: canvas.backgroundColor,
opacity: 0.7, opacity: 0.7,
}); });
var yRect = xRect.clone().set({ var yRect = xRect.clone().set({
width: bounds.width / 2, width: bounds.width / 2,
height: bounds.height height: bounds.height
}); });
_items.x = [].concat([xRect, xRect.clone()]); _items.x = [].concat([xRect, xRect.clone()]);
_items.y= [].concat([yRect, yRect.clone()]); _items.y= [].concat([yRect, yRect.clone()]);
[].concat(_items.x, _items.y).forEach(function (o) { [].concat(_items.x, _items.y).forEach(function (o) {
canvas.add(o); canvas.add(o);
}); });
canvas.renderAll(); canvas.renderAll();
} }
init(); init();
/** /**
* Applies configuration to the apertures apertures on the viewport * Applies configuration to the apertures apertures on the viewport
* @param {string} axis * @param {string} axis
* @param {viewport} viewport * @param {viewport} viewport
*/ */
this.apply = function (axis, viewport) { this.apply = function (axis, viewport) {
this.getApertures(axis).forEach(function (o) { this.getApertures(axis).forEach(function (o) {
o.visible = false; o.visible = false;
}); });
var active = this.getApertures(axis === 'x' ? 'y' : 'x'); var active = this.getApertures(axis === 'x' ? 'y' : 'x');
active.forEach(function (o) { active.forEach(function (o) {
o.visible = true; o.visible = true;
}); });
active[0].width= active[1].width = canvas.width; active[0].width= active[1].width = canvas.width;
active[0].height = active[1].height = canvas.height; active[0].height = active[1].height = canvas.height;
if (axis === 'y') { if (axis === 'y') {
active[0].top = viewport.top - active[0].height + 0.5; active[0].top = viewport.top - active[0].height + 0.5;
active[1].top = viewport.top + viewport.height - 0.5; active[1].top = viewport.top + viewport.height - 0.5;
} else { } else {
active[0].left = viewport.left - active[0].width + 0.5; active[0].left = viewport.left - active[0].width + 0.5;
active[1].left = viewport.left + viewport.width - 0.5; active[1].left = viewport.left + viewport.width - 0.5;
} }
this.getApertures().forEach(function (o) { this.getApertures().forEach(function (o) {
o.setCoords(); o.setCoords();
}); });
canvas.renderAll(); canvas.renderAll();
}; };
/** /**
* Gets the apertures on specified axis. If no axis is provided, both x and y are returned. * Gets the apertures on specified axis. If no axis is provided, both x and y are returned.
* @param {string} axis * @param {string} axis
* @returns {Array} * @returns {Array}
*/ */
this.getApertures = function (axis) { this.getApertures = function (axis) {
return axis ? _items[axis] : [].concat(_items.x, _items.y); return axis ? _items[axis] : [].concat(_items.x, _items.y);
}; };
/** /**
* Sets transparency of the apertures depending on the crop status * Sets transparency of the apertures depending on the crop status
* @param {boolean} apply * @param {boolean} apply
* @returns {ApertureHandler} * @returns {ApertureHandler}
*/ */
this.setTransparent = function (apply) { this.setTransparent = function (apply) {
this.getApertures().forEach(function (o) { this.getApertures().forEach(function (o) {
o.opacity = apply ? 0.7 : 1; o.opacity = apply ? 0.7 : 1;
}); });
canvas.renderAll(); canvas.renderAll();
return this; return this;
}; };
this.disable = function () { this.disable = function () {
this.getApertures().forEach(function (o) { this.getApertures().forEach(function (o) {
o.visible = false; o.visible = false;
}); });
}; };
} }
module.exports = ApertureHandler; module.exports = ApertureHandler;
+91 -91
View File
@@ -9,143 +9,143 @@ var TextButton = require('./TextButton');
* @param {Object=} settings * @param {Object=} settings
*/ */
function ButtonMenu(canvas, settings) { function ButtonMenu(canvas, settings) {
var _textButtons = []; var _textButtons = [];
var _width = 0; var _width = 0;
/** /**
* Calculates the width of all contained items * Calculates the width of all contained items
* @return {Number} * @return {Number}
*/ */
function setWidth() { function setWidth() {
var startWidth = 0; var startWidth = 0;
_textButtons.forEach(function(textButton) { _textButtons.forEach(function(textButton) {
startWidth += textButton.width; startWidth += textButton.width;
}); });
_width = startWidth += settings.margin * (_textButtons.length - 1); _width = startWidth += settings.margin * (_textButtons.length - 1);
} }
/** /**
* Adds items to the button-menu. * Adds items to the button-menu.
* @param {String} text * @param {String} text
* @param {Function} callback * @param {Function} callback
* @return {ButtonMenu} * @return {ButtonMenu}
*/ */
this.addItem = function(id, text, callback, isActive) { this.addItem = function(id, text, callback, isActive) {
_textButtons.push( _textButtons.push(
new TextButton(id, text, settings, isActive) new TextButton(id, text, settings, isActive)
.onClick(callback) .onClick(callback)
.set({__group: this}) .set({__group: this})
); );
return this; return this;
}; };
/** /**
* Brings the buttons to the front inside the canvas * Brings the buttons to the front inside the canvas
* @return {ButtonMenu} * @return {ButtonMenu}
*/ */
this.bringToFront = function() { this.bringToFront = function() {
_textButtons.forEach(function(textButton) { _textButtons.forEach(function(textButton) {
textButton.bringToFront(); textButton.bringToFront();
}); });
return this; return this;
}; };
/** /**
* Gets all buttons inside the menu. * Gets all buttons inside the menu.
* @return {Array} * @return {Array}
*/ */
this.getItems = function() { this.getItems = function() {
return _textButtons; return _textButtons;
}; };
/** /**
* Gets the full width of the buttonMenu. * Gets the full width of the buttonMenu.
* @return {Number} * @return {Number}
*/ */
this.getWidth = function() { this.getWidth = function() {
return _width; return _width;
}; };
/** /**
* Sets the button with id=buttonId to active/not active mode * Sets the button with id=buttonId to active/not active mode
*/ */
this.setButtonActive = function(buttonId, isActive) { this.setButtonActive = function(buttonId, isActive) {
_textButtons.forEach(function (button) { _textButtons.forEach(function (button) {
if (button.getId() === buttonId) { if (button.getId() === buttonId) {
button.setActive(isActive); button.setActive(isActive);
} }
}); });
}; };
/** /**
* Sets the button with id=buttonId to disabled/enabled mode * Sets the button with id=buttonId to disabled/enabled mode
*/ */
this.setButtonDisabled = function(buttonId, isDisabled) { this.setButtonDisabled = function(buttonId, isDisabled) {
_textButtons.forEach(function (button) { _textButtons.forEach(function (button) {
if (button.getId() === buttonId) { if (button.getId() === buttonId) {
button.setDisabled(isDisabled); button.setDisabled(isDisabled);
} }
}); });
}; };
/** /**
* Hides the buttons * Hides the buttons
*/ */
this.hide = function() { this.hide = function() {
_textButtons.forEach(function(textButton) { _textButtons.forEach(function(textButton) {
textButton.set({ textButton.set({
opacity: 0, opacity: 0,
disabled: true disabled: true
}); });
}); });
}; };
/** /**
* Shows all the buttons * Shows all the buttons
*/ */
this.show = function() { this.show = function() {
_textButtons.forEach(function(textButton) { _textButtons.forEach(function(textButton) {
textButton.set({ textButton.set({
opacity: 1, opacity: 1,
disabled: false disabled: false
}); });
}); });
}; };
/** /**
* Recalculate boundaries and add all items to canvas if required * Recalculate boundaries and add all items to canvas if required
* @return {ButtonMenu} * @return {ButtonMenu}
*/ */
this.render = function() { this.render = function() {
setWidth(); setWidth();
var start = canvas.width / 2 - this.getWidth() / 2; var start = canvas.width / 2 - this.getWidth() / 2;
var currPos = Math.round(start); var currPos = Math.round(start);
_textButtons.forEach(function(textButton) { _textButtons.forEach(function(textButton) {
textButton textButton
.set({ .set({
top: 10, top: 10,
left: currPos left: currPos
}) })
.setCoords(); .setCoords();
if (!textButton.canvas) { if (!textButton.canvas) {
textButton.addTo(canvas); textButton.addTo(canvas);
} }
currPos += Math.round(textButton.width + settings.margin); currPos += Math.round(textButton.width + settings.margin);
// Disable moving of text-buttons // Disable moving of text-buttons
textButton.lockMovementX = textButton.lockMovementY = true; textButton.lockMovementX = textButton.lockMovementY = true;
}); });
canvas.renderAll(); canvas.renderAll();
this.show(); this.show();
return this; return this;
}; };
} }
module.exports = ButtonMenu; module.exports = ButtonMenu;
+158 -158
View File
@@ -19,221 +19,221 @@ var $document = $(document);
* Fe. getDragbars method can be called from most places as the Canvas class is available in most places. * Fe. getDragbars method can be called from most places as the Canvas class is available in most places.
*/ */
var Canvas = fabric.util.createClass(fabric.Canvas, { var Canvas = fabric.util.createClass(fabric.Canvas, {
initialize: function (id, dimensions) { initialize: function (id, dimensions) {
this.callSuper('initialize', id, { this.callSuper('initialize', id, {
enableRetinaScaling: true, enableRetinaScaling: true,
renderOnAddRemove: false, renderOnAddRemove: false,
// 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: '#ededed',
preserveObjectStacking: true, preserveObjectStacking: true,
selection: false, selection: false,
width: dimensions.width, width: dimensions.width,
height: dimensions.height height: dimensions.height
}); });
}, },
resize: function (args) { resize: function (args) {
args = args || { height: this.height, width: this.width}; args = args || { height: this.height, width: this.width};
if (!args.width || !args.height) { if (!args.width || !args.height) {
return; return;
} }
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()) { if (this.get3dHandler().isEnabled()) {
this.get3dHandler().refreshImage(); this.get3dHandler().refreshImage();
} else { } else {
this.refreshImage(this.getResizedImage(this.getImage())); this.refreshImage(this.getResizedImage(this.getImage()));
this.getViewport().reset(); this.getViewport().reset();
} }
this.sendToBack(this.getImage()); this.sendToBack(this.getImage());
this.getImage().center(); this.getImage().center();
this.getDragbars().resetPosition(); this.getDragbars().resetPosition();
this.renderAll(); this.renderAll();
}, },
disableScroll: function() { disableScroll: function() {
this.set({ this.set({
allowTouchScrolling: false allowTouchScrolling: false
}); });
return this; return this;
}, },
enableScroll: function() { enableScroll: function() {
this.set({ this.set({
allowTouchScrolling: true allowTouchScrolling: true
}); });
return this; return this;
}, },
get3dHandler: function () { get3dHandler: function () {
return this.__3dHandler || return this.__3dHandler ||
(this.__3dHandler = new ThreeDHandler(this)); (this.__3dHandler = new ThreeDHandler(this));
}, },
/** /**
* @return {String} * @return {String}
*/ */
get3dUrl: function () { get3dUrl: function () {
var imageData = this.getImageData().getData(); var imageData = this.getImageData().getData();
var params = [ var params = [
'h=400', 'h=400',
'canvas[edge]=' + imageData.edge, 'canvas[edge]=' + imageData.edge,
'crop[w]=' + imageData.width, 'crop[w]=' + imageData.width,
'crop[h]=' + imageData.height, 'crop[h]=' + imageData.height,
'crop[x]=' + imageData.x, 'crop[x]=' + imageData.x,
'crop[y]=' + imageData.y, 'crop[y]=' + imageData.y,
]; ];
if (imageData.mirrored) { if (imageData.mirrored) {
params.push('mirror=1'); params.push('mirror=1');
} }
return this.getImage().__url.replace(/\?h=\d+$/, '?') + params.join('&'); 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));
}, },
/** /**
* *
* @returns {DragbarHandler} * @returns {DragbarHandler}
*/ */
getDragbars: function () { getDragbars: function () {
return this.__dragbars || return this.__dragbars ||
(this.__dragbars = new DragbarHandler(this)); (this.__dragbars = new DragbarHandler(this));
}, },
/** /**
* @return {fabric.Image} * @return {fabric.Image}
*/ */
getImage: function () { getImage: function () {
return this.__image; return this.__image;
}, },
/** /**
* @return {MirrorHandler} * @return {MirrorHandler}
*/ */
getMirror: function () { getMirror: function () {
return this.__mirror || return this.__mirror ||
(this.__mirror = new MirrorHandler(this.getImage())); (this.__mirror = new MirrorHandler(this.getImage()));
}, },
/** /**
* @return {MirrorHandler} * @return {MirrorHandler}
*/ */
getImageData: function () { getImageData: function () {
return this.__imageData || return this.__imageData ||
(this.__imageData = new ImageDataHandler(this.getImage())); (this.__imageData = new ImageDataHandler(this.getImage()));
}, },
/** /**
* @return {Viewport} * @return {Viewport}
*/ */
getViewport: function () { getViewport: function () {
return this.__viewport || return this.__viewport ||
(this.__viewport = new Viewport(this)); (this.__viewport = new Viewport(this));
}, },
/** /**
* Gets the menu for this instance * Gets the menu for this instance
* @returns {ButtonMenu} * @returns {ButtonMenu}
*/ */
getButtonMenu: function (settings) { getButtonMenu: function (settings) {
if (!this.__buttonMenu) { if (!this.__buttonMenu) {
var defaults = config.buttonMenu[this.__type]; var defaults = config.buttonMenu[this.__type];
this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings)); this.__buttonMenu = new ButtonMenu(this, $.extend({}, defaults, settings));
} }
return this.__buttonMenu; return this.__buttonMenu;
}, },
/** /**
* Reloads the 3D view, if it is present * Reloads the 3D view, if it is present
* @return {Canvas} * @return {Canvas}
*/ */
refresh3dView: function () { refresh3dView: function () {
if (this.get3dHandler().isEnabled()) { if (this.get3dHandler().isEnabled()) {
this.toggle3D(true); this.toggle3D(true);
} }
return this; return this;
}, },
/** /**
* @return {Canvas} * @return {Canvas}
*/ */
removeImage: function () { removeImage: function () {
if (!this.__image) { if (!this.__image) {
return this; return this;
} }
this.__imageData = null; this.__imageData = null;
return this.remove(this.__image); return this.remove(this.__image);
}, },
refreshImage: function(img) { refreshImage: function(img) {
this.__image = img; this.__image = img;
return this; return this;
}, },
/** /**
* @param {fabric.Image} img * @param {fabric.Image} img
* @return {Canvas} * @return {Canvas}
*/ */
setImage: function (img) { setImage: function (img) {
this.removeImage(); this.removeImage();
this.__image = img; this.__image = img;
this.__image.__dragged = false; this.__image.__dragged = false;
this.__image.__cropped = false; this.__image.__cropped = false;
this.__image.addTo(this).center().on('mousedown', function () { this.__image.addTo(this).center().on('mousedown', function () {
img.canvas.getApertures().setTransparent(true); img.canvas.getApertures().setTransparent(true);
}).setCoords(); }).setCoords();
this.getViewport().reset(); this.getViewport().reset();
return this; return this;
}, },
getResizedImage: function(img) { getResizedImage: function(img) {
// Calculate maxHeight and maxWidth of the 3d image // Calculate maxHeight and maxWidth of the 3d image
// and scale the image accoring to those values // 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;
img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height); img.scaleToHeight(maxHeight < img.height ? maxHeight : img.height);
img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX); img.scaleToWidth(maxWidth < (img.width * img.scaleX) ? maxWidth : img.width * img.scaleX);
return img; return img;
}, },
toggle3D: function (showAs3d) { toggle3D: function (showAs3d) {
this.getButtonMenu().setButtonActive('toggle3d', showAs3d); this.getButtonMenu().setButtonActive('toggle3d', showAs3d);
if (!showAs3d) { if (!showAs3d) {
return this.get3dHandler().disable(); return this.get3dHandler().disable();
}
$document.trigger('PIE:image-start-load');
$.ajax({
url: this.get3dUrl(),
crossDomain: true,
type: 'HEAD',
cache: true,
}).done(function() {
fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) {
if (!img._element) {
$document.trigger('PIE:image-error-load');
return;
} }
$document.trigger('PIE:image-start-load'); this.get3dHandler().setImage(img);
$document.trigger('PIE:image-end-load');
$.ajax({ }.bind(this));
url: this.get3dUrl(), }.bind(this));
crossDomain: true, },
type: "HEAD",
cache: true,
}).done(function() {
fabric.Image.fromURL(encodeURI(this.get3dUrl()), function (img) {
if (!img._element) {
$document.trigger('PIE:image-error-load');
return;
}
this.get3dHandler().setImage(img);
$document.trigger('PIE:image-end-load');
}.bind(this));
}.bind(this));
},
}); });
module.exports = Canvas; module.exports = Canvas;
+124 -124
View File
@@ -5,145 +5,145 @@ var config = require('./config');
var util = require('./util'); var util = require('./util');
var DragHandle = function (handler) { var DragHandle = function (handler) {
var _currentAxis; var _currentAxis;
var _dragHandle; var _dragHandle;
var _clickHandle = false; var _clickHandle = false;
var _movedHandle; var _movedHandle;
// Event declarations // Event declarations
var events = { var events = {
mouseDown: function () { mouseDown: function () {
if(handler.canvas.__type !== 'wallpaper') { if(handler.canvas.__type !== 'wallpaper') {
_dragHandle = true; _dragHandle = true;
} }
_clickHandle = true; _clickHandle = true;
_currentAxis = this.axis; _currentAxis = this.axis;
handler.canvas.getImage().trigger('mousedown'); handler.canvas.getImage().trigger('mousedown');
}, },
mouseUp: function () { mouseUp: function () {
if (!_dragHandle && !_clickHandle) { if (!_dragHandle && !_clickHandle) {
return; return;
} }
if (_clickHandle) { if (_clickHandle) {
$(document).trigger('PIE:dragbar-click', { axis: _currentAxis }); $(document).trigger('PIE:dragbar-click', { axis: _currentAxis });
_clickHandle = false; _clickHandle = false;
} }
_dragHandle = false; _dragHandle = false;
_movedHandle = false; _movedHandle = false;
_currentAxis = null; _currentAxis = null;
util.MouseMetrics.deletePreviousMouseData(); util.MouseMetrics.deletePreviousMouseData();
handler.canvas.getImage().trigger('mouseup'); handler.canvas.getImage().trigger('mouseup');
}, },
mouseMove: function (e) { mouseMove: function (e) {
if (!_dragHandle) { if (!_dragHandle) {
return; return;
} }
//Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case //Android devices have different structure of TouchEvent so e.e.touches[0] element uses in this case
var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX); var pageX = (typeof e.e.pageX !== 'undefined' ? e.e.pageX : e.e.touches[0].pageX);
var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY); var pageY = (typeof e.e.pageY !== 'undefined' ? e.e.pageY : e.e.touches[0].pageY);
// We're using a polyfill to calculate moude/touch movement if the browser/device // We're using a polyfill to calculate moude/touch movement if the browser/device
// does not support movementX/movementY. // does not support movementX/movementY.
var previousMouseData = util.MouseMetrics.previousMouseData; var previousMouseData = util.MouseMetrics.previousMouseData;
var movement = { var movement = {
x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0), x: 'movementX' in e.e ? e.e.movementX : (previousMouseData.x ? pageX - previousMouseData.x : 0),
y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0) y: 'movementY' in e.e ? e.e.movementY : (previousMouseData.y ? pageY - previousMouseData.y : 0)
}; };
util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY}); util.MouseMetrics.setPreviousMouseData({x: pageX, y: pageY});
_movedHandle = true; _movedHandle = true;
if (_currentAxis === 'x') { if (_currentAxis === 'x') {
handler.canvas.getImage().left -= movement.x; handler.canvas.getImage().left -= movement.x;
} else { } else {
handler.canvas.getImage().top -= movement.y; handler.canvas.getImage().top -= movement.y;
} }
// Trigger moving for image, to stay within bounds // Trigger moving for image, to stay within bounds
handler.canvas.getImage().setCoords().trigger('moving'); handler.canvas.getImage().setCoords().trigger('moving');
handler.canvas.renderAll(); handler.canvas.renderAll();
} }
}; };
function getRect(text, width) { function getRect(text, width) {
var txt = new fabric.Text(text, config.dragHandle.text); var txt = new fabric.Text(text, config.dragHandle.text);
var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, { var rect = new fabric.Rect($.extend({}, config.dragHandle.rect, {
width: width, width: width,
})); }));
return new fabric.Group([rect, txt]).set({ return new fabric.Group([rect, txt]).set({
evented: false, evented: false,
}); });
}
this.getCanvas = function () {
return handler.canvas;
};
this.getHandles = function () {
if (!this.__handles) {
return [];
} }
this.getCanvas = function () { return [].concat(this.__handles.x, this.__handles.y);
return handler.canvas; };
this.setHandlePosition = function() {
this.__handles.y.set({left: handler.getTracks().y.left}).setCoords();
this.__handles.x.set({top: handler.getTracks().x.top}).setCoords();
return this;
};
this.init = function () {
var canvas = this.getCanvas();
var viewport = canvas.getViewport();
var viewportData = viewport.getData();
var frameHandler = viewport.getFrameHandler();
var tracks = handler.getTracks();
if (this.__handles) {
this.getCanvas().remove(this.__handles.x);
this.getCanvas().remove(this.__handles.y);
}
var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels.
var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm.
var frameType = frameHandler.getFrameType();
var handleWidth = viewportData.width;
var handleHeight = viewportData.height;
var widthToDisplay = viewportData.dim.width;
var heightToDisplay = viewportData.dim.height;
var unit = viewportData.dim.units;
if (frameType == 'image') {
var doubleRealFrameWidth = realFrameWidth * 2;
handleWidth -= frameWidth * 2;
handleHeight -= frameWidth * 2;
widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
}
this.__handles = {
x: getRect(widthToDisplay + ' ' + unit, handleWidth),
y: getRect(heightToDisplay + ' ' + unit, handleHeight)
}; };
this.getHandles = function () { this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords();
if (!this.__handles) { this.__handles.y.addTo(this.getCanvas())
return []; .setAngle(-90)
} .centerV().set({ left: tracks.y.left })
.setCoords();
return [].concat(this.__handles.x, this.__handles.y); this.getCanvas()
}; .on('mouse:move', events.mouseMove)
.on('mouse:up', events.mouseUp);
this.setHandlePosition = function() { tracks.x.on('mousedown', events.mouseDown.bind(tracks.x));
this.__handles.y.set({left: handler.getTracks().y.left}).setCoords(); tracks.y.on('mousedown', events.mouseDown.bind(tracks.y));
this.__handles.x.set({top: handler.getTracks().x.top}).setCoords(); };
return this;
};
this.init = function () {
var canvas = this.getCanvas();
var viewport = canvas.getViewport();
var viewportData = viewport.getData();
var frameHandler = viewport.getFrameHandler();
var tracks = handler.getTracks();
if (this.__handles) {
this.getCanvas().remove(this.__handles.x);
this.getCanvas().remove(this.__handles.y);
}
var frameWidth = frameHandler.getFrameSize(); // Rendered frameWidth, in pixels.
var realFrameWidth = canvas.__canvasFrameSize; // Real frame size, in cm.
var frameType = frameHandler.getFrameType();
var handleWidth = viewportData.width;
var handleHeight = viewportData.height;
var widthToDisplay = viewportData.dim.width;
var heightToDisplay = viewportData.dim.height;
var unit = viewportData.dim.units;
if (frameType == 'image') {
var doubleRealFrameWidth = realFrameWidth * 2;
handleWidth -= frameWidth * 2;
handleHeight -= frameWidth * 2;
widthToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
heightToDisplay -= unit == 'inch' ? doubleRealFrameWidth / 2.54 : doubleRealFrameWidth;
}
this.__handles = {
x: getRect(widthToDisplay + ' ' + unit, handleWidth),
y: getRect(heightToDisplay + ' ' + unit, handleHeight)
};
this.__handles.x.addTo(this.getCanvas()).centerH().set({ top: tracks.x.top }).setCoords();
this.__handles.y.addTo(this.getCanvas())
.setAngle(-90)
.centerV().set({ left: tracks.y.left })
.setCoords();
this.getCanvas()
.on('mouse:move', events.mouseMove)
.on('mouse:up', events.mouseUp);
tracks.x.on('mousedown', events.mouseDown.bind(tracks.x));
tracks.y.on('mousedown', events.mouseDown.bind(tracks.y));
};
}; };
module.exports = DragHandle; module.exports = DragHandle;
+93 -93
View File
@@ -5,127 +5,127 @@ var DragHandle = require('./DragHandle');
var config = require('./config'); var config = require('./config');
function DragbarHandler(canvas) { function DragbarHandler(canvas) {
var _dragbars = { var _dragbars = {
x: null, x: null,
y: null y: null
}; };
/** /**
* @return {DragbarHandler} * @return {DragbarHandler}
*/ */
this.apply = function () { this.apply = function () {
if (!canvas.__hasDragbars) { if (!canvas.__hasDragbars) {
this.init(); this.init();
canvas.__hasDragbars = true; canvas.__hasDragbars = true;
} }
this.sync(); this.sync();
if (!this.__handles) { if (!this.__handles) {
this.__handles = new DragHandle(this); this.__handles = new DragHandle(this);
} }
this.__handles.init(); this.__handles.init();
this.bringToFront(); this.bringToFront();
canvas.renderAll(); canvas.renderAll();
return this; return this;
}; };
this.canvas = canvas; this.canvas = canvas;
this.bringToFront = function() { this.bringToFront = function() {
[].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) { [].concat(_dragbars.x, _dragbars.y).forEach(function (dragbar) {
dragbar.bringToFront(); dragbar.bringToFront();
}); });
this.__handles.getHandles().forEach(function (handle) { this.__handles.getHandles().forEach(function (handle) {
handle.bringToFront(); handle.bringToFront();
}); });
}; };
/** /**
* Removes dragbars from canvas * Removes dragbars from canvas
*/ */
this.clear = function () { this.clear = function () {
canvas canvas
.remove(_dragbars.x) .remove(_dragbars.x)
.remove(_dragbars.y) .remove(_dragbars.y)
.renderAll(); .renderAll();
return this; return this;
}; };
this.getTracks = function () { this.getTracks = function () {
return _dragbars; return _dragbars;
}; };
this.resetPosition = function() { this.resetPosition = function() {
if (!_dragbars.y || !_dragbars.x) { if (!_dragbars.y || !_dragbars.x) {
return this; return this;
} }
_dragbars.y.set({ _dragbars.y.set({
left: canvas.width - 30, left: canvas.width - 30,
height: canvas.getImage().height * canvas.getImage().scaleY, height: canvas.getImage().height * canvas.getImage().scaleY,
}).setCoords(); }).setCoords();
_dragbars.x.set({ _dragbars.x.set({
top: canvas.height - 30, top: canvas.height - 30,
width: canvas.getImage().width * canvas.getImage().scaleY, width: canvas.getImage().width * canvas.getImage().scaleY,
}).setCoords(); }).setCoords();
this.__handles.setHandlePosition(); this.__handles.setHandlePosition();
return this; return this;
}; };
/** /**
* @return {DragbarHandler} * @return {DragbarHandler}
*/ */
this.init = function () { this.init = function () {
this.clear(); this.clear();
var typeIsWallpaper = canvas.__type === 'wallpaper'; var typeIsWallpaper = canvas.__type === 'wallpaper';
_dragbars.x = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.x = new fabric.Rect($.extend({}, config.dragBar, {
axis: 'x', axis: 'x',
width: canvas.getImage().width * canvas.getImage().scaleY, width: canvas.getImage().width * canvas.getImage().scaleY,
height: config.dragBar.size, height: config.dragBar.size,
lockMovementY: true, lockMovementY: true,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) // Movement should also be disabled when the user is on wallpaper (repeating paterns)
lockMovementX: typeIsWallpaper, lockMovementX: typeIsWallpaper,
selectable: true, selectable: true,
hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', hoverCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize', moveCursor: typeIsWallpaper ? 'pointer' : 'ew-resize',
})) }))
.addTo(canvas) .addTo(canvas)
.centerH().set({ top: canvas.height - 30 }).setCoords(); .centerH().set({ top: canvas.height - 30 }).setCoords();
_dragbars.y = new fabric.Rect($.extend({}, config.dragBar, { _dragbars.y = new fabric.Rect($.extend({}, config.dragBar, {
axis: 'y', axis: 'y',
width: config.dragBar.size, width: config.dragBar.size,
height: canvas.getImage().height * canvas.getImage().scaleY, height: canvas.getImage().height * canvas.getImage().scaleY,
lockMovementX: true, lockMovementX: true,
// Movement should also be disabled when the user is on wallpaper (repeating paterns) // Movement should also be disabled when the user is on wallpaper (repeating paterns)
lockMovementY: typeIsWallpaper, lockMovementY: typeIsWallpaper,
selectable: true, selectable: true,
hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize', hoverCursor: typeIsWallpaper ? 'pointer': 'ns-resize',
moveCursor: 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);
return this; return this;
}; };
/** /**
* @return {DragbarHandler} * @return {DragbarHandler}
*/ */
this.sync = function () { this.sync = function () {
_dragbars.x.set({left: canvas.getImage().left}).setCoords(); _dragbars.x.set({left: canvas.getImage().left}).setCoords();
_dragbars.y.set({top: canvas.getImage().top}).setCoords(); _dragbars.y.set({top: canvas.getImage().top}).setCoords();
return this; return this;
}; };
} }
module.exports = DragbarHandler; module.exports = DragbarHandler;
+50 -50
View File
@@ -7,69 +7,69 @@ var util = require('./util');
* @param {fabric.Rect} boundingRect * @param {fabric.Rect} boundingRect
*/ */
function Draggable(img, boundingRect) { function Draggable(img, boundingRect) {
var _bounds = boundingRect; var _bounds = boundingRect;
var _img = img; var _img = img;
/** /**
* Triggers when object is moved * Triggers when object is moved
*/ */
function onMove() { function onMove() {
/*jshint validthis: true */ /*jshint validthis: true */
if (!this.__dragging) { if (!this.__dragging) {
//Trigger start-drag on first 'moving' trigger. //Trigger start-drag on first 'moving' trigger.
$(document).trigger('PIE:start-drag'); $(document).trigger('PIE:start-drag');
this.__dragging = true; this.__dragging = true;
}
this.canvas.disableScroll();
util.setPositionInside(this, _bounds);
} }
this.canvas.disableScroll();
this.onMouseUp = function () { util.setPositionInside(this, _bounds);
if (this.__dragging) { }
this.__dragged = true;
this.__dragging = false;
this.canvas.getImageData().setCropData();
if (!util.isMobile()) {
this.canvas.enableScroll();
}
// Trigger event to tell the image has been dragged.
$(document).trigger('PIE:dragged');
}
if (this.__dragged) {
// Always set aperture transparency to false even if image hasn't been dragged this click.
this.canvas.getApertures().setTransparent(false);
}
this.canvas.renderAll();
};
// Attach onMove event to image this.onMouseUp = function () {
_img.on('moving', onMove); if (this.__dragging) {
this.__dragged = true;
this.__dragging = false;
this.canvas.getImageData().setCropData();
if (!util.isMobile()) {
this.canvas.enableScroll();
}
// Trigger event to tell the image has been dragged.
$(document).trigger('PIE:dragged');
}
if (this.__dragged) {
// Always set aperture transparency to false even if image hasn't been dragged this click.
this.canvas.getApertures().setTransparent(false);
}
this.canvas.renderAll();
};
// Attach mouse up event to canvas, can't do mouse up events on canvas objects. // Attach onMove event to image
_img.canvas.on('mouse:up', this.onMouseUp.bind(_img)); _img.on('moving', onMove);
/** // Attach mouse up event to canvas, can't do mouse up events on canvas objects.
_img.canvas.on('mouse:up', this.onMouseUp.bind(_img));
/**
* @param {fabric.Rect} localBoundingRect * @param {fabric.Rect} localBoundingRect
* @return {Draggable} * @return {Draggable}
*/ */
this.enable = function (localBoundingRect) { this.enable = function (localBoundingRect) {
if (localBoundingRect) { if (localBoundingRect) {
_bounds = localBoundingRect; _bounds = localBoundingRect;
} }
// @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect // @TODO Refactor this, see Viewport.calcMinMaxBoundsForRect
if (_img.canvas.getViewport().getData().axis === 'x') { if (_img.canvas.getViewport().getData().axis === 'x') {
_bounds.top.min = _bounds.top.max = _img.top; _bounds.top.min = _bounds.top.max = _img.top;
} else { } else {
_bounds.left.min = _bounds.left.max = _img.left; _bounds.left.min = _bounds.left.max = _img.left;
} }
_img.lockMovementX = _img.lockMovementY = false; _img.lockMovementX = _img.lockMovementY = false;
_img.selectable = true; _img.selectable = true;
_img.hoverCursor = 'move'; _img.hoverCursor = 'move';
return this; return this;
}; };
} }
module.exports = Draggable; module.exports = Draggable;
+97 -97
View File
@@ -4,146 +4,146 @@
var config = require('./config'); var config = require('./config');
function FrameHandler(viewport) { function FrameHandler(viewport) {
var _frames; var _frames;
var _frameType = viewport.canvas.__canvasFrameType; var _frameType = viewport.canvas.__canvasFrameType;
var _frameSize; var _frameSize;
function getFramesAsArray() { function getFramesAsArray() {
return [ return [
_frames.top, _frames.right, _frames.bottom, _frames.left _frames.top, _frames.right, _frames.bottom, _frames.left
]; ];
} }
/** /**
* Sets the 4 rectangles which are used when current canvas should be framed * Sets the 4 rectangles which are used when current canvas should be framed
*/ */
function initFrames() { function initFrames() {
var frame = new fabric.Rect(config.frames.default); var frame = new fabric.Rect(config.frames.default);
_frames = { _frames = {
top: frame.clone(), top: frame.clone(),
right: frame.clone(), right: frame.clone(),
bottom: frame.clone(), bottom: frame.clone(),
left: frame.clone() left: frame.clone()
}; };
getFramesAsArray().forEach(function (o) { getFramesAsArray().forEach(function (o) {
viewport.canvas.add(o); viewport.canvas.add(o);
}); });
} }
function init() { function init() {
initFrames(); initFrames();
} }
init(); init();
/** /**
* @return {String} * @return {String}
*/ */
this.getFrameType = function () { this.getFrameType = function () {
return _frameType; return _frameType;
}; };
this.getFrameSize = function() { this.getFrameSize = function() {
return _frameSize; return _frameSize;
}; };
this.setVisible = function (isVisible) { this.setVisible = function (isVisible) {
isVisible = typeof isVisible === 'undefined' ? true : !!isVisible; isVisible = typeof isVisible === 'undefined' ? true : !!isVisible;
getFramesAsArray().forEach(function (frame) { getFramesAsArray().forEach(function (frame) {
frame.set({ visible: isVisible }); frame.set({ visible: isVisible });
}); });
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
}; };
/** /**
* Sets passed frametype to passed viewwport * Sets passed frametype to passed viewwport
* @param {string} frameType none|image|black|white * @param {string} frameType none|image|black|white
* @return {FrameHandler} * @return {FrameHandler}
*/ */
this.setFrames = function (frameType) { this.setFrames = function (frameType) {
var bounds = viewport.getBounds(); var bounds = viewport.getBounds();
frameType = frameType || _frameType || 'image'; frameType = frameType || _frameType || 'image';
_frameType = frameType; _frameType = frameType;
if (!frameType) { if (!frameType) {
return; return;
} }
if (frameType === 'none') { if (frameType === 'none') {
viewport.canvas.getDragbars().apply(); viewport.canvas.getDragbars().apply();
return this.setVisible(false); return this.setVisible(false);
} }
this.setVisible(true); this.setVisible(true);
getFramesAsArray().forEach(function (o) { getFramesAsArray().forEach(function (o) {
o.set(config.frames[frameType]); o.set(config.frames[frameType]);
}); });
var vpData = viewport.getData(); var vpData = viewport.getData();
var realFrameSize = 29; // Actual real life frame size width in mm. var realFrameSize = 29; // Actual real life frame size width in mm.
_frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX; _frameSize = vpData.ppmm * realFrameSize * viewport.canvas.getImage().scaleX;
_frames.top.height = _frames.top.height =
_frames.bottom.height = _frames.bottom.height =
_frames.right.width = _frames.right.width =
_frames.left.width = _frameSize; _frames.left.width = _frameSize;
_frames.top.width = _frames.bottom.width = vpData.width; _frames.top.width = _frames.bottom.width = vpData.width;
_frames.right.height = _frames.left.height = vpData.height; _frames.right.height = _frames.left.height = vpData.height;
if (frameType === 'image') { if (frameType === 'image') {
_frames.top.width -= _frameSize * 2; _frames.top.width -= _frameSize * 2;
_frames.bottom.width = _frames.top.width; _frames.bottom.width = _frames.top.width;
_frames.right.height -= _frameSize * 2; _frames.right.height -= _frameSize * 2;
_frames.left.height = _frames.right.height; _frames.left.height = _frames.right.height;
_frames.top.set({ _frames.top.set({
top: bounds.top, top: bounds.top,
}).centerH().setCoords(); }).centerH().setCoords();
_frames.bottom.set({ _frames.bottom.set({
top: (bounds.top + bounds.height - _frames.bottom.height) - 1 top: (bounds.top + bounds.height - _frames.bottom.height) - 1
}).centerH().setCoords(); }).centerH().setCoords();
_frames.right.set({ _frames.right.set({
left: (bounds.left + bounds.width - _frames.right.width) - 1 left: (bounds.left + bounds.width - _frames.right.width) - 1
}).centerV().setCoords(); }).centerV().setCoords();
_frames.left.set({ _frames.left.set({
left: bounds.left left: bounds.left
}).centerV().setCoords(); }).centerV().setCoords();
} else { } else {
_frames.top.set({ _frames.top.set({
top: (bounds.top - _frames.top.height) + 1, top: (bounds.top - _frames.top.height) + 1,
}).centerH().setCoords(); }).centerH().setCoords();
_frames.bottom.set({ _frames.bottom.set({
top: (bounds.top + bounds.height) - 1, top: (bounds.top + bounds.height) - 1,
}).centerH().setCoords(); }).centerH().setCoords();
_frames.right.set({ _frames.right.set({
left: (bounds.left + bounds.width) - 1 left: (bounds.left + bounds.width) - 1
}).centerV().setCoords(); }).centerV().setCoords();
_frames.left.set({ _frames.left.set({
left: (bounds.left - _frames.left.width) + 1 left: (bounds.left - _frames.left.width) + 1
}).centerV().setCoords(); }).centerV().setCoords();
} }
viewport.canvas.getDragbars().apply(); viewport.canvas.getDragbars().apply();
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
}; };
} }
module.exports = FrameHandler; module.exports = FrameHandler;
+47 -47
View File
@@ -2,78 +2,78 @@
/* globals fabric */ /* globals fabric */
function GoreHandler(viewport) { function GoreHandler(viewport) {
var _enabled = false; var _enabled = false;
var _lines = []; var _lines = [];
/** /**
* @return {fabric.Line} * @return {fabric.Line}
*/ */
function getLine(left) { function getLine(left) {
return new fabric.Line([0, 0, 0, viewport.getData().height], { return new fabric.Line([0, 0, 0, viewport.getData().height], {
evented: false, evented: false,
strokeDashArray: [5, 5], strokeDashArray: [5, 5],
stroke: '#F31FB3', stroke: '#F31FB3',
strokeWidth: 1, strokeWidth: 1,
left: left, left: left,
top: viewport.getBounds().top top: viewport.getBounds().top
}); });
} }
/** /**
* @return {GoreHandler} * @return {GoreHandler}
*/ */
this.clear = function () { this.clear = function () {
_lines.forEach(function (line) { _lines.forEach(function (line) {
viewport.canvas.remove(line); viewport.canvas.remove(line);
}); });
_lines = []; _lines = [];
return this; return this;
}; };
/** /**
* @param {Boolean} enabled * @param {Boolean} enabled
* @return {GoreHandler} * @return {GoreHandler}
*/ */
this.enable = function (enabled) { this.enable = function (enabled) {
_enabled = enabled; _enabled = enabled;
this.clear(); this.clear();
if (!_enabled) { if (!_enabled) {
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
} }
var viewportData = viewport.getData(); var viewportData = viewport.getData();
var bounds = viewport.getBounds(); var bounds = viewport.getBounds();
var step = viewportData.ppmm * viewportData.image.scaleX * 450; var step = viewportData.ppmm * viewportData.image.scaleX * 450;
/* /*
* First round to 5 digits to fix pixel rounding issues when requested width is an even multiplier of 450mm. * First round to 5 digits to fix pixel rounding issues when requested width is an even multiplier of 450mm.
* Could set precision higher but 5 decimals places should be enough, pixel rounding issues show somewhere * Could set precision higher but 5 decimals places should be enough, pixel rounding issues show somewhere
* around 15 decimals places. * around 15 decimals places.
* Then round up to get correct number of gores. * Then round up to get correct number of gores.
*/ */
var count = Math.ceil((bounds.width / step).toFixed(5)); var count = Math.ceil((bounds.width / step).toFixed(5));
for (var i = 1; i < count; i++) { for (var i = 1; i < count; i++) {
_lines.push(getLine(bounds.left + step * i)); _lines.push(getLine(bounds.left + step * i));
} }
_lines.forEach(function (o) { _lines.forEach(function (o) {
viewport.canvas.add(o); viewport.canvas.add(o);
}); });
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
}; };
/** /**
* @return {GoreHandler} * @return {GoreHandler}
*/ */
this.reset = function () { this.reset = function () {
return this.enable(_enabled); return this.enable(_enabled);
}; };
} }
module.exports = GoreHandler; module.exports = GoreHandler;
+50 -50
View File
@@ -3,70 +3,70 @@
function ImageDataHandler(img) { function ImageDataHandler(img) {
var _cropData; var _cropData;
/** /**
* Gets information about how the cropped image is dragged * Gets information about how the cropped image is dragged
* @return {Object} * @return {Object}
*/ */
this.getCropData = function () { this.getCropData = function () {
return _cropData; return _cropData;
};
this.setCropData = function() {
var viewportBounds = img.canvas.getViewport().getBounds();
if (!viewportBounds) {
return;
}
var dragAxis = img.canvas.getViewport().getData().axis;
var leftDiff = viewportBounds.left - img.left;
var topDiff = viewportBounds.top - img.top;
// Robustness measure to handle the extreme precision of shape positioning in canvas.
var countAsZeroLimit = 1e-5;
leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff;
topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff;
_cropData = {
x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0,
y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0,
viewportWidth: viewportBounds.width,
viewportHeight: viewportBounds.height,
}; };
};
this.setCropData = function() { this.removeCropData = function() {
var viewportBounds = img.canvas.getViewport().getBounds(); _cropData = null;
if (!viewportBounds) { };
return;
}
var dragAxis = img.canvas.getViewport().getData().axis; /**
var leftDiff = viewportBounds.left - img.left;
var topDiff = viewportBounds.top - img.top;
// Robustness measure to handle the extreme precision of shape positioning in canvas.
var countAsZeroLimit = 1e-5;
leftDiff = Math.abs(leftDiff) < countAsZeroLimit ? 0 : leftDiff;
topDiff = Math.abs(topDiff) < countAsZeroLimit ? 0 : topDiff;
_cropData = {
x: dragAxis === 'x' ? (leftDiff) / (img.width * img.scaleX) : 0,
y: dragAxis === 'y' ? (topDiff) / (img.height * img.scaleY) : 0,
viewportWidth: viewportBounds.width,
viewportHeight: viewportBounds.height,
};
};
this.removeCropData = function() {
_cropData = null;
};
/**
* Gets an object containing applied transformations for the Image and also * Gets an object containing applied transformations for the Image and also
* how it is cropped and dragged. * how it is cropped and dragged.
* @return {Object} * @return {Object}
*/ */
this.getData = function () { this.getData = function () {
var viewportData = img.canvas.getViewport().getData(); var viewportData = img.canvas.getViewport().getData();
var returnValue = $.extend( var returnValue = $.extend(
{}, {},
{ {
mirrored: img.canvas.getMirror().getStatus(), mirrored: img.canvas.getMirror().getStatus(),
width: viewportData.dim.width, width: viewportData.dim.width,
height: viewportData.dim.height, height: viewportData.dim.height,
}, },
this.getCropData() this.getCropData()
); );
if (img.canvas.__type === 'canvas') { if (img.canvas.__type === 'canvas') {
var frameHandler = img.canvas.getViewport().getFrameHandler(); var frameHandler = img.canvas.getViewport().getFrameHandler();
returnValue.edge = frameHandler.getFrameType(); returnValue.edge = frameHandler.getFrameType();
returnValue.framed = returnValue.edge !== 'none'; returnValue.framed = returnValue.edge !== 'none';
} }
return returnValue; return returnValue;
}; };
} }
module.exports = ImageDataHandler; module.exports = ImageDataHandler;
+150 -150
View File
@@ -5,198 +5,198 @@ var Canvas = require('./Canvas');
var util = require('./util'); var util = require('./util');
function ImageEditor(canvasId, args) { function ImageEditor(canvasId, args) {
var _canvas; var _canvas;
var _settings = $.extend({ var _settings = $.extend({
// Type defaults to wallpaper // Type defaults to wallpaper
type: 'wallpaper', type: 'wallpaper',
// canvasFrameType defaults to image on frame // canvasFrameType defaults to image on frame
canvasFrameType: 'image', canvasFrameType: 'image',
canvasFrameSize: 2.9, canvasFrameSize: 2.9,
// Default texts on the buttons // Default texts on the buttons
texts: { texts: {
showThreeD: '3d', showThreeD: '3d',
hideThreeD: 'Flat', hideThreeD: 'Flat',
showMurals: 'Show Murals Panel', showMurals: 'Show Murals Panel',
hideMurals: 'Hide Murals Panel', hideMurals: 'Hide Murals Panel',
showRulers: 'Show Ruler', showRulers: 'Show Ruler',
hideRulers: 'Hide Ruler', hideRulers: 'Hide Ruler',
showFullscreen: 'Fullscreen', showFullscreen: 'Fullscreen',
exitFullscreen: 'Exit Fullscreen', exitFullscreen: 'Exit Fullscreen',
cm: 'cm', cm: 'cm',
inch: 'inch' inch: 'inch'
}, },
// Default dimensions // Default dimensions
dimensions: { dimensions: {
width: 800, width: 800,
height: 600 height: 600
}, },
// Default unit // Default unit
unit: 'cm', unit: 'cm',
isVisibleFullscreenButton: true isVisibleFullscreenButton: true
}, args); }, args);
// Initialize canvas // Initialize canvas
_canvas = new Canvas(canvasId, _settings.dimensions); _canvas = new Canvas(canvasId, _settings.dimensions);
// Let Canvas know which type it is, canvas or wallpaper since it is // Let Canvas know which type it is, canvas or wallpaper since it is
// accessible for all objects contained within. // accessible for all objects contained within.
_canvas.set({
__type: _settings.type,
__texts: _settings.texts
});
// Adding buttons to the canvas depending on which type is active.
// It might be better that this resides somewhere else, either in Canvas or
// during the initialization of the image editor.
if (_canvas.__type === 'canvas') {
_canvas.getButtonMenu()
.addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () {
_canvas.toggle3D(this.isActive());
});
_canvas.set({ _canvas.set({
__type: _settings.type, __canvasFrameType: _settings.canvasFrameType,
__texts: _settings.texts __canvasFrameSize: _settings.canvasFrameSize,
}); });
} else {
_canvas.getButtonMenu()
.addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () {
_canvas.getViewport().getGores().enable(this.isActive());
})
.addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () {
_canvas.getViewport().getRulers().enable(this.isActive());
});
}
// Adding buttons to the canvas depending on which type is active. if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) {
// It might be better that this resides somewhere else, either in Canvas or _canvas.getButtonMenu()
// during the initialization of the image editor. .addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () {
if (_canvas.__type === 'canvas') { util.toggleFullscreen(_canvas.getSelectionElement().parentNode);
_canvas.getButtonMenu() });
.addItem('toggle3d', [_settings.texts.showThreeD, _settings.texts.hideThreeD], function () { }
_canvas.toggle3D(this.isActive());
}); _canvas.getButtonMenu().render();
_canvas.set({
__canvasFrameType: _settings.canvasFrameType, // Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active.
__canvasFrameSize: _settings.canvasFrameSize, $(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
}); var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
} else {
_canvas.getButtonMenu() if (isFullscreen) {
.addItem('toggleMurals', [_settings.texts.showMurals, _settings.texts.hideMurals], function () { return;
_canvas.getViewport().getGores().enable(this.isActive());
})
.addItem('toggleRulers', [_settings.texts.showRulers, _settings.texts.hideRulers], function () {
_canvas.getViewport().getRulers().enable(this.isActive());
});
} }
if (util.supportsFullscreen() && _settings.isVisibleFullscreenButton) { _canvas.getButtonMenu().getItems().forEach(function(button) {
_canvas.getButtonMenu() if (button.getId() === 'toggleFullscreen') {
.addItem('toggleFullscreen', [_settings.texts.showFullscreen, _settings.texts.exitFullscreen], function () { button.setActive(false);
util.toggleFullscreen(_canvas.getSelectionElement().parentNode); }
});
}
_canvas.getButtonMenu().render();
// Binding fullscreen change event to the image-editor wrapper. This way we can set the correct button active.
$(_canvas.getSelectionElement().parentNode).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
var isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
if (isFullscreen) {
return;
}
_canvas.getButtonMenu().getItems().forEach(function(button) {
if (button.getId() === 'toggleFullscreen') {
button.setActive(false);
}
});
}); });
/** });
/**
* Crops image to desired dimensions * Crops image to desired dimensions
* @param {int} width [description] * @param {int} width [description]
* @param {int} height [description] * @param {int} height [description]
* @param {string} unit cm|inch * @param {string} unit cm|inch
* @return {ImageEditor} * @return {ImageEditor}
*/ */
this.crop = function (width, height, unit, removeTransparency) { this.crop = function (width, height, unit, removeTransparency) {
removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false; removeTransparency = typeof removeTransparency !== 'undefined' ? removeTransparency : false;
if (!width || !height) { if (!width || !height) {
return this; return this;
} }
unit = typeof unit !== 'undefined' ? unit : _settings.unit; unit = typeof unit !== 'undefined' ? unit : _settings.unit;
var viewport = _canvas.getViewport(); var viewport = _canvas.getViewport();
var frameType = _canvas.__canvasFrameType; var frameType = _canvas.__canvasFrameType;
if (frameType === 'image') { if (frameType === 'image') {
var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize; var canvasFrameSize = unit === 'inch' ? _canvas.__canvasFrameSize / 2.54 : _canvas.__canvasFrameSize;
width += 2 * canvasFrameSize; width += 2 * canvasFrameSize;
height += 2 * canvasFrameSize; height += 2 * canvasFrameSize;
} }
viewport.set(width, height, unit); viewport.set(width, height, unit);
var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height); var shouldBeCropped = util.isAspectChanged(_canvas.getImage().width, _canvas.getImage().height, width, height);
if (shouldBeCropped) { if (shouldBeCropped) {
_canvas.getImage().__dragged = false; _canvas.getImage().__dragged = false;
_canvas.getImage().__cropped = true; _canvas.getImage().__cropped = true;
} }
else { else {
_canvas.getImage().__cropped = false; _canvas.getImage().__cropped = false;
} }
if (removeTransparency) { if (removeTransparency) {
_canvas.getApertures().setTransparent(false); _canvas.getApertures().setTransparent(false);
} }
return this; return this;
}; };
this.getCropRatio = function () { this.getCropRatio = function () {
var image = _canvas.getImage(); var image = _canvas.getImage();
var cropData = _canvas.getImageData().getCropData(); var cropData = _canvas.getImageData().getCropData();
if (!cropData) { if (!cropData) {
return false; return false;
} }
var scaledImageWidth = image.width * image.scaleX; var scaledImageWidth = image.width * image.scaleX;
var scaledImageHeight = image.height * image.scaleY; var scaledImageHeight = image.height * image.scaleY;
var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100; var ratioWidth = Math.round(cropData.viewportWidth / scaledImageWidth * 100) / 100;
var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100; var ratioHeight = Math.round(cropData.viewportHeight / scaledImageHeight * 100) / 100;
return {width: ratioWidth, height: ratioHeight}; return {width: ratioWidth, height: ratioHeight};
}; };
/** /**
* @param {string|object} key * @param {string|object} key
* @param {object} defaultValue * @param {object} defaultValue
* @return {object} * @return {object}
*/ */
this.get = function (key, defaultValue) { this.get = function (key, defaultValue) {
var value = _settings[key]; var value = _settings[key];
return typeof value === 'undefined' ? defaultValue : value; return typeof value === 'undefined' ? defaultValue : value;
}; };
/** /**
* Loads the image into the canvas. * Loads the image into the canvas.
* @param {Number|String} url * @param {Number|String} url
* @param {Function} callback * @param {Function} callback
* @return {ImageEditor} * @return {ImageEditor}
*/ */
this.loadImage = function (url, callback) { this.loadImage = function (url, callback) {
callback = typeof callback === 'function' ? callback : function () {}; callback = typeof callback === 'function' ? callback : function () {};
fabric.util.loadImage(this._url = url, function (obj) { fabric.util.loadImage(this._url = url, function (obj) {
if(obj === null) { if(obj === null) {
throw new Error('Error loading ' + url); throw new Error('Error loading ' + url);
} }
var img = new fabric.Image(obj); var img = new fabric.Image(obj);
_canvas.setImage(img); _canvas.setImage(img);
img.__url = url; img.__url = url;
img.sendToBack(); img.sendToBack();
callback(img); callback(img);
}, { crossOrigin: 'anonymous' }); }, { crossOrigin: 'anonymous' });
return this; return this;
}; };
/** /**
* @param {string|object} key * @param {string|object} key
* @param {object} value * @param {object} value
* @return {ImageEditor} * @return {ImageEditor}
*/ */
this.set = function (key, value) { this.set = function (key, value) {
$.extend(_settings, util.assertKeyValuePair(key, value)); $.extend(_settings, util.assertKeyValuePair(key, value));
return this; return this;
}; };
util.setProperties(this, { util.setProperties(this, {
canvas: { canvas: {
get: function () { get: function () {
return _canvas; return _canvas;
} }
} }
}); });
} }
module.exports = ImageEditor; module.exports = ImageEditor;
+10 -10
View File
@@ -2,22 +2,22 @@
function MirrorHandler(img) { function MirrorHandler(img) {
var _mirrored = 0; var _mirrored = 0;
/** /**
* @param {Boolean} checked * @param {Boolean} checked
* @return {MirrorHandler} * @return {MirrorHandler}
*/ */
this.set = function(checked) { this.set = function(checked) {
_mirrored = (img.flipX = checked) ? 1 : 0; _mirrored = (img.flipX = checked) ? 1 : 0;
img.setCoords().canvas.renderAll(); img.setCoords().canvas.renderAll();
return this; return this;
}; };
this.getStatus = function() { this.getStatus = function() {
return _mirrored; return _mirrored;
}; };
} }
+92 -92
View File
@@ -6,130 +6,130 @@ var TextButton = require('./TextButton');
var config = require('./config'); var config = require('./config');
function RulerHandler(viewport) { function RulerHandler(viewport) {
var _enabled = false; var _enabled = false;
var _lines = { x: null, y: null }; var _lines = { x: null, y: null };
var _rect = { x: null, y: null }; var _rect = { x: null, y: null };
function updateRulerText(ruler) { function updateRulerText(ruler) {
var axis = ruler.axis; var axis = ruler.axis;
var bounds = viewport.getBounds(); var bounds = viewport.getBounds();
var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]); var pos = util.assertBetween(ruler[axis], bounds.min[axis], bounds.max[axis]);
ruler.marker[axis] = ruler[axis] = pos; ruler.marker[axis] = ruler[axis] = pos;
var posWithinBounds = ruler[axis] - bounds[axis]; var posWithinBounds = ruler[axis] - bounds[axis];
var viewportData = viewport.getData(); var viewportData = viewport.getData();
var imageData = viewport.canvas.getImage(); var imageData = viewport.canvas.getImage();
var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX; var pixelsPerCm = viewportData.ppmm * 10 * imageData.scaleX;
var dim = posWithinBounds / pixelsPerCm; var dim = posWithinBounds / pixelsPerCm;
var units = viewportData.dim.units; var units = viewportData.dim.units;
if (units === 'inch') { if (units === 'inch') {
dim /= 2.54; dim /= 2.54;
}
if (axis === 'top') {
dim = viewportData.dim.height - dim;
}
var value = Math.round(dim * 100) / 100;
if(units === 'cm') {
value = Math.round(value);
}
var label = viewport.canvas.__texts[units] || 'cm';
ruler.setText(value + ' ' + label);
} }
if (axis === 'top') {
dim = viewportData.dim.height - dim;
}
var value = Math.round(dim * 100) / 100;
if(units === 'cm') {
value = Math.round(value);
}
var label = viewport.canvas.__texts[units] || 'cm';
ruler.setText(value + ' ' + label);
}
var Event = { var Event = {
/** /**
* Triggers when handlebar is moved * Triggers when handlebar is moved
*/ */
onMove: function () { onMove: function () {
updateRulerText(this); updateRulerText(this);
} }
}; };
/** /**
* @return {fabric.Line} * @return {fabric.Line}
*/ */
function getLine(axis) { function getLine(axis) {
var bounds = viewport.getBounds(); var bounds = viewport.getBounds();
return new fabric.Line([ return new fabric.Line([
0, 0, 0, 0,
axis === 'x' ? bounds.width : 0, axis === 'x' ? bounds.width : 0,
axis === 'y' ? bounds.height : 0 axis === 'y' ? bounds.height : 0
], { ], {
evented: false, evented: false,
strokeDashArray: [5, 5], strokeDashArray: [5, 5],
stroke: '#000', stroke: '#000',
strokeWidth: 1, strokeWidth: 1,
top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top,
left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left
}); });
} }
/** /**
* @return {RulerHandler} * @return {RulerHandler}
*/ */
this.clear = function () { this.clear = function () {
[].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) { [].concat(_rect.x, _rect.y, _lines.x, _lines.y).forEach(function (o) {
viewport.canvas.remove(o); viewport.canvas.remove(o);
}); });
return this; return this;
}; };
/** /**
* @param {Boolean} enabled * @param {Boolean} enabled
* @return {RulerHandler} * @return {RulerHandler}
*/ */
this.enable = function (enabled) { this.enable = function (enabled) {
var bounds = viewport.getBounds(); var bounds = viewport.getBounds();
var keepPosition = ( var keepPosition = (
enabled && (_enabled === enabled) && enabled && (_enabled === enabled) &&
_lines.x && (Math.abs(_lines.x.width - bounds.width) < 1) && _lines.x && (Math.abs(_lines.x.width - bounds.width) < 1) &&
_lines.y && (Math.abs(_lines.y.height - bounds.height) < 1) _lines.y && (Math.abs(_lines.y.height - bounds.height) < 1)
); );
if (keepPosition) { if (keepPosition) {
updateRulerText(_rect.x); updateRulerText(_rect.x);
updateRulerText(_rect.y); updateRulerText(_rect.y);
return this; return this;
} }
_enabled = enabled; _enabled = enabled;
this.clear(); this.clear();
if (!_enabled) { if (!_enabled) {
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
} }
_lines = { x: getLine('x'), y: getLine('y') }; _lines = { x: getLine('x'), y: getLine('y') };
viewport.canvas.add(_lines.x); viewport.canvas.add(_lines.x);
viewport.canvas.add(_lines.y); viewport.canvas.add(_lines.y);
_rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true) _rect.x = new TextButton('horizontalRuler', 'H', config.rulerHandle, true)
.set(config.rulerHandle.x(_lines, bounds)) .set(config.rulerHandle.x(_lines, bounds))
.addTo(viewport.canvas) .addTo(viewport.canvas)
.on('moving', Event.onMove) .on('moving', Event.onMove)
.trigger('moving'); .trigger('moving');
_rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true) _rect.y = new TextButton('verticalRuler', 'V', config.rulerHandle, true)
.set(config.rulerHandle.y(_lines, bounds)) .set(config.rulerHandle.y(_lines, bounds))
.addTo(viewport.canvas) .addTo(viewport.canvas)
.on('moving', Event.onMove) .on('moving', Event.onMove)
.trigger('moving'); .trigger('moving');
viewport.canvas.renderAll(); viewport.canvas.renderAll();
return this; return this;
}; };
/** /**
* @return {RulerHandler} * @return {RulerHandler}
*/ */
this.reset = function () { this.reset = function () {
return this.enable(_enabled); return this.enable(_enabled);
}; };
} }
module.exports = RulerHandler; module.exports = RulerHandler;
+81 -81
View File
@@ -11,113 +11,113 @@ var config = require('./config');
* @param {bool} isActive * @param {bool} isActive
*/ */
function TextButton(id, text, settings, isActive) { function TextButton(id, text, settings, isActive) {
/* jshint unused:false */ /* jshint unused:false */
fabric.Group.call(this); fabric.Group.call(this);
var __active = isActive || false; var __active = isActive || false;
var _callback = null; var _callback = null;
var _rect = null; var _rect = null;
var _text = null; var _text = null;
var _id = id; var _id = id;
var width = settings.rect ? settings.rect.width : 0; var width = settings.rect ? settings.rect.width : 0;
var height = settings.rect ? settings.rect.height : 0; var height = settings.rect ? settings.rect.height : 0;
var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect); var _rectSettings = $.extend({}, config.textButton.rect(width, height), settings.rect);
var _textSettings = $.extend({}, config.textButton.text, settings.text, { var _textSettings = $.extend({}, config.textButton.text, settings.text, {
text: Array.isArray(text) ? text[0] : text, text: Array.isArray(text) ? text[0] : text,
textActive: Array.isArray(text) ? text[1] : text, textActive: Array.isArray(text) ? text[1] : text,
}); });
this.selectable = true; this.selectable = true;
// Make sure we're interactive // Make sure we're interactive
this.disabled = false; this.disabled = false;
this.hoverCursor = config.textButton.cursor; this.hoverCursor = config.textButton.cursor;
// Initialize text and rectangle // Initialize text and rectangle
_text = new fabric.Text('', _textSettings); _text = new fabric.Text('', _textSettings);
_rect = new fabric.Rect(_rectSettings); _rect = new fabric.Rect(_rectSettings);
this.addWithUpdate(_rect).addWithUpdate(_text); this.addWithUpdate(_rect).addWithUpdate(_text);
/** /**
* @param {String} text * @param {String} text
* @return {TextButton} * @return {TextButton}
*/ */
this.setText = function(text) { this.setText = function(text) {
_text.setText((text || '').toString()).setCoords(); _text.setText((text || '').toString()).setCoords();
if (_rectSettings.dynamicW) { if (_rectSettings.dynamicW) {
this.width = _rect.width = _text.width + config.textButton.padding; this.width = _rect.width = _text.width + config.textButton.padding;
} }
if (_rectSettings.dynamicH) { if (_rectSettings.dynamicH) {
this.height = _rect.height = _text.height + config.textButton.padding; this.height = _rect.height = _text.height + config.textButton.padding;
} }
return this.setCoords(); return this.setCoords();
}; };
this.getId = function() { this.getId = function() {
return _id; return _id;
}; };
/** /**
* @return {Boolean} * @return {Boolean}
*/ */
this.isActive = function() { this.isActive = function() {
return this.__active; return this.__active;
}; };
function toggleActiveStyle() { function toggleActiveStyle() {
/*jshint validthis: true */ /*jshint validthis: true */
_rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']); _rect.setFill(_rectSettings[this.isActive() ? 'activeFill' : 'fill']);
_text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']); _text.setFill(_textSettings[this.isActive() ? 'activeFill' : 'fill']);
this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']); this.setText(_textSettings[this.isActive() ? 'textActive' : 'text']);
}
function handleMouseDown(e) {
/*jshint validthis: true */
toggleActiveStyle.call(this);
_callback.call(this, e);
if (this.__group) {
this.__group.render();
} }
}
function handleMouseDown(e) { this.onClick = function(callback) {
/*jshint validthis: true */ _callback = callback || function() {};
toggleActiveStyle.call(this); this.on('mousedown', function (e) {
_callback.call(this, e); // As inactive buttons are still clickable, we first check if the button is disabled.
// Only then we should do stuff.
if (!this.disabled) {
this.__active = !this.__active;
handleMouseDown.call(this, e);
}
}.bind(this));
return this;
};
if (this.__group) { this.setActive = function (isActive) {
this.__group.render(); this.__active = typeof isActive === 'undefined' ? true : !!isActive;
} toggleActiveStyle.call(this);
} };
this.onClick = function(callback) { this.setDisabled = function (isDisabled)
_callback = callback || function() {}; {
this.on('mousedown', function (e) { this.disabled = isDisabled;
// As inactive buttons are still clickable, we first check if the button is disabled.
// Only then we should do stuff.
if (!this.disabled) {
this.__active = !this.__active;
handleMouseDown.call(this, e);
}
}.bind(this));
return this;
};
this.setActive = function (isActive) { _rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']);
this.__active = typeof isActive === 'undefined' ? true : !!isActive; _text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']);
toggleActiveStyle.call(this);
};
this.setDisabled = function (isDisabled) this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor;
{ };
this.disabled = isDisabled;
_rect.setFill(_rectSettings[this.disabled ? 'disabledFill' : 'fill']); if (_textSettings.text) {
_text.setFill(_textSettings[this.disabled ? 'disabledFill' : 'fill']); this.setText(_textSettings.text);
}
this.hoverCursor = this.disabled ? config.textButton.disabledCursor : config.textButton.cursor;
};
if (_textSettings.text) {
this.setText(_textSettings.text);
}
} }
TextButton.prototype = Object.create(fabric.Group.prototype); TextButton.prototype = Object.create(fabric.Group.prototype);
+145 -145
View File
@@ -7,203 +7,203 @@ var RulerHandler = require('./RulerHandler');
var util = require('./util'); var util = require('./util');
function Viewport(canvas) { function Viewport(canvas) {
var _beams = []; var _beams = [];
var _borderWidth = 2; var _borderWidth = 2;
var _data = null; var _data = null;
var _rect; var _rect;
var self = this; var self = this;
/** /**
* Render the diagonal lines from viewport to edge of the canvas * Render the diagonal lines from viewport to edge of the canvas
*/ */
function drawBeams() { function drawBeams() {
_beams.forEach(function (beam) { _beams.forEach(function (beam) {
canvas.remove(beam); canvas.remove(beam);
}); });
_beams = []; _beams = [];
// TOP LEFT // TOP LEFT
_beams.push(new fabric.Line( _beams.push(new fabric.Line(
[_rect.left, _rect.top, _rect.left - _rect.top, -1], { [_rect.left, _rect.top, _rect.left - _rect.top, -1], {
stroke: '#fff', stroke: '#fff',
strokeWidth: 2, strokeWidth: 2,
} }
)); ));
// TOP RIGHT // TOP RIGHT
_beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width })); _beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width }));
// BOTTOM RIGHT // BOTTOM RIGHT
_beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height })); _beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height }));
// BOTTOM LEFT // BOTTOM LEFT
_beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height })); _beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height }));
_beams.forEach(function (o) { _beams.forEach(function (o) {
canvas.add(o); canvas.add(o);
o.bringToFront(); o.bringToFront();
}); });
} }
/** /**
* Gets an object with min / max values for each axis, based on the bounds * Gets an object with min / max values for each axis, based on the bounds
* of passed fabric.Rect * of passed fabric.Rect
* @param {fabric.Rect} rect * @param {fabric.Rect} rect
* @return {Object} * @return {Object}
*/ */
function calcMinMaxBoundsForRect(rect, img) { function calcMinMaxBoundsForRect(rect, img) {
return { return {
left: { left: {
min: rect.left + rect.width - (img.width * img.scaleX), min: rect.left + rect.width - (img.width * img.scaleX),
max: rect.left max: rect.left
}, },
top: { top: {
min: rect.top + rect.height - (img.height * img.scaleY), min: rect.top + rect.height - (img.height * img.scaleY),
max: rect.top max: rect.top
} }
}; };
} }
/** /**
* Applies viewport to page * Applies viewport to page
*/ */
function apply() { function apply() {
var cropData = canvas.getImageData().getCropData(); var cropData = canvas.getImageData().getCropData();
canvas.remove(_rect); canvas.remove(_rect);
_rect = new fabric.Rect({ _rect = new fabric.Rect({
evented: false, evented: false,
fill: 'transparent', fill: 'transparent',
width: _data.width, width: _data.width,
height: _data.height, height: _data.height,
stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff', stroke: canvas.__type === 'canvas' ? 'transparent' : '#fff',
strokeWidth: _borderWidth, strokeWidth: _borderWidth,
}); });
_rect.width += _borderWidth; _rect.width += _borderWidth;
_rect.height += _borderWidth; _rect.height += _borderWidth;
_rect.addTo(canvas).center().setCoords(); _rect.addTo(canvas).center().setCoords();
if (cropData) { if (cropData) {
var viewportBounds = _rect.getInsideBoundingRect(); var viewportBounds = _rect.getInsideBoundingRect();
// Calculate the new position after screenresize and when the // Calculate the new position after screenresize and when the
// image already has been cropped to a certain position. // image already has been cropped to a certain position.
var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x); var left = viewportBounds.left - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x);
var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y); var top = viewportBounds.top - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y);
canvas.getImage().set({ left: left, top: top }).setCoords(); canvas.getImage().set({ left: left, top: top }).setCoords();
} else { } else {
canvas.getImage().center().setCoords(); canvas.getImage().center().setCoords();
canvas.getImageData().setCropData(); canvas.getImageData().setCropData();
}
if(canvas.__type !== 'wallpaper') {
canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage()));
canvas.getApertures().apply(_data.axis, _rect.getBoundingRect());
} else {
canvas.getApertures().disable();
}
if (canvas.__type !== 'canvas') {
drawBeams();
} else {
self.setFrame(canvas.__canvasFrameType);
}
canvas.getDragbars().apply();
// Apertures sometimes overlaps the viewports bounding rect.
// Solve this by bringing it to the front after apertures are applied.
_rect.bringToFront();
} }
this.canvas = canvas; if(canvas.__type !== 'wallpaper') {
canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage()));
canvas.getApertures().apply(_data.axis, _rect.getBoundingRect());
} else {
canvas.getApertures().disable();
}
this.getBounds = function () { if (canvas.__type !== 'canvas') {
return _rect ? _rect.getInsideBoundingRect() : null; drawBeams();
}; } else {
self.setFrame(canvas.__canvasFrameType);
}
/** canvas.getDragbars().apply();
// Apertures sometimes overlaps the viewports bounding rect.
// Solve this by bringing it to the front after apertures are applied.
_rect.bringToFront();
}
this.canvas = canvas;
this.getBounds = function () {
return _rect ? _rect.getInsideBoundingRect() : null;
};
/**
* @return {Viewport} * @return {Viewport}
*/ */
this.reset = function () { this.reset = function () {
if (_data) { if (_data) {
return this.set(_data.dim.width, _data.dim.height, _data.dim.units); return this.set(_data.dim.width, _data.dim.height, _data.dim.units);
} }
return this; return this;
}; };
/** /**
* @param {Number} width * @param {Number} width
* @param {Number} height * @param {Number} height
* @param {string} units * @param {string} units
* @return {Viewport} * @return {Viewport}
*/ */
this.set = function (width, height, units) { this.set = function (width, height, units) {
if (!width || !height) { if (!width || !height) {
return this; return this;
} }
_data = util.calcCrop(canvas.getImage(), width, height, units); _data = util.calcCrop(canvas.getImage(), 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));
if (!isAspectTheSame) { if (!isAspectTheSame) {
canvas.getImageData().removeCropData(); canvas.getImageData().removeCropData();
} }
apply(); apply();
this.getGores().reset(); this.getGores().reset();
this.getRulers().reset(); this.getRulers().reset();
if (canvas.getImage().__cropped && !isAspectTheSame) { if (canvas.getImage().__cropped && !isAspectTheSame) {
canvas.getApertures().setTransparent(true); canvas.getApertures().setTransparent(true);
// Trigger event to tell the image needs to be dragged. // Trigger event to tell the image needs to be dragged.
$(document).trigger('PIE:needs-dragging', { axis: _data.axis }); $(document).trigger('PIE:needs-dragging', { axis: _data.axis });
} }
canvas.getButtonMenu().bringToFront(); canvas.getButtonMenu().bringToFront();
return this; return this;
}; };
/** /**
* @param {string} frameType white|black|image|none * @param {string} frameType white|black|image|none
* @return {Viewport} * @return {Viewport}
*/ */
this.setFrame = function (frameType) { this.setFrame = function (frameType) {
this.getFrameHandler().setFrames(frameType); this.getFrameHandler().setFrames(frameType);
var buttons = canvas.getButtonMenu().getItems(); var buttons = canvas.getButtonMenu().getItems();
if (frameType === 'none') { if (frameType === 'none') {
buttons[0].setDisabled(true); buttons[0].setDisabled(true);
} }
else { else {
buttons[0].setDisabled(false); buttons[0].setDisabled(false);
} }
canvas.getButtonMenu().bringToFront(); canvas.getButtonMenu().bringToFront();
canvas.refresh3dView(); canvas.refresh3dView();
}; };
this.getData = function () { this.getData = function () {
return _data; return _data;
}; };
var _frameHandler = null; var _frameHandler = null;
this.getFrameHandler = function () { this.getFrameHandler = function () {
return _frameHandler || (_frameHandler = new FrameHandler(this)); return _frameHandler || (_frameHandler = new FrameHandler(this));
}; };
this.getGores = function () { this.getGores = function () {
return this.__goreHandler || (this.__goreHandler = new GoreHandler(this)); return this.__goreHandler || (this.__goreHandler = new GoreHandler(this));
}; };
this.getRulers = function () { this.getRulers = function () {
return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this)); return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this));
}; };
} }
+6 -6
View File
@@ -1,10 +1,10 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
frames: require('./config/frames'), frames: require('./config/frames'),
textButton: require('./config/text-button'), textButton: require('./config/text-button'),
buttonMenu: require('./config/button-menu'), buttonMenu: require('./config/button-menu'),
rulerHandle: require('./config/ruler-handle'), rulerHandle: require('./config/ruler-handle'),
dragHandle: require('./config/drag-handle'), dragHandle: require('./config/drag-handle'),
dragBar: require('./config/drag-bar') dragBar: require('./config/drag-bar')
}; };
+32 -32
View File
@@ -2,40 +2,40 @@
module.exports = { module.exports = {
canvas: { canvas: {
margin: 5, margin: 5,
text: { text: {
fill: '#ffffff', fill: '#ffffff',
activeFill: '#ffffff', activeFill: '#ffffff',
},
rect: {
fill: '#343434',
activeFill: '#494949',
},
}, },
rect: {
'photo-wallpaper': { fill: '#343434',
margin: 5, activeFill: '#494949',
text: {
fill: '#ffffff',
activeFill: '#ffffff',
},
rect: {
fill: '#000000',
activeFill: '#444444',
},
}, },
},
wallpaper: { 'photo-wallpaper': {
margin: 5, margin: 5,
text: { text: {
fill: '#ffffff', fill: '#ffffff',
activeFill: '#ffffff', activeFill: '#ffffff',
}, },
rect: { rect: {
fill: '#343434', fill: '#000000',
activeFill: '#494949', activeFill: '#444444',
}, },
} },
wallpaper: {
margin: 5,
text: {
fill: '#ffffff',
activeFill: '#ffffff',
},
rect: {
fill: '#343434',
activeFill: '#494949',
},
}
}; };
+2 -2
View File
@@ -1,6 +1,6 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
fill: '#bbbbbb', fill: '#bbbbbb',
size: 20, size: 20,
}; };
+12 -12
View File
@@ -1,16 +1,16 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
text: { text: {
fontFamily: 'breuer', fontFamily: 'breuer',
fontSize: 12, fontSize: 12,
fill: '#ffffff', fill: '#ffffff',
originX: 'center', originX: 'center',
top: 2, top: 2,
}, },
rect: { rect: {
fill: '#666666', fill: '#666666',
height: 20, height: 20,
originX: 'center', originX: 'center',
}, },
}; };
+18 -18
View File
@@ -2,26 +2,26 @@
module.exports = { module.exports = {
default: { default: {
fill: '#000000', fill: '#000000',
stroke: '#f31fb3', stroke: '#f31fb3',
width: 1, width: 1,
height: 1, height: 1,
}, },
image: { image: {
fill: 'rgba(0,0,0,0.2)', fill: 'rgba(0,0,0,0.2)',
strokeWidth: 1, strokeWidth: 1,
}, },
black: { black: {
fill: '#000000', fill: '#000000',
strokeWidth: 0, strokeWidth: 0,
}, },
white: { white: {
fill: '#ffffff', fill: '#ffffff',
strokeWidth: 0, strokeWidth: 0,
}, },
}; };
+40 -40
View File
@@ -2,46 +2,46 @@
module.exports = { module.exports = {
line: function(axis, bounds) { line: function(axis, bounds) {
return { return {
evented: false, evented: false,
strokeDashArray: [5, 5], strokeDashArray: [5, 5],
stroke: '#000', stroke: '#000',
strokeWidth: 1, strokeWidth: 1,
top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top, top: axis === 'x' ? bounds.top + bounds.height / 2 : bounds.top,
left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left left: axis === 'y' ? bounds.left + bounds.width / 2 : bounds.left
}; };
}, },
text: { text: {
fontSize: 12, fontSize: 12,
width: 75, width: 75,
height: 20, height: 20,
fill: '#FFFFFF', fill: '#FFFFFF',
}, },
x: function(lines, bounds) { x: function(lines, bounds) {
return { return {
axis: 'left', axis: 'left',
marker: lines.y, marker: lines.y,
top: Math.ceil(bounds.top + bounds.height + 5), top: Math.ceil(bounds.top + bounds.height + 5),
left: lines.y.left, left: lines.y.left,
originX: 'center', originX: 'center',
lockMovementY: true, lockMovementY: true,
moveCursor: 'ew-resize', moveCursor: 'ew-resize',
hoverCursor: 'ew-resize', hoverCursor: 'ew-resize',
}; };
}, },
y: function(lines, bounds) { y: function(lines, bounds) {
return { return {
axis: 'top', axis: 'top',
marker: lines.x, marker: lines.x,
top: lines.x.top, top: lines.x.top,
left: Math.ceil(bounds.left + bounds.width + 5), left: Math.ceil(bounds.left + bounds.width + 5),
originY: 'center', originY: 'center',
lockMovementX: true, lockMovementX: true,
moveCursor: 'ns-resize', moveCursor: 'ns-resize',
hoverCursor: 'ns-resize', hoverCursor: 'ns-resize',
}; };
} }
}; };
+24 -24
View File
@@ -2,30 +2,30 @@
module.exports = { module.exports = {
rect: function(width, height) { rect: function(width, height) {
return { return {
fill: '#343434', fill: '#343434',
activeFill: '#494949', activeFill: '#494949',
disabledFill: '#494949', disabledFill: '#494949',
originX: 'center', originX: 'center',
originY: 'center', originY: 'center',
width: width || 1, width: width || 1,
dynamicW: !width, dynamicW: !width,
height: height || 1, height: height || 1,
dynamicH: !height, dynamicH: !height,
}; };
}, },
text: { text: {
fill: '#ffffff', fill: '#ffffff',
disabledFill: '#999999', disabledFill: '#999999',
fontFamily: 'breuer', fontFamily: 'breuer',
fontSize: 14, fontSize: 14,
originX: 'center', originX: 'center',
originY: 'center', originY: 'center',
}, },
cursor: 'pointer', cursor: 'pointer',
disabledCursor: 'default', disabledCursor: 'default',
padding: 20, padding: 20,
}; };
+43 -43
View File
@@ -6,59 +6,59 @@ var util = require('./util');
function ExtendFabricFunctionality() { function ExtendFabricFunctionality() {
// Set default values for the fabric canvas // Set default values for the fabric canvas
$.extend(fabric.Object.prototype, { $.extend(fabric.Object.prototype, {
cornerSize: 0, cornerSize: 0,
hasBorders: false, hasBorders: false,
hasControls: false, hasControls: false,
padding: 0, padding: 0,
selectable: false, selectable: false,
strokeWidth: 0, strokeWidth: 0,
addTo: function(canvas) { addTo: function(canvas) {
canvas.add(this); canvas.add(this);
return this; return this;
}, },
}); });
util.setProperties(fabric.Image.prototype, { util.setProperties(fabric.Image.prototype, {
drag: { drag: {
get: function() { get: function() {
return this.__draggable || (this.__draggable = new Draggable(this)); return this.__draggable || (this.__draggable = new Draggable(this));
} }
} }
}); });
$.extend(fabric.Rect.prototype, { $.extend(fabric.Rect.prototype, {
/** /**
* Gets the inner bounds of this fabric.Rect * Gets the inner bounds of this fabric.Rect
* @return {Object} * @return {Object}
*/ */
getInsideBoundingRect: function() { getInsideBoundingRect: function() {
var bounds = this.getBoundingRect(); var bounds = this.getBoundingRect();
var returnValue = { var returnValue = {
left: bounds.left + this.strokeWidth, left: bounds.left + this.strokeWidth,
top: bounds.top + this.strokeWidth, top: bounds.top + this.strokeWidth,
width: bounds.width - this.strokeWidth * 2, width: bounds.width - this.strokeWidth * 2,
height: bounds.height - this.strokeWidth * 2 height: bounds.height - this.strokeWidth * 2
}; };
returnValue.right = returnValue.left + returnValue.width; returnValue.right = returnValue.left + returnValue.width;
returnValue.bottom = returnValue.top + returnValue.height; returnValue.bottom = returnValue.top + returnValue.height;
returnValue.min = { returnValue.min = {
left: returnValue.left, left: returnValue.left,
top: returnValue.top top: returnValue.top
}; };
returnValue.max = { returnValue.max = {
left: returnValue.left + returnValue.width, left: returnValue.left + returnValue.width,
top: returnValue.top + returnValue.height top: returnValue.top + returnValue.height
}; };
return returnValue; return returnValue;
} }
}); });
} }
module.exports = ExtendFabricFunctionality; module.exports = ExtendFabricFunctionality;
+4 -4
View File
@@ -3,17 +3,17 @@
(function() { (function() {
/** /**
* Fabric functionality is extended with some custom functionality. This is done before * Fabric functionality is extended with some custom functionality. This is done before
* we do anything else. * we do anything else.
*/ */
require('./extend-fabric-functionality')(); require('./extend-fabric-functionality')();
/** /**
* ImageEditor is the starting point of all files. Here the image editor is created and * ImageEditor is the starting point of all files. Here the image editor is created and
* it receives attributes from the initialisation. As this is done from outside of this file, * it receives attributes from the initialisation. As this is done from outside of this file,
* the ImageEditor should be available on globally. * the ImageEditor should be available on globally.
*/ */
window.ImageEditor = require('./ImageEditor'); window.ImageEditor = require('./ImageEditor');
}()); }());
+11 -11
View File
@@ -2,15 +2,15 @@
module.exports = { module.exports = {
assertKeyValuePair: require('./utils/assert-key-value-pair'), assertKeyValuePair: require('./utils/assert-key-value-pair'),
assertBetween: require('./utils/assert-between'), assertBetween: require('./utils/assert-between'),
calcCrop: require('./utils/calc-crop'), calcCrop: require('./utils/calc-crop'),
setPositionInside: require('./utils/set-position-inside'), setPositionInside: require('./utils/set-position-inside'),
setProperties: require('./utils/set-properties'), setProperties: require('./utils/set-properties'),
toggleFullscreen: require('./utils/toggle-fullscreen'), toggleFullscreen: require('./utils/toggle-fullscreen'),
isMobile: require('./utils/is-mobile'), isMobile: require('./utils/is-mobile'),
MouseMetrics: require('./utils/mouse-metrics'), MouseMetrics: require('./utils/mouse-metrics'),
supportsFullscreen: require('./utils/supports-fullscreen'), supportsFullscreen: require('./utils/supports-fullscreen'),
isFullscreen: require('./utils/is-fullscreen'), isFullscreen: require('./utils/is-fullscreen'),
isAspectChanged: require('./utils/is-aspect-changed'), isAspectChanged: require('./utils/is-aspect-changed'),
}; };
+7 -7
View File
@@ -1,13 +1,13 @@
'use strict'; 'use strict';
function assertBetween(value, min, max) { function assertBetween(value, min, max) {
if (value < min) { if (value < min) {
return min; return min;
} }
if (value > max) { if (value > max) {
return max; return max;
} }
return value; return value;
} }
module.exports = assertBetween; module.exports = assertBetween;
+6 -6
View File
@@ -1,14 +1,14 @@
'use strict'; 'use strict';
function assertKeyValuePair(key, value) { function assertKeyValuePair(key, value) {
if (typeof key === 'object') { if (typeof key === 'object') {
return key; return key;
} }
var returnValue = {}; var returnValue = {};
returnValue[key] = value; returnValue[key] = value;
return returnValue; return returnValue;
} }
module.exports = assertKeyValuePair; module.exports = assertKeyValuePair;
+27 -27
View File
@@ -13,38 +13,38 @@
* ppmm: NUMBER * ppmm: NUMBER
*/ */
function calcCrop(obj, width, height, units) { function calcCrop(obj, width, height, units) {
var cropRatio = width / height; var cropRatio = width / height;
var objRatio = obj.width / obj.height; var objRatio = obj.width / obj.height;
var inchToCm = units === "inch" ? 2.54 : 1; var inchToCm = units === 'inch' ? 2.54 : 1;
var returnValue = { var returnValue = {
image: obj, image: obj,
axis: objRatio > cropRatio ? 'x' : 'y', axis: objRatio > cropRatio ? 'x' : 'y',
dim: { dim: {
width: Number(width), width: Number(width),
height: Number(height), height: Number(height),
units: units units: units
}, },
width: obj.width * obj.scaleX, width: obj.width * obj.scaleX,
height: obj.height * obj.scaleY, height: obj.height * obj.scaleY,
objectRatio: objRatio, objectRatio: objRatio,
cropRatio: cropRatio cropRatio: cropRatio
}; };
if (objRatio > cropRatio) { if (objRatio > cropRatio) {
returnValue.width *= cropRatio / objRatio; returnValue.width *= cropRatio / objRatio;
} else { } else {
returnValue.height /= cropRatio / objRatio; returnValue.height /= cropRatio / objRatio;
} }
// Pixels per millimeter // Pixels per millimeter
var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10); var ppmm = returnValue.width / ((returnValue.dim.width * inchToCm * obj.scaleX) * 10);
//Round to four decimal places to avoid precision issues. At least 4 decimals is needed though //Round to four decimal places to avoid precision issues. At least 4 decimals is needed though
//for correct calculation of number of gores on wide wallpaperes in editor. //for correct calculation of number of gores on wide wallpaperes in editor.
returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4; returnValue.ppmm = Math.round(ppmm * 1e4) / 1e4;
return returnValue; return returnValue;
} }
module.exports = calcCrop; module.exports = calcCrop;
+1 -1
View File
@@ -1,7 +1,7 @@
'use strict'; 'use strict';
function isAspectChanged(x1, y1, x2, y2) { function isAspectChanged(x1, y1, x2, y2) {
return (Math.abs(x1 / y1 - x2 / y2) > 0.005); return (Math.abs(x1 / y1 - x2 / y2) > 0.005);
} }
module.exports = isAspectChanged; module.exports = isAspectChanged;
+1 -1
View File
@@ -1,7 +1,7 @@
'use strict'; 'use strict';
function isFullscreen() { function isFullscreen() {
return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
} }
module.exports = isFullscreen; module.exports = isFullscreen;
+1 -1
View File
@@ -2,7 +2,7 @@
/* globals $, window */ /* globals $, window */
function isMobile() { function isMobile() {
return $(window).width() < 768; return $(window).width() < 768;
} }
module.exports = isMobile; module.exports = isMobile;
+16 -16
View File
@@ -1,24 +1,24 @@
'use strict'; 'use strict';
var MouseMetrics = { var MouseMetrics = {
previousMouseData: { previousMouseData: {
x: null, x: null,
y: null y: null
}, },
deletePreviousMouseData: function() { deletePreviousMouseData: function() {
MouseMetrics.previousMouseData = { MouseMetrics.previousMouseData = {
x: null, x: null,
y: null y: null
}; };
}, },
setPreviousMouseData: function(values) { setPreviousMouseData: function(values) {
MouseMetrics.previousMouseData = { MouseMetrics.previousMouseData = {
x: values.x || null, x: values.x || null,
y: values.y || null, y: values.y || null,
}; };
}, },
}; };
module.exports = MouseMetrics; module.exports = MouseMetrics;
+9 -9
View File
@@ -6,16 +6,16 @@
* @return {fabric.Object} * @return {fabric.Object}
*/ */
function setPositionInside(obj, bounds) { function setPositionInside(obj, bounds) {
['left', 'top'].forEach(function (v) { ['left', 'top'].forEach(function (v) {
if (obj[v] < bounds[v].min) { if (obj[v] < bounds[v].min) {
obj.set(v, bounds[v].min).setCoords(); obj.set(v, bounds[v].min).setCoords();
} }
if (obj[v] > bounds[v].max) { if (obj[v] > bounds[v].max) {
obj.set(v, bounds[v].max).setCoords(); obj.set(v, bounds[v].max).setCoords();
} }
}); });
return obj; return obj;
} }
module.exports = setPositionInside; module.exports = setPositionInside;
+4 -4
View File
@@ -5,11 +5,11 @@
* @param {Object} properties * @param {Object} properties
*/ */
function setProperties(obj, properties) { function setProperties(obj, properties) {
for (var o in properties) { for (var o in properties) {
if (properties.hasOwnProperty(o)) { if (properties.hasOwnProperty(o)) {
Object.defineProperty(obj, o, properties[o]); Object.defineProperty(obj, o, properties[o]);
}
} }
}
} }
module.exports = setProperties; module.exports = setProperties;
+1 -1
View File
@@ -2,7 +2,7 @@
function supportsFullscreen() { function supportsFullscreen() {
return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen; return document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen || document.documentElement.msRequestFullscreen;
} }
+20 -20
View File
@@ -6,28 +6,28 @@ var isFullscreen = require('./is-fullscreen');
* @param {HTMLElement} elem * @param {HTMLElement} elem
*/ */
function toggleFullscreen(elem) { function toggleFullscreen(elem) {
if (isFullscreen()) { if (isFullscreen()) {
if (document.exitFullscreen) { if (document.exitFullscreen) {
document.exitFullscreen(); document.exitFullscreen();
} else if (document.msExitFullscreen) { } else if (document.msExitFullscreen) {
document.msExitFullscreen(); document.msExitFullscreen();
} else if (document.mozCancelFullScreen) { } else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen(); document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) { } else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen(); document.webkitCancelFullScreen();
}
return;
} }
return;
}
if (elem.requestFullscreen) { if (elem.requestFullscreen) {
elem.requestFullscreen(); elem.requestFullscreen();
} else if (elem.webkitRequestFullScreen) { } else if (elem.webkitRequestFullScreen) {
elem.webkitRequestFullScreen(); elem.webkitRequestFullScreen();
} else if (elem.mozRequestFullScreen) { } else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen(); elem.mozRequestFullScreen();
} else if (elem.msRequestFullscreen) { } else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen(); elem.msRequestFullscreen();
} }
} }
module.exports = toggleFullscreen; module.exports = toggleFullscreen;
+6
View File
@@ -0,0 +1,6 @@
{
"globals": {
"QUnit": false,
"ImageEditor": false
}
}
+20 -20
View File
@@ -1,28 +1,28 @@
(function() { (function() {
QUnit.module('ImageEditor'); QUnit.module('ImageEditor');
QUnit.test('load image', function(assert) { QUnit.test('load image', function(assert) {
var done = assert.async(); var done = assert.async();
var editor = new ImageEditor('canvas'); var editor = new ImageEditor('canvas');
editor.loadImage('fixtures/dog.jpg', function() { editor.loadImage('fixtures/dog.jpg', function() {
assert.ok(editor.canvas.getImage(), 'image loaded'); assert.ok(editor.canvas.getImage(), 'image loaded');
done(); done();
});
}); });
});
QUnit.test('crop image', function(assert) { QUnit.test('crop image', function(assert) {
var done = assert.async(); var done = assert.async();
var editor = new ImageEditor('canvas'); var editor = new ImageEditor('canvas');
editor.loadImage('fixtures/dog.jpg', function() { editor.loadImage('fixtures/dog.jpg', function() {
editor.crop(400, 200, 'cm'); editor.crop(400, 200, 'cm');
var data = editor.canvas.getImageData().getData(); var data = editor.canvas.getImageData().getData();
assert.strictEqual(data.width, 400, 'sets image width'); assert.strictEqual(data.width, 400, 'sets image width');
assert.strictEqual(data.height, 200, 'sets image height'); assert.strictEqual(data.height, 200, 'sets image height');
assert.strictEqual(data.x, 0, 'sets crop x'); assert.strictEqual(data.x, 0, 'sets crop x');
assert.strictEqual(data.y.toFixed(7), (0.12482117310443483).toFixed(7), 'sets crop y'); assert.strictEqual(data.y.toFixed(7), (0.12482117310443483).toFixed(7), 'sets crop y');
done(); done();
});
}); });
});
})(); })();