Skip to content

Commit

Permalink
fix(controls): keep last sign when over origin (#8490)
Browse files Browse the repository at this point in the history
Co-authored-by: ShaMan123 <shacharnen@gmail.com>
  • Loading branch information
luizzappa and ShaMan123 authored Dec 5, 2022
1 parent 4107721 commit c0b7c1c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [next]

- fix(scaleObject): handle when scale is 0 to not bug flip [#8490](https://github.com/fabricjs/fabric.js/pull/8490)
- chore(TS): migrate StatiCanvas to TS [#8485](https://github.com/fabricjs/fabric.js/pull/8485)
- chore(): refactor `Object.__uid++` => `uid()` [#8482](https://github.com/fabricjs/fabric.js/pull/8482)
- chore(TS): migrate object mixins to TS [#8414](https://github.com/fabricjs/fabric.js/pull/8414)
Expand Down
4 changes: 2 additions & 2 deletions src/controls/scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ function scaleObject(
// by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily
// cross many time the origin point and flip the object. so we need a way to filter out the noise.
// This ternary here should be ok to filter out X scaling when we want Y only and vice versa.
signX = by !== 'y' ? Math.sign(newPoint.x) : 1;
signY = by !== 'x' ? Math.sign(newPoint.y) : 1;
signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1;
signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1;
if (!transform.signX) {
transform.signX = signX;
}
Expand Down
58 changes: 57 additions & 1 deletion test/unit/controls_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
eventData = {};
transform = prepareTransform(target, 'mr');
});
hooks.afterEach(function() {
hooks.afterEach(function () {
canvas.off();
canvas.clear();
});
function prepareTransform(target, corner) {
Expand Down Expand Up @@ -262,5 +263,60 @@
);
wrapped(eventData, transform, x, y);
});
['ml', 'mt', 'mr', 'mb'].forEach(controlKey => {
const axis = {
ml: 'x',
mt: 'y',
mr: 'x',
mb: 'y',
}[controlKey]
const AXIS = axis.toUpperCase();
const signKey = `sign${AXIS}`;
const scaleKey = `scale${AXIS}`;
const flipKey = `flip${AXIS}`;
const isX = axis === 'x';
QUnit.test(`scaling ${AXIS} from ${controlKey} keeps the same sign when scale = 0`, function (assert) {
transform = prepareTransform(transform.target, controlKey);
const size = transform.target._getTransformedDimensions()[axis];
const factor = 0.5;
const fn = fabric.controlsUtils[`scaling${AXIS}`];
const exec = point => {
const { target } = transform;
const origin = target.translateToGivenOrigin(
target.getRelativeCenterPoint(),
'center',
'center',
transform.originX,
transform.originY
);
const pointer = point.add(origin);
fn(eventData, transform, pointer.x, pointer.y);
};
const deltaFromControl = new fabric.Point(
Number(isX),
Number(!isX)
).scalarMultiply(size * factor);
exec(new fabric.Point());
assert.equal(transform[signKey], 1, `${signKey} value after scaling`);
assert.equal(transform.target[flipKey], false, `${flipKey} value after scaling`);
assert.ok(transform.target[scaleKey] <= 0.001, `${scaleKey} value after scaling back to origin`);
exec(deltaFromControl);
assert.equal(transform[signKey], 1, `${signKey} value after scaling`);
assert.equal(transform.target[flipKey], false, `${flipKey} value after scaling`);
assert.equal(transform.target[scaleKey], factor, `${scaleKey} value after scaling`);
exec(new fabric.Point());
assert.equal(transform[signKey], 1, `${signKey} value after scaling`);
assert.equal(transform.target[flipKey], false, `${flipKey} value after scaling`);
assert.ok(transform.target[scaleKey] <= 0.001, `${scaleKey} value after scaling back to origin`);
exec(deltaFromControl.scalarMultiply(-1));
assert.equal(transform[signKey], -1, `${signKey} value after scaling`);
assert.equal(transform.target[flipKey], true, `${flipKey} value after scaling`);
assert.equal(transform.target[scaleKey], factor, `${scaleKey} value after scaling`);
exec(new fabric.Point());
assert.equal(transform[signKey], -1, `${signKey} value after scaling`);
assert.equal(transform.target[flipKey], true, `${flipKey} value after scaling`);
assert.ok(transform.target[scaleKey] <= 0.001, `${scaleKey} value after scaling back to origin`);
});
});
});
})();

0 comments on commit c0b7c1c

Please sign in to comment.