Skip to content

Commit

Permalink
fix: respect presetRatio on new cropzone (nhn#700)
Browse files Browse the repository at this point in the history
  • Loading branch information
omergy authored Mar 30, 2022
1 parent c9e1219 commit 418e5fe
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
36 changes: 33 additions & 3 deletions apps/image-editor/src/js/component/cropper.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class Cropper extends Component {

if (Math.abs(x - this._startX) + Math.abs(y - this._startY) > MOUSE_MOVE_THRESHOLD) {
canvas.remove(cropzone);
cropzone.set(this._calcRectDimensionFromPoint(x, y));
cropzone.set(this._calcRectDimensionFromPoint(x, y, cropzone.presetRatio));

canvas.add(cropzone);
canvas.setActiveObject(cropzone);
Expand All @@ -191,10 +191,11 @@ class Cropper extends Component {
* Get rect dimension setting from Canvas-Mouse-Position(x, y)
* @param {number} x - Canvas-Mouse-Position x
* @param {number} y - Canvas-Mouse-Position Y
* @param {number|null} presetRatio - fixed aspect ratio (width/height) of the cropzone (null if not set)
* @returns {{left: number, top: number, width: number, height: number}}
* @private
*/
_calcRectDimensionFromPoint(x, y) {
_calcRectDimensionFromPoint(x, y, presetRatio = null) {
const canvas = this.getCanvas();
const canvasWidth = canvas.getWidth();
const canvasHeight = canvas.getHeight();
Expand All @@ -205,7 +206,7 @@ class Cropper extends Component {
let width = clamp(x, startX, canvasWidth) - left; // (startX <= x(mouse) <= canvasWidth) - left
let height = clamp(y, startY, canvasHeight) - top; // (startY <= y(mouse) <= canvasHeight) - top

if (this._withShiftKey) {
if (this._withShiftKey && !presetRatio) {
// make fixed ratio cropzone
if (width > height) {
height = width;
Expand All @@ -220,6 +221,35 @@ class Cropper extends Component {
if (startY >= y) {
top = startY - height;
}
} else if (presetRatio) {
// Restrict cropzone to given presetRatio
height = width / presetRatio;

// If moving in a direction where the top left corner moves (ie. top-left, bottom-left, top-right)
// the left and/or top values has to be changed based on the new height/width
if (startX >= x) {
left = clamp(startX - width, 0, canvasWidth);
}

if (startY >= y) {
top = clamp(startY - height, 0, canvasHeight);
}

// Check if the new height is too large
if (top + height > canvasHeight) {
height = canvasHeight - top; // Set height to max available height
width = height * presetRatio; // Restrict cropzone to given presetRatio based on the new height

// If moving in a direction where the top left corner moves (ie. top-left, bottom-left, top-right)
// the left and/or top values has to be changed based on the new height/width
if (startX >= x) {
left = clamp(startX - width, 0, canvasWidth);
}

if (startY >= y) {
top = clamp(startY - height, 0, canvasHeight);
}
}
}

return {
Expand Down
34 changes: 34 additions & 0 deletions apps/image-editor/tests/cropper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,40 @@ describe('Cropper', () => {
height: 20,
});
});

it('should restrict cropzone dimensions to presetRatio', () => {
const dimension = cropper._calcRectDimensionFromPoint(50, 100, 16 / 9);

expect(dimension).toEqual({
left: 10,
top: 20,
width: 40,
height: 22.5, // width / presetRatio -> 60 / 1,777777778
});
});

it('should restrict cropzone within canvas and keep presetRatio when width too large', () => {
const dimension = cropper._calcRectDimensionFromPoint(110, 100, 16 / 9);

expect(dimension).toEqual({
left: 10,
top: 20,
width: 90, // maxwidth (100) minus start (10)
height: 50.625, // width / presetRatio -> 90 / (16/9)
});
});

it('should restrict cropzone within canvas and keep presetRatio when height too large', () => {
cropper._startY = 177.5;
const dimension = cropper._calcRectDimensionFromPoint(100, 250, 16 / 9);

expect(dimension).toEqual({
left: 10,
top: 177.5,
width: 40, // height * presetRatio -> 22.5 * (16/9)
height: 22.5, // maxwidth (200) minus start (177.5)
});
});
});

it('should activate cropzone', () => {
Expand Down

0 comments on commit 418e5fe

Please sign in to comment.