Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented resize functionality fix #100, #342 #575

Merged
merged 26 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1b26950
adding resize functionality
Mar 26, 2021
ce95f02
add resize icon
Mar 30, 2021
fcaaf47
UI minor style improvements
Mar 30, 2021
9b3d9c2
Image resizing functionality implemented
Apr 8, 2021
e2273ef
Merge branch 'master' of https://github.com/nhn/tui.image-editor into…
Apr 9, 2021
32f9eb8
Merge branch 'nhn-master'
Apr 9, 2021
f3509e1
fix sometimes image cropped on resizing bug.
Apr 9, 2021
faf595a
fix image resizing undo and redo functions problems
Apr 9, 2021
6b5aadd
Beautified resize label in history list
Apr 9, 2021
bd853c2
Added image resizing icon on history
Apr 9, 2021
e6d7f48
changes documentation commentline resize component and command files.…
Apr 14, 2021
9c0c35d
Created resize API for graphics.
Apr 14, 2021
851a861
simplifying resize methods
Apr 14, 2021
e1976c0
simplifying resize methods
Apr 14, 2021
e99e747
deleted unnecessary comments
Apr 14, 2021
2c98e63
simplified selectionCleared method
Apr 14, 2021
b0111ec
fix test: 'switches drawing modes'
Apr 14, 2021
76b6722
fix dimension update after scaling bug
Apr 15, 2021
dbae066
lockState is turned on recalculated max width and heigth values
Apr 15, 2021
dc5a614
remove unnecessary lockState property and set method
Apr 15, 2021
e499d83
added resize component test case
Apr 15, 2021
5891daa
Resize command tests added.
Apr 15, 2021
ab7cd8c
import Promise from tui image editor utils for old browser support
Apr 22, 2021
2865f1a
Simplified ui limit set functions.
Apr 22, 2021
21c5045
Simple language change on resize tests: should setted original -> sho…
Apr 22, 2021
c00777d
Resize added to Features title on README.md
Apr 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/image-editor/src/css/buttons.styl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@
.{prefix}-button.apply.active svg > use.active
display: block;

/* RESIZE BUTTON */
.tie-resize-button,
.tie-resize-preset-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;


/* SHAPE BUTTON */
.tie-shape-button
Expand Down
3 changes: 2 additions & 1 deletion apps/image-editor/src/css/gridtable.styl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
.tui-image-editor
transition: none;
.{prefix}-main.{prefix}-menu-flip .{prefix}-grid-visual,
.{prefix}-main.{prefix}-menu-rotate .{prefix}-grid-visual
.{prefix}-main.{prefix}-menu-rotate .{prefix}-grid-visual,
.{prefix}-main.{prefix}-menu-resize .{prefix}-grid-visual
display: block;
.{prefix}-grid-visual
table
Expand Down
2 changes: 1 addition & 1 deletion apps/image-editor/src/css/range.styl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
font-weight: lighter;
vertical-align: baseline;
font-family: 'Noto Sans', sans-serif;
margin-top: 21px;
margin-top: 15px;
margin-left: 4px;
.{prefix}-controls
position: absolute;
Expand Down
2 changes: 2 additions & 0 deletions apps/image-editor/src/css/submenu.styl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
label > span
width: 70px;
.{prefix}-main.{prefix}-menu-crop .{prefix}-submenu > div.{prefix}-menu-crop,
.{prefix}-main.{prefix}-menu-resize .{prefix}-submenu > div.{prefix}-menu-resize,
.{prefix}-main.{prefix}-menu-flip .{prefix}-submenu > div.{prefix}-menu-flip,
.{prefix}-main.{prefix}-menu-rotate .{prefix}-submenu > div.{prefix}-menu-rotate,
.{prefix}-main.{prefix}-menu-shape .{prefix}-submenu > div.{prefix}-menu-shape,
Expand All @@ -78,6 +79,7 @@
.{prefix}-main.{prefix}-menu-zoom .{prefix}-submenu > div.{prefix}-menu-zoom
display: table-cell;
.{prefix}-main.{prefix}-menu-crop,
.{prefix}-main.{prefix}-menu-resize,
.{prefix}-main.{prefix}-menu-flip,
.{prefix}-main.{prefix}-menu-rotate,
.{prefix}-main.{prefix}-menu-shape,
Expand Down
1 change: 1 addition & 0 deletions apps/image-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ import '@/command/rotate';
import '@/command/setObjectProperties';
import '@/command/setObjectPosition';
import '@/command/changeSelection';
import '@/command/resize';

module.exports = ImageEditor;
99 changes: 96 additions & 3 deletions apps/image-editor/src/js/action.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { extend } from 'tui-code-snippet';
import Imagetracer from '@/helper/imagetracer';
import { isSupportFileApi, base64ToBlob, toInteger, isEmptyCropzone } from '@/util';
import { eventNames, historyNames, drawingModes, drawingMenuNames, zoomModes } from '@/consts';
import {
eventNames,
historyNames,
drawingModes,
drawingMenuNames,
zoomModes,
componentNames,
} from '@/consts';

export default {
/**
Expand All @@ -14,6 +21,7 @@ export default {
main: this._mainAction(),
shape: this._shapeAction(),
crop: this._cropAction(),
resize: this._resizeAction(),
flip: this._flipAction(),
rotate: this._rotateAction(),
text: this._textAction(),
Expand Down Expand Up @@ -405,6 +413,88 @@ export default {
);
},

/**
* Resize Action
* @returns {Object} actions for ui resize
* @private
*/
_resizeAction() {
return extend(
{
getCurrentDimensions: () => {
return this._graphics.getComponent(componentNames.RESIZE).getCurrentDimensions();
seytar marked this conversation as resolved.
Show resolved Hide resolved
},
preview: (actor, value, lockState) => {
const resizeComponent = this._graphics.getComponent(componentNames.RESIZE);

const currentDimensions = resizeComponent.getCurrentDimensions();
const calcAspectRatio = () => currentDimensions.width / currentDimensions.height;

let dimensions = {};
switch(actor) {
case 'width':
dimensions.width = value;
if (lockState) {
dimensions.height = value / calcAspectRatio();
} else {
dimensions.height = currentDimensions.height;
}
break;
case 'height':
dimensions.height = value;
if (lockState) {
dimensions.width = value * calcAspectRatio();
} else {
dimensions.width = currentDimensions.width;
}
seytar marked this conversation as resolved.
Show resolved Hide resolved
break;
default:
seytar marked this conversation as resolved.
Show resolved Hide resolved
}

resizeComponent.resize(dimensions).then(() => {
this.ui.resizeEditor();
});

if (lockState) {
this.ui.resize.setWidthValue(dimensions.width);
this.ui.resize.setHeightValue(dimensions.height);
}
},
resize: (dimensions = null) => {
const resizeComponent = this._graphics.getComponent(componentNames.RESIZE);
if (!dimensions) {
dimensions = resizeComponent.getCurrentDimensions();
}

this.resize(dimensions)
.then(() => {
resizeComponent.setOriginalDimensions(dimensions);
this.stopDrawingMode();
this.ui.resizeEditor();
this.ui.changeMenu('resize');
})
['catch']((message) => Promise.reject(message));
},
reset: (standByMode = false) => {
const resizeComponent = this._graphics.getComponent(componentNames.RESIZE);
const dimensions = resizeComponent.getOriginalDimensions();

this.ui.resize.setWidthValue(dimensions.width, true);
this.ui.resize.setHeightValue(dimensions.height, true);

resizeComponent.resize(dimensions).then(() => {
if (!standByMode) {
this.stopDrawingMode();
this.ui.resizeEditor();
this.ui.changeMenu('resize');
}
});
},
},
this._commonAction()
);
},

/**
* Flip Action
* @returns {Object} actions for ui flip
Expand Down Expand Up @@ -541,7 +631,7 @@ export default {
this.activeObjectId = null;
if (this.ui.submenu === 'text') {
this.changeCursor('text');
} else if (this.ui.submenu !== 'draw' && this.ui.submenu !== 'crop') {
} else if (this.ui.submenu !== 'draw' && this.ui.submenu !== 'crop' && this.ui.submenu !== 'resize') {
seytar marked this conversation as resolved.
Show resolved Hide resolved
this.stopDrawingMode();
}
},
Expand All @@ -566,7 +656,7 @@ export default {
* @private
*/
_commonAction() {
const { TEXT, CROPPER, SHAPE, ZOOM } = drawingModes;
const { TEXT, CROPPER, SHAPE, ZOOM, RESIZE } = drawingModes;

return {
modeChange: (menu) => {
Expand All @@ -584,6 +674,9 @@ export default {
case drawingMenuNames.ZOOM:
this.startDrawingMode(ZOOM);
break;
case drawingMenuNames.RESIZE:
this.startDrawingMode(RESIZE);
break;
default:
break;
}
Expand Down
42 changes: 42 additions & 0 deletions apps/image-editor/src/js/command/resize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @author NHN. FE Development Team <dl_javascript@nhn.com>
* @fileoverview Resize an image
*/
import commandFactory from '@/factory/command';
import { componentNames, commandNames } from '@/consts';

const { RESIZE } = componentNames;

const command = {
name: commandNames.RESIZE_IMAGE,

/**
* Resize an image
* @param {Graphics} graphics - Graphics instance
* @param {object} dimensions - Image Dimensions
* @returns {Promise}
*/
execute(graphics, dimensions) {
const resizeComp = graphics.getComponent(RESIZE);

if (!this.isRedo) {
this.undoData.dimensions = resizeComp.getOriginalDimensions();
}

return resizeComp.resize(dimensions);
},

/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo(graphics) {
const resizeComp = graphics.getComponent(RESIZE);

return resizeComp.resize(this.undoData.dimensions);
},
};

commandFactory.register(command);

export default command;
118 changes: 118 additions & 0 deletions apps/image-editor/src/js/component/resize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import Component from '@/interface/component';
import { componentNames } from '@/consts';

/**
* Resize components
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @class Resize
* @ignore
*/
class Resize extends Component {
constructor(graphics) {
super(componentNames.RESIZE, graphics);

/**
* Current dimensions
* @type {Object}
* @private
*/
this._dimensions = null;

/**
* Original dimensions
* @type {Object}
* @private
*/
this._originalDimensions = null;

/**
* Lock aspect ratio state
* @type {boolean}
* @private
*/
this._lockState = false;
}

/**
* Get current dimensions
* @returns {object}
*/
getCurrentDimensions() {
if (!this._dimensions) {
const canvasImage = this.getCanvasImage();
this._dimensions = {
width: canvasImage.width,
height: canvasImage.height,
seytar marked this conversation as resolved.
Show resolved Hide resolved
};
}

return this._dimensions;
}

/**
* Get original dimensions
* @returns {object}
*/
getOriginalDimensions() {
return this._originalDimensions;
}

/**
* Set original dimensions
* @param {object} dimensions - Dimensions
*/
setOriginalDimensions(dimensions) {
this._originalDimensions = dimensions;
}

/**
* Set states of lock aspect ratio
* @param {boolean} lockState - Lock aspect ratio state
*/
setLockState(lockState) {
this._lockState = lockState;
}

/**
* Resize Image
* @param {Object} dimensions - Resize dimensions
* @returns {Promise}
* @private
*/
resize(dimensions) {
const canvasImage = this.getCanvasImage();
const scaleValues = {
scaleX: dimensions.width ? dimensions.width / canvasImage.width : canvasImage.scaleX,
scaleY: dimensions.height ? dimensions.height / canvasImage.height : canvasImage.scaleY,
};

if (canvasImage.scaleX !== scaleValues.scaleX || canvasImage.scaleY !== scaleValues.scaleY) {
canvasImage.set(scaleValues).setCoords();

this._dimensions = {
width: canvasImage.width * canvasImage.scaleX,
height: canvasImage.height * canvasImage.scaleY,
};
seytar marked this conversation as resolved.
Show resolved Hide resolved
}

this.adjustCanvasDimensionBase();

return Promise.resolve();
}

/**
* Start resizing
*/
start() {
const dimensions = this.getCurrentDimensions();
this.setOriginalDimensions(dimensions);
}

/**
* End resizing
*/
end() {}
}

export default Resize;
Loading