From 24f38f381ae3bbd787a70c3c29901a083e3f3113 Mon Sep 17 00:00:00 2001 From: Joel Bair Date: Wed, 22 Aug 2018 11:51:55 -0600 Subject: [PATCH 1/3] crop presets --- src/css/buttons.styl | 10 ++-- src/js/action.js | 22 ++++++++ src/js/component/cropper.js | 51 ++++++++++++++++++ src/js/graphics.js | 9 ++++ src/js/imageEditor.js | 9 ++++ src/js/ui/crop.js | 58 ++++++++++++++++++++- src/js/ui/template/submenu/crop.js | 83 +++++++++++++++++++++++++++++- 7 files changed, 236 insertions(+), 6 deletions(-) diff --git a/src/css/buttons.styl b/src/css/buttons.styl index a4cb0d904..9831f4763 100644 --- a/src/css/buttons.styl +++ b/src/css/buttons.styl @@ -30,18 +30,20 @@ display: none; svg > use.active display: block; - + /* MASK BUTTON */ #tie-mask-apply.apply.active .{prefix}-button.apply label color: #fff; svg > use.active display: block; - + /* CROP BUTTON */ #tie-crop-button .{prefix}-button.apply margin-right: 24px; + .{prefix}-button.preset.active svg > use.active + display: block; .{prefix}-button.apply.active svg > use.active display: block; @@ -50,7 +52,7 @@ #tie-shape-button &.rect .{prefix}-button.rect, &.circle .{prefix}-button.circle, - &.triangle .{prefix}-button.triangle + &.triangle .{prefix}-button.triangle svg > use.normal display: none; svg > use.active @@ -74,4 +76,4 @@ border: 1px solid green; cursor: inherit; left: 0; - top: 0; \ No newline at end of file + top: 0; diff --git a/src/js/action.js b/src/js/action.js index ae6a20f50..00a65820a 100644 --- a/src/js/action.js +++ b/src/js/action.js @@ -319,6 +319,28 @@ export default { cancel: () => { this.stopDrawingMode(); this.ui.changeMenu('crop'); + }, + 'preset-none': () => { + this.setCropzoneRect(); + this.ui.crop.changeApplyButtonStatus(false); + }, + 'preset-square': () => { + this.setCropzoneRect(1 / 1); + }, + 'preset-3-2': () => { + this.setCropzoneRect(3 / 2); + }, + 'preset-4-3': () => { + this.setCropzoneRect(4 / 3); + }, + 'preset-5-4': () => { + this.setCropzoneRect(5 / 4); + }, + 'preset-7-5': () => { + this.setCropzoneRect(7 / 5); + }, + 'preset-16-9': () => { + this.setCropzoneRect(16 / 9); } }, this._commonAction()); }, diff --git a/src/js/component/cropper.js b/src/js/component/cropper.js index e2333e04a..f19d3c022 100644 --- a/src/js/component/cropper.js +++ b/src/js/component/cropper.js @@ -277,6 +277,57 @@ class Cropper extends Component { }; } + /* + * Set a cropzone square + */ + setCropzoneRect(factor) { + const canvas = this.getCanvas(); + canvas.deactivateAll(); + canvas.selection = false; + + const cropzone = this._cropzone; + cropzone.remove(); + + if (!factor) { + return; + } + + const canvasImage = this.getCanvasImage(); + const oWidth = canvasImage.getOriginalSize().width; + const oHeight = canvasImage.getOriginalSize().height; + + let width = (10000 * factor); + let height = 10000; + let scale = 1; + + if (width > oWidth) { + scale = (oWidth / width); + width = (width * scale); + height = (height * scale); + } + + if (height > oHeight) { + scale = (oHeight / height); + width = (width * scale); + height = (height * scale); + } + + const top = 0; + const left = 0; + + cropzone.set({ + top, + left, + height, + width + }); + + canvas.add(cropzone); + canvas.centerObject(cropzone); + canvas.setActiveObject(cropzone); + canvas.selection = true; + } + /** * Keydown event handler * @param {KeyboardEvent} e - Event object diff --git a/src/js/graphics.js b/src/js/graphics.js index af32f71ae..6ac8189fa 100644 --- a/src/js/graphics.js +++ b/src/js/graphics.js @@ -545,6 +545,15 @@ class Graphics { return this.getComponent(components.CROPPER).getCropzoneRect(); } + /** + * Get cropped rect + * @param {Object} mode cropzone rect mode + * @returns {Object} rect + */ + setCropzoneRect(mode) { + return this.getComponent(components.CROPPER).setCropzoneRect(mode); + } + /** * Get cropped image data * @param {Object} cropRect cropzone rect diff --git a/src/js/imageEditor.js b/src/js/imageEditor.js index dfa3004db..4e115aa68 100644 --- a/src/js/imageEditor.js +++ b/src/js/imageEditor.js @@ -655,6 +655,15 @@ class ImageEditor { return this._graphics.getCropzoneRect(); } + /** + * Set the cropping rect + * @param {Object} mode crop rect mode [1, 1.5, 1.3333333333333333, 1.25, 1.7777777777777777] + * @returns {Object} {{left: number, top: number, width: number, height: number}} rect + */ + setCropzoneRect(mode) { + return this._graphics.setCropzoneRect(mode); + } + /** * Flip * @returns {Promise} diff --git a/src/js/ui/crop.js b/src/js/ui/crop.js index d8a47848a..5879697e9 100644 --- a/src/js/ui/crop.js +++ b/src/js/ui/crop.js @@ -18,7 +18,14 @@ class Crop extends Submenu { this.status = 'active'; this._els = { apply: this.selector('#tie-crop-button .apply'), - cancel: this.selector('#tie-crop-button .cancel') + cancel: this.selector('#tie-crop-button .cancel'), + 'preset-none': this.selector('#tie-crop-button .preset-none'), + 'preset-square': this.selector('#tie-crop-button .preset-square'), + 'preset-3-2': this.selector('#tie-crop-button .preset-3-2'), + 'preset-4-3': this.selector('#tie-crop-button .preset-4-3'), + 'preset-5-4': this.selector('#tie-crop-button .preset-5-4'), + 'preset-7-5': this.selector('#tie-crop-button .preset-7-5'), + 'preset-16-9': this.selector('#tie-crop-button .preset-16-9') }; } @@ -39,6 +46,41 @@ class Crop extends Submenu { this.actions.cancel(); this._els.apply.classList.remove('active'); }); + + this._els['preset-none'].addEventListener('click', () => { + this.setPresetButtonActive('preset-none'); + this.actions['preset-none'](); + }); + + this._els['preset-square'].addEventListener('click', () => { + this.setPresetButtonActive('preset-square'); + this.actions['preset-square'](); + }); + + this._els['preset-3-2'].addEventListener('click', () => { + this.setPresetButtonActive('preset-3-2'); + this.actions['preset-3-2'](); + }); + + this._els['preset-4-3'].addEventListener('click', () => { + this.setPresetButtonActive('preset-4-3'); + this.actions['preset-4-3'](); + }); + + this._els['preset-5-4'].addEventListener('click', () => { + this.setPresetButtonActive('preset-5-4'); + this.actions['preset-5-4'](); + }); + + this._els['preset-7-5'].addEventListener('click', () => { + this.setPresetButtonActive('preset-7-5'); + this.actions['preset-7-5'](); + }); + + this._els['preset-16-9'].addEventListener('click', () => { + this.setPresetButtonActive('preset-16-9'); + this.actions['preset-16-9'](); + }); } /** @@ -66,6 +108,20 @@ class Crop extends Submenu { this._els.apply.classList.remove('active'); } } + + /** + * Set preset button to active status + * @param {String} preset - preset name + */ + setPresetButtonActive(preset) { + const excludeList = [preset, 'apply', 'cancel']; + Object.keys(this._els).forEach(key => { + if (!excludeList.includes(key)) { + this._els[key].classList.remove('active'); + } + }); + this._els[preset].classList.add('active'); + } } export default Crop; diff --git a/src/js/ui/template/submenu/crop.js b/src/js/ui/template/submenu/crop.js index 109169846..ac1bdad20 100644 --- a/src/js/ui/template/submenu/crop.js +++ b/src/js/ui/template/submenu/crop.js @@ -1,6 +1,87 @@ export default ({iconStyle: {normal, active}}) => (`