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 StaticCanvas #8485

Merged
merged 20 commits into from Dec 5, 2022
Merged

chore(TS): convert StaticCanvas #8485

merged 20 commits into from Dec 5, 2022

Conversation

asturur
Copy link
Member

@asturur asturur commented Dec 3, 2022

Converting only StaticCanvas for now, Canvas in next PR

  • added new types for small objects that had recurring usage
  • had to losen a bit the toObect properties array
  • gave a stab at reducing and converting the stateful mixin but is not worth, is easier to just delete it
  • changed some private/protected stuff and add/remove implemementation to make TS happy
  • BREAKING drawClipPathOnCanvas no takes the clipPath as second argument instead of rechecking its existance inside.
  • introduced a type for cachedObject to specify which functions actually need an object that has a woring cache ( maybe we will cancel this idea before getting out of beta )

Motivation

Description

Changes

Gist

In Action

@github-actions
Copy link
Contributor

github-actions bot commented Dec 4, 2022

Build Stats

file / KB (diff) bundled minified
fabric 983.963 (-13.591) 310.080 (-1.294)

@asturur asturur marked this pull request as ready for review December 4, 2022 20:28
@github-actions
Copy link
Contributor

github-actions bot commented Dec 4, 2022

Coverage after merging TS-convert-static-canvas into master will be

82.77%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
HEADER.js54%48.15%0%63.64%12, 14, 14, 14, 14, 14, 16–17, 21, 21–22, 22, 22, 24, 24, 26, 28, 30–31, 77, 77, 77
src
   cache.ts97.06%90%100%100%56
   canvas.class.ts93%89.93%94.12%95.06%1047, 1047–1048, 1051, 1071, 1071, 1106, 1139–1140, 1168–1169, 1202, 1210, 1320–1321, 1323–1324, 1344–1345, 1511, 1516, 1526, 1526, 1526–1527, 1530, 474–475, 480, 489, 638–640, 685–686, 735–736, 739, 741, 784–786, 828, 833–834, 862–863
   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%118, 124, 135, 144, 96
   point.class.ts100%100%100%100%
   shadow.class.ts98.51%96%100%100%157
   static_canvas.class.ts92.22%86.67%96.88%94.64%1186–1187, 1187, 1187–1188, 1308, 1318, 1372–1373, 1376, 1411–1412, 1490, 1499, 1504, 1619, 1621, 1623, 1623, 1623, 1623, 1626, 1626, 1626–1627, 1679–1681, 1683, 1685, 1685, 1685, 1685, 1689, 1689, 1689–1691, 1762, 1762–1763, 1820, 1822–1823, 1823, 1823, 1826–1827, 1827, 1827, 280, 302–306, 322, 392–393, 395–396, 405, 409–410, 412–413, 930
src/brushes
   base_brush.class.ts100%100%100%100%
   circle_brush.class.ts1.52%0%0%2%101, 103–105, 114, 114, 114, 116, 118, 120–122, 124–127, 135, 142, 144, 24, 29–30, 38–42, 46–50, 57–60, 68–72, 74, 82, 82, 82, 82, 82–83, 85, 85, 85–88, 90, 98–99
   pattern_brush.class.ts97.14%87.50%100%100%22
   pencil_brush.class.ts91.91%85.42%100%93.64%123–124, 153, 153–155, 277, 281, 286–287, 69–70, 85–86
   spray_brush.class.ts1.16%0%0%1.56%100–102, 104–105, 113, 113, 113, 113, 113–114, 116–117, 124–125, 127, 129–133, 142, 146–147, 147, 155, 155, 155–158, 160–163, 167–168, 170, 172–175, 178, 185–186, 188, 190–191, 193, 200–201, 203–204, 207, 207, 214, 214, 218, 23–24, 26–28, 28, 28–30, 34, 43, 50, 57, 64, 71, 78, 90–92
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
   actions.ts100%100%100%100%
   changeWidth.ts100%100%100%100%
   control.class.ts93.98%88.89%90.91%97.78%235, 319, 319, 354
   controls.render.ts81.63%78%100%84.78%106, 111, 121, 121, 45, 50, 61, 61, 65–72, 81–82
   default_controls.ts86.67%66.67%100%100%125, 132
   drag.ts100%100%100%100%
   rotate.ts20%12.50%50%22.22%45, 51, 51, 51–52, 55–57, 59, 59, 59, 59, 59–61, 61, 61–63, 65, 65, 65–67, 67, 67–68, 73, 73, 73–74, 76, 78, 80–81
   scale.ts94.41%94.74%100%93.59%129–130, 132–134, 181–183, 42
   scaleSkew.ts80.56%66.67%100%92.31%14, 28, 30, 30, 30, 32, 34
   skew.ts91.03%79.31%100%97.67%130–131, 162–163, 170, 176, 178
   util.ts100%100%100%100%
   wrapWithFireEvent.ts100%100%100%100%
   wrapWithFixedAnchor.ts100%100%100%100%
src/filters
   2d_backend.class.ts92%83.33%100%93.75%35–36
   FilterBackend.ts88.89%83.33%100%90%11–12
   WebGLProbe.ts40.54%40%60%36.36%28–30, 30, 30–31, 33–35, 43, 46–48, 48, 48–51, 53, 58
   base_filter.class.ts20.47%20.41%31.82%18%100–102, 102, 102–103, 110–112, 112, 112–113, 120–123, 123, 123–124, 130, 130, 130–133, 151, 181–186, 190–191, 191, 191–194, 194, 194, 194, 194–196, 202, 211–212, 217–221, 264–267, 276, 287–288, 288, 288–289, 291, 307–309, 309, 309, 309, 309–310, 312, 314–315, 317–318, 320–322, 330–331, 333, 337–339, 343, 343, 343, 347, 347, 347–348, 370, 370, 370–374, 402, 58–59, 81–82, 84, 84, 84–85, 85, 88, 93–95, 97, 97, 97, 97, 97, 97–98
   blendcolor_filter.class.ts6.82%0%25%6.35%101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 103–106, 108–111, 113–116, 119–122, 124–127, 129–132, 134–137, 139–140, 140, 143–144, 144, 147–148, 148, 151, 153–156, 158–160, 175, 190–195, 60, 76, 80, 90–94, 96–99
   blendimage_filter.class.ts52.86%70%9.09%59.18%130, 138–139, 154, 170–172, 180, 182, 182, 197–198, 46, 50, 54–58, 62, 72–74
   blur_filter.class.ts2.17%0%0%2.90%100–101, 103–107, 120, 135–136, 144–146,

this.off('mouse:up', this._mouseUpITextHandler);
this._iTextInstances = null;
this._hasITextHandlers = false;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

StaticCanvas shouldn't have Itext handlers, if someone come with a real use case we can revert this back

@asturur
Copy link
Member Author

asturur commented Dec 4, 2022

@ShaMan123 ready to go for me.
See if you see something meaningful that needs to be changed

ShaMan123
ShaMan123 previously approved these changes Dec 4, 2022
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.

src/util/types.ts:
I saw your comment regarding using instanceof. My suggestion is simple. We create a base class that is exposed only internally for instanceof checks.
So we do something like:

export class TextBase extends FabricObject {

}

export class Text extends TextBase {
   ...logic
}

import { TextBase, type Text } from '..';

function isText(what: FabricObject): what is Text {
   return what instanceof TextBase
}

A bit clumsy IMO. Is it that bad including it (importing the real class)?

export const isHTMLCanvas = (
canvas: HTMLCanvasElement | string
): canvas is HTMLCanvasElement => {
return !!canvas && (canvas as HTMLCanvasElement).getContext !== undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if instanceof works on node as well nowadays

export const isPattern = (filler: TFiller): filler is Pattern => {
return (
!!filler &&
(filler as Pattern).offsetX !== undefined &&
Copy link
Contributor

Choose a reason for hiding this comment

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

no need for this logic, why not instanceof?

Copy link
Contributor

Choose a reason for hiding this comment

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

I saw the comments

* The coordinates get updated with @method calcViewportBoundaries.
* @memberOf fabric.StaticCanvas.prototype
*/
vptCoords: TCornerPoint;
Copy link
Contributor

Choose a reason for hiding this comment

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

TCornerPoint: not a great name

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah i agree.

}
});

if (this._isCurrentlyDrawing) {
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 shouldn't be in StaticCanvas as well, it is canvas domain

Copy link
Member Author

Choose a reason for hiding this comment

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

i didn't even see it

*/
drawClipPathOnCanvas(
ctx: CanvasRenderingContext2D,
clipPath: TCachedFabricObject
Copy link
Contributor

Choose a reason for hiding this comment

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

nice and simple!

width: this.width / (shouldTransform ? vpt[0] : 1),
height: this.height / (shouldTransform ? vpt[3] : 1),
};
return fill.toSVG(object as Rect, {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like object as Rect
I prefer fixing the types in the Filler

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah so object needs to be a fabricObject, but it can be FabricObject | StaticCanvas to be honest, it just needs to have TSize or extends the interface of a TSize

Copy link
Contributor

Choose a reason for hiding this comment

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

So let's change the signature at fill#toSVG

return;
}
if (isFiller(filler)) {
// @ts-ignore TS is so stubbordn that i can't even check if a property exists.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is really too much, I agree

@asturur
Copy link
Member Author

asturur commented Dec 5, 2022

oh ok, i understand what you mean with the empty classes.
A empty shell class that is the base class ONLY for a specific class, in its own file so it doesn't crete any code import.
I can try that when i convert Canvas

@asturur
Copy link
Member Author

asturur commented Dec 5, 2022

src/util/types.ts: I saw your comment regarding using instanceof. My suggestion is simple. We create a base class that is exposed only internally for instanceof checks. So we do something like:

export class TextBase extends FabricObject {

}

export class Text extends TextBase {
   ...logic
}
import { TextBase, type Text } from '..';

function isText(what: FabricObject): what is Text {
   return what instanceof TextBase
}

A bit clumsy IMO. Is it that bad including it (importing the real class)?

Well you can't code split anymore.
If you work with canvas and rect, you have to import patterns or text just for the purpose of checking the objects you have aren't Text.
At leat this is my impression.

@asturur
Copy link
Member Author

asturur commented Dec 5, 2022

@ShaMan123 Did you reorder imports with some logic?
If prettier doesn't do that don't do it, is that some plugin you have or was willingful?

@ShaMan123
Copy link
Contributor

VSCODE handles organizing imports
ctrl + shift + o
It removes unused, duplicate and reorders

@ShaMan123
Copy link
Contributor

Is there a way for prettier to do that?

@asturur
Copy link
Member Author

asturur commented Dec 5, 2022

is the reorder part that isn't great.
I don't want meaningless commits in the history, when you need to debug something, reading that list trying to figure out if there is a change or a reorder only.
Or if we rename a file then we will have a bit at time changes of ordering all over the place.

@asturur asturur merged commit 4107721 into master Dec 5, 2022
@asturur asturur deleted the TS-convert-static-canvas branch December 5, 2022 09:53
@ShaMan123
Copy link
Contributor

is the reorder part that isn't great.

If we make it part of config that won't happen since it will be reordered before committing by vscode/prettier

@ShaMan123
Copy link
Contributor

VSCODE handles organizing imports ctrl + shift + o It removes unused, duplicate and reorders

It is alt+ shift + o on windows

@ShaMan123
Copy link
Contributor

We should move control rendering logic to canvas as well.
Things like

if (this.controlsAboveOverlay && this.interactive) {

@ShaMan123
Copy link
Contributor

I don't understand how the static canvas file passes TS, many fields aren't typed. Did you do some magic config I missed?

@ShaMan123
Copy link
Contributor

ShaMan123 commented Dec 6, 2022

I see, it is because of CollectionMixin types, I will try to fix

frankrousseau pushed a commit to cgwire/fabric.js that referenced this pull request Jan 6, 2023
Co-authored-by: ShaMan123 <shacharnen@gmail.com>
ShaMan123 added a commit that referenced this pull request Mar 16, 2024
Co-authored-by: ShaMan123 <shacharnen@gmail.com>
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.

None yet

2 participants