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

fix(polyline): stroke bounding rect calculation typescript #8344

Merged
merged 96 commits into from
Oct 15, 2022
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
03c5360
feat(getOrthogonalUnitVector)
Oct 2, 2022
75722d1
fix(calcAngleBetweenVectors): use atan2 instead of dot product
Oct 2, 2022
b4b866e
fix(getBisector): since calcAngleBetweenVectors use atan2, we don't h…
Oct 2, 2022
efaf936
feat(): add hypot in misc.ts
Oct 2, 2022
4aac2d4
fix(getHatVector): change Math#hypot for misc#hypot
Oct 2, 2022
0c86b4a
style(getHatVector)
Oct 2, 2022
975dd1d
test(): add hypot test
Oct 2, 2022
430619f
test(): removed only
Oct 2, 2022
4327d7f
refactor(polyline#_calcDimensions): remove exactBoundingBox logic and…
Oct 2, 2022
7db09ce
fix(polyline#_setPositionDimensions): correctly calculate width, heig…
Oct 2, 2022
e5b2f1c
fix(): extend _getTransformedDimensions in polyline
Oct 2, 2022
73b8830
fix(): extend _set in polyline
Oct 2, 2022
a72a48f
fix(projectStrokeOnPoints)
Oct 2, 2022
4ce9c12
feat(hypot): hard coded hypot calculatoin to deal with precision betw…
Oct 3, 2022
935f406
fix(_getTransformedDimensions)
Oct 3, 2022
397126d
fix(projectStrokeOnPoints)
Oct 3, 2022
0a3d662
refactor(projectStrokeOnPoints): create function to each line join type
Oct 5, 2022
d1af8ce
fix(polyline): import instead of using namespace
Oct 5, 2022
8a54b08
refactor(polyline): pathOffset as a Point
Oct 5, 2022
7bdf5ba
refactor(polyline): replace vars
Oct 5, 2022
1193892
refactor(polyline#_set): add the conditions to the if statement
Oct 5, 2022
4bd47a8
style(projectStrokeOnPoints): JSDocs, missing semi colons
Oct 5, 2022
0d5b5f3
refactor(projectStrokeOnPoints): instance of Point with a single argu…
Oct 5, 2022
3eec3d1
feat(point#magnitude): add vector lenght in Point class
Oct 5, 2022
3bef574
refactor(projectStrokeOnPoints): call magnitude from Point class
Oct 5, 2022
fc42532
refactor(projectStrokeOnPoints): calcAngleBetweenVectors instead of M…
Oct 6, 2022
2b98c74
refactor(projectStrokeOnPoints): hat vector as const
Oct 7, 2022
735fe66
refactor(projectStrokeOnPoints): updated links to docs
Oct 8, 2022
2e61973
refactor(projectStrokeOnPoints): calculation of strokeMiterLimit with…
Oct 8, 2022
d2a199a
docs(projectStrokeOnPoints)
Oct 8, 2022
9dd7850
fix(projectStrokeOnPoints): remove applySkew from projectionsRoundNoSkew
Oct 9, 2022
1788eb6
fix(): optional tag to include number type
ShaMan123 Oct 10, 2022
81a1cf5
restore test/unit/polygon.js
Oct 10, 2022
997c415
refactor(projectStrokeOnPoints): create isAcute function to abstract …
Oct 11, 2022
f2c46a8
style(projectStrokeOnPoints): remove jsdocs types
Oct 11, 2022
f3d539a
style(hypot): typo
Oct 11, 2022
034a90a
refactor(projectStrokeOnPoints): projections as standalone functions
Oct 11, 2022
1636dd9
style(): prettier
Oct 11, 2022
37db1d6
refactor(): `_setPositionDimensions`
ShaMan123 Oct 11, 2022
0293390
refactor(): `_getTransformedDimensions`
ShaMan123 Oct 11, 2022
481b952
uglify(): keep backward style for migration compat
ShaMan123 Oct 11, 2022
5fa519f
refactor(vectors): es6, types, style
ShaMan123 Oct 11, 2022
90b4464
rename types
ShaMan123 Oct 11, 2022
592ae06
no function
ShaMan123 Oct 11, 2022
71b15f7
fix(`projectionsOpenPathButt`): dir can be determined
ShaMan123 Oct 11, 2022
02bdd2f
rename
ShaMan123 Oct 11, 2022
f8f12c2
refactor(): tidy
ShaMan123 Oct 11, 2022
5a2abdf
Update polyline.class.ts
ShaMan123 Oct 11, 2022
06c49aa
import
ShaMan123 Oct 11, 2022
e6706f2
Update projectStroke.ts
ShaMan123 Oct 11, 2022
023b1a6
fix(): imports
ShaMan123 Oct 11, 2022
584793b
refactor(): modularize
Oct 12, 2022
d7a28e8
refactor(): modularize squash
Oct 12, 2022
b744dde
refactor(): rename getOrthogonalUnitVector to getOrthonormalVector
Oct 12, 2022
10b1092
docs(): A B C JSDOC
ShaMan123 Oct 12, 2022
2c81536
fix(StrokeLineCapProjections#projectButt)
Oct 12, 2022
2ff9ee2
fix(StrokeLineJoinProjections#projectRoundWithSkew): correct calculat…
Oct 12, 2022
31b28a2
Merge commit 'refs/pull/8344/head' of github.com:fabricjs/fabric.js i…
Oct 12, 2022
5ff9847
fix(StrokeLineJoinProjections#projectRoundWithSkew): missing newY
Oct 12, 2022
0927c7e
fix(): `_setPositionDimensions` noSVG
ShaMan123 Oct 12, 2022
9eff7ad
refactor(): `_setPositionDimensions` + extract
ShaMan123 Oct 12, 2022
cfc186b
Update polygon.js
ShaMan123 Oct 12, 2022
c6f9906
fix(); glitch 9eff7adb
ShaMan123 Oct 12, 2022
3d8c33a
expose `setDimensions`
ShaMan123 Oct 12, 2022
b23f359
docs(changelog)
Oct 13, 2022
b7cc6d6
Merge branch 'master' into pr/8344
ShaMan123 Oct 13, 2022
f2afe77
safeguard(): no points
ShaMan123 Oct 13, 2022
ea35f21
fix(): return `Point[]`
ShaMan123 Oct 13, 2022
53a35b8
fix(): `_calcDimensions`
ShaMan123 Oct 13, 2022
94db2c5
fix(): imports
ShaMan123 Oct 13, 2022
ab5f63b
fix(path): account for `L` bounds
ShaMan123 Oct 13, 2022
5f57838
fix(polyline): `_getNonTransformedDimensions`
ShaMan123 Oct 13, 2022
c2ee044
fix? svg import
ShaMan123 Oct 13, 2022
873fc49
Merge branch 'master' into pr/8344
ShaMan123 Oct 13, 2022
d6b07f4
WIP: bbox + stroke
ShaMan123 Oct 13, 2022
0157f22
fix(): `exactBoundbox = false`
ShaMan123 Oct 13, 2022
9568563
tests
ShaMan123 Oct 13, 2022
253c228
Update CHANGELOG.md
ShaMan123 Oct 13, 2022
d624dcb
prettier
ShaMan123 Oct 13, 2022
62979a9
test(): adapt config
ShaMan123 Oct 14, 2022
5d81cf5
strokeOffset
ShaMan123 Oct 14, 2022
e0b954c
Merge branch 'master' into pr/8344
ShaMan123 Oct 15, 2022
c3b5254
fix(): testem browser start timeout
ShaMan123 Oct 15, 2022
5a98929
fix(): minor error
ShaMan123 Oct 15, 2022
d66f14d
fix(): line cap `round` `square` cases
ShaMan123 Oct 15, 2022
e4b48da
JSDOC
ShaMan123 Oct 15, 2022
76f5711
better
ShaMan123 Oct 15, 2022
f4de029
cleanup
ShaMan123 Oct 15, 2022
648d364
remove redundant projections + cases
ShaMan123 Oct 15, 2022
883e4b7
extract `magnitude` to vectors
ShaMan123 Oct 15, 2022
34460df
remove `hypot`
ShaMan123 Oct 15, 2022
aafe3a1
minor
ShaMan123 Oct 15, 2022
301276f
`strokeBBoxAffectingProperties`
ShaMan123 Oct 15, 2022
41d777e
syntax
ShaMan123 Oct 15, 2022
f158267
better svg options
ShaMan123 Oct 15, 2022
42d8f17
Merge branch 'master' into poly-stroke-bounding-rect-ts
asturur Oct 15, 2022
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
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = {
{
selector: '[callee.object.name="Math"][callee.property.name="hypot"]',
message:
'`Math.hypot` is not accurate on chrome, import `hypot` from `util` instead.',
'`Math.hypot` is not accurate on chrome, use `Math.sqrt` instead.\nSee https://stackoverflow.com/questions/62931950/different-results-of-math-hypot-on-chrome-and-firefox',
},
{
selector: 'VariableDeclarator[init.name="Math"]',
Expand Down
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
"error",
{
"selector": "[callee.object.name='Math'][callee.property.name='hypot']",
"message": "`Math.hypot` is not accurate on chrome, import `hypot` from `util` instead"
"message": "`Math.hypot` is not accurate on chrome, use `Math.sqrt` instead.\nSee https://stackoverflow.com/questions/62931950/different-results-of-math-hypot-on-chrome-and-firefox"
},
{
"selector": "VariableDeclarator[init.name='Math']",
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [next]

- BREAKING fix(polyline/polygon): stroke bounding box for all line join/cap cases [#8344](https://github.com/fabricjs/fabric.js/pull/8344)
BREAKING: `_setPositionDimensions` was removed in favor of `setDimensions`
- fix(textStyles): Handle style objects with only a textBackgroundColor property in stylesToArray [#8365](https://github.com/fabricjs/fabric.js/pull/8365)
- chore(): fix typos in intersection file [#8345](https://github.com/fabricjs/fabric.js/pull/8345)
- fix(textStyles): Handle empty style object in stylesToArray [#8357](https://github.com/fabricjs/fabric.js/pull/8357)
Expand Down
2 changes: 1 addition & 1 deletion src/point.class.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fabric } from '../HEADER';
import { TMat2D, TRadian } from './typedefs';
import { sin } from './util/misc/sin';
import { cos } from './util/misc/cos';
import { sin } from './util/misc/sin';

export interface IPoint {
x: number;
Expand Down
137 changes: 78 additions & 59 deletions src/shapes/path.class.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//@ts-nocheck

import { config } from '../config';
import { parseAttributes } from '../parser/parseAttributes';
import { Point } from '../point.class';
import { PathData } from '../typedefs';
import { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';
import { getBoundsOfCurve, makePathSimpler, parsePath } from '../util/path';

(function (global) {
var fabric = global.fabric || (global.fabric = {}),
Expand Down Expand Up @@ -49,23 +54,27 @@ import { config } from '../config';
options = clone(options || {});
delete options.path;
this.callSuper('initialize', options);
this._setPath(path || [], options);
const pathTL = this._setPath(path || []);
const origin = this.translateToGivenOrigin(
new Point(options.left ?? pathTL.x, options.top ?? pathTL.y),
typeof options.left === 'number' ? this.originX : 'left',
typeof options.top === 'number' ? this.originY : 'top',
this.originX,
this.originY
);
this.setPositionByOrigin(origin, this.originX, this.originY);
},

/**
* @private
* @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens)
* @param {Object} [options] Options object
* @param {PathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
* @returns {Point} top left position of the bounding box, useful for complementary positioning
*/
_setPath: function (path, options) {
this.path = fabric.util.makePathSimpler(
Array.isArray(path) ? path : fabric.util.parsePath(path)
);

fabric.Polyline.prototype._setPositionDimensions.call(
this,
options || {}
_setPath: function (path: PathData | string) {
this.path = makePathSimpler(
Array.isArray(path) ? path : parsePath(path)
);
return this.setDimensions();
},

/**
Expand Down Expand Up @@ -261,64 +270,75 @@ import { config } from '../config';
return this.path.length;
},

/**
* @returns {Point} top left position of the bounding box, useful for complementary positioning
*/
setDimensions: function () {
const { left, top, width, height, pathOffset } = this._calcDimensions();
this.set({ width, height, pathOffset });
return new Point(left, top);
},

/**
* @private
*/
_calcDimensions: function () {
var aX = [],
aY = [],
current, // current instruction
subpathStartX = 0,
const bounds: Point[] = [];
let subpathStartX = 0,
subpathStartY = 0,
x = 0, // current x
y = 0, // current y
bounds;

for (var i = 0, len = this.path.length; i < len; ++i) {
current = this.path[i];
y = 0; // current y

for (let i = 0; i < this.path.length; ++i) {
const current = this.path[i]; // current instruction
switch (
current[0] // first letter
) {
case 'L': // lineto, absolute
x = current[1];
y = current[2];
bounds = [];
bounds.push(
new Point(subpathStartX, subpathStartY),
new Point(x, y)
);
break;

case 'M': // moveTo, absolute
x = current[1];
y = current[2];
subpathStartX = x;
subpathStartY = y;
bounds = [];
break;

case 'C': // bezierCurveTo, absolute
bounds = fabric.util.getBoundsOfCurve(
x,
y,
current[1],
current[2],
current[3],
current[4],
current[5],
current[6]
bounds.push(
...getBoundsOfCurve(
x,
y,
current[1],
current[2],
current[3],
current[4],
current[5],
current[6]
)
);
x = current[5];
y = current[6];
break;

case 'Q': // quadraticCurveTo, absolute
bounds = fabric.util.getBoundsOfCurve(
x,
y,
current[1],
current[2],
current[1],
current[2],
current[3],
current[4]
bounds.push(
...getBoundsOfCurve(
x,
y,
current[1],
current[2],
current[1],
current[2],
current[3],
current[4]
)
);
x = current[3];
y = current[4];
Expand All @@ -330,26 +350,19 @@ import { config } from '../config';
y = subpathStartY;
break;
}
bounds.forEach(function (point) {
aX.push(point.x);
aY.push(point.y);
});
aX.push(x);
aY.push(y);
}

var minX = Math.min(...aX) || 0,
minY = Math.min(...aY) || 0,
maxX = Math.max(...aX) || 0,
maxY = Math.max(...aY) || 0,
deltaX = maxX - minX,
deltaY = maxY - minY;
const bbox = makeBoundingBoxFromPoints(bounds);
const strokeCorrection = this.fromSVG ? 0 : this.strokeWidth / 2;

return {
left: minX,
top: minY,
width: deltaX,
height: deltaY,
...bbox,
left: bbox.left - strokeCorrection,
top: bbox.top - strokeCorrection,
pathOffset: new Point(
bbox.left + bbox.width / 2,
bbox.top + bbox.height / 2
),
};
},
}
Expand Down Expand Up @@ -387,13 +400,19 @@ import { config } from '../config';
* @param {Function} [callback] Options callback invoked after parsing is finished
*/
fabric.Path.fromElement = function (element, callback, options) {
var parsedAttributes = fabric.parseAttributes(
const parsedAttributes = parseAttributes(
element,
fabric.Path.ATTRIBUTE_NAMES
);
parsedAttributes.fromSVG = true;
callback(
new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))
new fabric.Path(parsedAttributes.d, {
...parsedAttributes,
...options,
// we pass undefined to instruct the constructor to position the object using the bbox
left: undefined,
top: undefined,
fromSVG: true,
})
);
};
/* _FROM_SVG_END_ */
Expand Down
7 changes: 5 additions & 2 deletions src/shapes/polygon.class.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//@ts-nocheck

import { projectStrokeOnPoints } from '../util/misc/projectStroke';

(function (global) {
var fabric = global.fabric || (global.fabric = {}),
projectStrokeOnPoints = fabric.util.projectStrokeOnPoints;
var fabric = global.fabric || (global.fabric = {});

/**
* Polygon class
* @class fabric.Polygon
Expand Down
Loading