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

chore(TS): Convert object geometry in its own class #8390

Merged
merged 27 commits into from
Oct 27, 2022
Merged

Conversation

asturur
Copy link
Member

@asturur asturur commented Oct 21, 2022

Motivation

Moving forward with the TS migration

Description

  • basic properties and methods of object like top,left,width,height... and all the other that infuence position are moved to the ObjectOrigin class.
  • basic properties and methods that influence dimensions of bounding box like skew, scale and strokeUniform and few other things, have been moved to ObjectGeometry class
  • FabricObject extends ObjectGeometry, that extends ObjectOrigin, trying to keep code divided by concern and TS happy.
  • Basic typing across all code touched, and mandatory es6 conversion ( const, let, fat arrows, some default args, some spread operators)

Really nothing else
Diffs are unreadable, i m sorry bewteen spacing and syntax changes git can't handle it.

Changes

All added lines are JSDOCS that were missing

BREAKING:

  • some chainability removed: setCoords, scale, scaleToWidth, scaleToHeight
  • adjustPosition is gone ( what it was even for? )

Gist

In Action

@asturur
Copy link
Member Author

asturur commented Oct 21, 2022

i think i m at 50% of this file and till now i didn't find any issue or bad thing

export class Group extends FabricObject {

}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to make typings happy for now

@github-actions
Copy link
Contributor

github-actions bot commented Oct 25, 2022

Build Stats

file / KB (diff) bundled reduced* minified gzipped
fabric.min.js 1126 (+35) 332 (+8) 93 (+2)
src/shapes/object.class.ts 64400 (-2547) 53056 (-46)
src/shapes/group.class.ts 37081 (+95) 38992 (-12)
src/mixins/object_geometry.mixin.ts 29335 (+29335) 27167 (+27167)
src/mixins/itext_click_behavior.mixin.ts 10808 (+723) 11411 (+581)
src/mixins/object_origin.mixin.ts 10901 (+10901) 7995 (+7995)
src/intersection.class.ts 6864 (+7) 7079 (0)
src/util/misc/boundingBoxFromPoints.ts 842 (+47) 782 (0)

*inaccurate, see link

@asturur
Copy link
Member Author

asturur commented Oct 26, 2022

Ok i have 29 Unit test to address by the code is done, apart the part that needs to be changed to get back the UTs in shape.

@asturur
Copy link
Member Author

asturur commented Oct 26, 2022

22 UTs to go

Copy link
Contributor

@ShaMan123 ShaMan123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • fixed typos
  • fixed buildStats diff sign
  • removed duplicate TBoundingBox => TBBox
  • added comment regarding getScaledWidth/Height
    I think we should deprecate them and expose getSize that will return the size in canvas plane

Comment on lines -169 to -175
* Returns the coordinates of the object based on center coordinates
* @param {Point} point The point which corresponds to the originX and originY params
* @return {Point}
*/
// getOriginPoint: function(center) {
// return this.translateToOriginPoint(center, this.originX, this.originY);
// },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted forever

Comment on lines -268 to -291
adjustPosition: function (to) {
var angle = degreesToRadians(this.angle),
hypotFull = this.getScaledWidth(),
xFull = fabric.util.cos(angle) * hypotFull,
yFull = fabric.util.sin(angle) * hypotFull,
offsetFrom,
offsetTo;

//TODO: this function does not consider mixed situation like top, center.
if (typeof this.originX === 'string') {
offsetFrom = originXOffset[this.originX];
} else {
offsetFrom = this.originX - 0.5;
}
if (typeof to === 'string') {
offsetTo = originXOffset[to];
} else {
offsetTo = to - 0.5;
}
this.left += xFull * (offsetTo - offsetFrom);
this.top += yFull * (offsetTo - offsetFrom);
this.setCoords();
this.originX = to;
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted forever

Comment on lines +351 to +391
* Sets the origin/position of the object to it's center point
* @private
* @return {void}
*/
_setOriginToCenter() {
this._originalOriginX = this.originX;
this._originalOriginY = this.originY;

const center = this.getRelativeCenterPoint();

this.originX = 'center';
this.originY = 'center';

this.left = center.x;
this.top = center.y;
}

/**
* Resets the origin/position of the object to it's original origin
* @private
* @return {void}
*/
_resetOrigin() {
if (
this._originalOriginX !== undefined &&
this._originalOriginY !== undefined
) {
const originPoint = this.translateToOriginPoint(
this.getRelativeCenterPoint(),
this._originalOriginX,
this._originalOriginY
);

this.left = originPoint.x;
this.top = originPoint.y;

this.originX = this._originalOriginX;
this.originY = this._originalOriginY;
this._originalOriginX = undefined;
this._originalOriginY = undefined;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would love to refactor those to be just inside the object.rotate method, and remove those as standalone methods. Not today

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed
I would add normalizePoint to the list.
I think it is used only by controls.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 26, 2022

Coverage after merging object-geometry into master will be

82.31%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
HEADER.js54.90%48.15%0%65.22%105, 105, 105, 12, 14, 14, 14, 14, 14, 16–17, 21, 21–22, 22, 22, 24, 24, 26, 28, 30–31
src
   cache.ts97.06%90%100%100%57
   canvas.class.ts93.44%90.36%94.23%95.58%1078, 1078–1079, 1082, 1102, 1102, 1137, 1170–1171, 1199–1200, 1233, 1241, 1351–1352, 1354–1355, 1375–1376, 1534, 1539, 1549, 1553, 486–487, 492, 501, 650–652, 697–698, 762–763, 766, 768, 815–817, 859, 864–865, 893–894
   config.ts77.27%66.67%66.67%84.62%130, 138–140, 151–153
   constants.ts100%100%100%100%
   intersection.class.ts100%100%100%100%
   pattern.class.ts92.19%85.71%100%96.30%110, 116, 127, 136, 88
   point.class.ts100%100%100%100%
   shadow.class.ts95.95%90%100%100%173, 240, 9
   static_canvas.class.ts90.21%83.99%96.77%92.82%1153–1154, 1154, 1154–1155, 1289, 1355–1356, 1359, 1408–1409, 1502, 1517, 1521, 1547–1548, 1577–1578, 1611–1612, 1653–1654, 1657, 1659, 1659, 1659, 1659, 1663, 1663, 1663–1665, 1687–1688, 1729–1730, 1733, 1735, 1735, 1735, 1735, 1739, 1739, 1739–1741, 1814, 1814–1815, 1888, 1890, 1890, 1890, 1890, 1890–1891, 1894–1895, 1895, 1895–1896, 1899, 1899, 1899, 1901, 1904, 1910, 1912–1913, 1913, 1913, 1916–1917, 1917, 1917, 1920, 279–280, 282–283, 285–286, 299–300, 302–303, 617, 643, 699–702, 902
src/brushes
   base_brush.class.ts100%100%100%100%
   circle_brush.class.ts2.99%0%0%3.92%100–101, 103, 105–107, 116, 116, 116, 118, 120, 122–124, 126–129, 137, 144, 146, 26, 31–32, 40–44, 48–52, 59–62, 70–74, 76, 84, 84, 84, 84, 84–85, 87, 87, 87–90, 92
   pattern_brush.class.ts5.26%0%0%8.33%16, 20–23, 25–26, 26, 26–29, 37–38, 40, 44, 55, 55, 55, 63–65, 65, 65, 72–73, 75–76, 76, 80
   pencil_brush.class.ts91.95%85.42%100%93.69%125–126, 155, 155–157, 279, 283, 288–289, 71–72, 87–88
   spray_brush.class.ts2.30%0%0%3.08%102–104, 106–107, 115, 115, 115, 115, 115–116, 118–119, 126–127, 129, 131–135, 144, 148–149, 149, 157, 157, 157–160, 162–165, 169–170, 172, 174–177, 180, 187–188, 190, 192–193, 195, 202–203, 205–206, 209, 209, 216, 216, 220, 25–26, 28–30, 30, 30–32, 36, 45, 52, 59, 66, 73, 80, 92–94
src/color
   color.class.ts91.67%84.51%100%94.44%325–326, 330–331, 334–335, 41, 45, 72–73, 73, 75, 75, 75–76, 78–79
   color_map.ts100%100%100%100%
   constants.ts100%100%100%100%
   index.ts100%100%100%100%
   util.ts100%100%100%100%
src/controls
   control.class.ts90.24%81.48%86.67%97.50%210, 304, 304, 348, 372, 6
   controls.actions.ts76.80%69.20%93.75%80.67%161, 163, 163, 163, 165, 167, 26, 28, 28, 28, 290–293, 321, 323, 330–331, 333, 333–334, 336–337, 341, 373, 375, 382–383, 385, 385–386, 388–389, 393, 421–422, 424, 426, 431, 434, 434, 434–435, 435, 435, 437, 437, 437–438, 438, 438, 441, 441, 441–442, 442, 442, 475–476, 478, 480, 485, 488, 488, 488–489, 489, 489, 491, 491, 491–492, 492, 492, 495, 495, 495–496, 496, 496, 520–522, 528, 528, 528–529, 532–535, 537, 537, 537–539, 539, 539–541, 543, 543, 543–545, 545, 545–546, 551, 551, 551–552, 554, 556–558, 57, 589–590, 592–594, 641–643, 8, 841
   controls.render.ts85.11%84.78%100%84.78%23, 27, 42–49, 58–59, 82, 86
   default_controls.ts94.29%50%100%100%117, 85
src/filters
   2d_backend.class.ts96.43%83.33%100%100%78
   WebGLProbe.ts40%40%57.14%34.78%38–39, 49–53, 61, 64, 66, 66, 66–67, 67, 67–70, 72, 74, 78
   base_filter.class.ts28.90%31.82%36.36%26.17%100–102, 102, 102–103, 112–116, 116, 116–117, 124–125, 125, 125–128, 143, 159, 169–174, 178, 181, 181, 181–184, 184, 184–185, 185, 188–189, 195, 204–205, 210–214, 257–260, 273, 273, 273–274, 276, 292–294, 294, 294, 294, 294–295, 297, 299–300, 306–307, 309–311, 315–316, 318, 322–324, 328, 332, 352, 352, 352–356, 393, 78, 78, 78–79, 79, 79–80, 80, 80–81, 86–89, 89, 89–90, 99

@asturur
Copy link
Member Author

asturur commented Oct 26, 2022

@ShaMan123 ok this is it.
The breaking changes are listed, see if there is something that really stands out ( in theory we have no code changes here ), then i want to move on to more conversion

Copy link
Contributor

@ShaMan123 ShaMan123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great
From all I commented I would rename _getTransformedDimensions ASAP
I guess you would prefer a dedicated PR.
Great job!

* @param {Boolean} calculate use coordinates of current position instead of .oCoords
* @return {Boolean} true if the object contains the point
*/
_containsCenterOfCanvas(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be private:
Does not make sense outside the context of isOnScreen and isPartiallyOnScreen

flipX: this.flipX,
flipY: this.flipY,
},
value = composeMatrix(options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where I think of trying the skewY trick

* @type Number
* @default 1
*/
strokeWidth: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this class requires strokeWidth and strokeUniform but I think they belong in an abstract super class
Thoughts?
But we can move ahead and think about this in a follow up

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe yes i don't want to over engineer, no one is going to look at those classes and they are going to look at Object only or Object + interaction.

I want to put a target on eoy for finishing this thing and all the changes that do not touch the public api can be postponed for me.

* @private
* @returns {Point} dimensions
*/
_getTransformedDimensions(options: any = {}): Point {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to rename this important method to getDimensions or calcDimensions
I think it should deprecate getScaledWidth/height

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's have a renaming task for all of those, but let's talk about it in a video call so that we can actually have a plan, and then we just go and rename. Renaming needs to be done before release of course.

skewX: this.skewX,
skewY: this.skewY,
width: this.width,
height: this.height,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put width and height here a while back
But now (after thinking of a fix to skewing controls + stroke projection) I understand it is wrong.
I makes no sense that a consumer of this method will provide the size.
Does it? The whole point of the method is to return the size of transform.
Passing width/height lets you "project" the bbox with a transform....
Thoughts?

offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY);

if (offsetX || offsetY) {
const dim = this._getTransformedDimensions();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part I didn't touch in the group PRs but it requires thought
This method is restricted to the containing plane of the object.
Should it be? Is it confusing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course changing this method means chaning all the rest.

Comment on lines +351 to +391
* Sets the origin/position of the object to it's center point
* @private
* @return {void}
*/
_setOriginToCenter() {
this._originalOriginX = this.originX;
this._originalOriginY = this.originY;

const center = this.getRelativeCenterPoint();

this.originX = 'center';
this.originY = 'center';

this.left = center.x;
this.top = center.y;
}

/**
* Resets the origin/position of the object to it's original origin
* @private
* @return {void}
*/
_resetOrigin() {
if (
this._originalOriginX !== undefined &&
this._originalOriginY !== undefined
) {
const originPoint = this.translateToOriginPoint(
this.getRelativeCenterPoint(),
this._originalOriginX,
this._originalOriginY
);

this.left = originPoint.x;
this.top = originPoint.y;

this.originX = this._originalOriginX;
this.originY = this._originalOriginY;
this._originalOriginX = undefined;
this._originalOriginY = undefined;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed
I would add normalizePoint to the list.
I think it is used only by controls.

* @private
* @returns {Point} dimensions
*/
_getNonTransformedDimensions(): Point {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should deprecate this method as well.
It is used only by Object._renderBackground

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And is weird in some context

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes getNonTransformedDimensions is not used anymore as before. is no more the base for getTransformed.

@asturur
Copy link
Member Author

asturur commented Oct 27, 2022

@ShaMan123 can you open 2 tasks with your comments? is not that i m lazy i m really short in time and i don't want to loose them.
One for what we want to rename, and one for what we want to merge where use and remove.

@asturur asturur merged commit 6a338db into master Oct 27, 2022
@asturur asturur deleted the object-geometry branch November 1, 2022 23:37
frankrousseau pushed a commit to cgwire/fabric.js that referenced this pull request Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants