Skip to content

Commit ae6c245

Browse files
authored
Chore(): TS add detailed types for on/off/once callbacks (#8431)
1 parent 59e6a22 commit ae6c245

31 files changed

+431
-168
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## [next]
44

5+
- chore(TS): Observable types [#8431](https://github.com/fabricjs/fabric.js/pull/8431)
56
- chore(TS): migrate Group/ActiveSelection [#8455](https://github.com/fabricjs/fabric.js/pull/8455)
67
- fix(TS): migration error of itext key mixin (#8421) [#8457](https://github.com/fabricjs/fabric.js/pull/8457)
78
- chore(TS): migrate text classes/mixins [#8421](https://github.com/fabricjs/fabric.js/pull/8421)

src/EventTypeDefs.ts

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import type { Control } from './controls/control.class';
2+
import type { Point } from './point.class';
3+
import type { FabricObject } from './shapes/fabricObject.class';
4+
import type { Group } from './shapes/group.class';
5+
import type { TOriginX, TOriginY, TRadian } from './typedefs';
6+
import type { saveObjectTransform } from './util/misc/objectTransforms';
7+
import type { Canvas } from './__types__';
8+
import type { IText } from './shapes/itext.class';
9+
10+
export type ModifierKey = 'altKey' | 'shiftKey' | 'ctrlKey';
11+
12+
export type TPointerEvent = MouseEvent | TouchEvent;
13+
14+
export type TransformAction<T extends Transform = Transform, R = void> = (
15+
eventData: TPointerEvent,
16+
transform: T,
17+
x: number,
18+
y: number
19+
) => R;
20+
21+
export type TransformActionHandler<T extends Transform = Transform> =
22+
TransformAction<T, boolean>;
23+
24+
export type ControlCallback<R = void> = (
25+
eventData: TPointerEvent,
26+
control: Control,
27+
fabricObject: FabricObject
28+
) => R;
29+
30+
export type ControlCursorCallback = ControlCallback<string>;
31+
32+
/**
33+
* relative to target's containing coordinate plane
34+
* both agree on every point
35+
*/
36+
export type Transform = {
37+
target: FabricObject;
38+
action: string;
39+
actionHandler: TransformActionHandler;
40+
corner: string;
41+
scaleX: number;
42+
scaleY: number;
43+
skewX: number;
44+
skewY: number;
45+
offsetX: number;
46+
offsetY: number;
47+
originX: TOriginX;
48+
originY: TOriginY;
49+
ex: number;
50+
ey: number;
51+
lastX: number;
52+
lastY: number;
53+
theta: TRadian;
54+
width: number;
55+
height: number;
56+
shiftKey: boolean;
57+
altKey: boolean;
58+
original: ReturnType<typeof saveObjectTransform>;
59+
};
60+
61+
export type TEvent<E extends Event = TPointerEvent> = {
62+
e: E;
63+
};
64+
65+
export type BasicTransformEvent<E extends Event = TPointerEvent> = TEvent<E> & {
66+
transform: Transform;
67+
pointer: Point;
68+
};
69+
70+
export type TModificationEvents =
71+
| 'moving'
72+
| 'scaling'
73+
| 'rotating'
74+
| 'skewing'
75+
| 'resizing';
76+
77+
type ObjectModifiedEvents = Record<TModificationEvents, BasicTransformEvent> & {
78+
modified: BasicTransformEvent | never;
79+
};
80+
81+
type CanvasModifiedEvents = Record<
82+
`object:${keyof ObjectModifiedEvents}`,
83+
BasicTransformEvent & { target: FabricObject }
84+
>;
85+
86+
export type TransformEvent<T extends Event = TPointerEvent> =
87+
BasicTransformEvent<T> & {
88+
target: FabricObject;
89+
subTargets: FabricObject[];
90+
button: number;
91+
isClick: boolean;
92+
pointer: Point;
93+
absolutePointer: Point;
94+
};
95+
96+
type SimpleEventHandler<T extends Event = TPointerEvent> = TEvent<T> & {
97+
target: FabricObject;
98+
subTargets: FabricObject[];
99+
};
100+
101+
type InEvent = {
102+
previousTarget?: FabricObject;
103+
};
104+
105+
type OutEvent = {
106+
nextTarget?: FabricObject;
107+
};
108+
109+
type DragEventData = TEvent<DragEvent> & {
110+
target: FabricObject;
111+
subTargets?: FabricObject[];
112+
dragSource?: FabricObject;
113+
canDrop?: boolean;
114+
dropTarget?: FabricObject;
115+
};
116+
117+
type DropEventData = DragEventData & { pointer: Point };
118+
119+
type DnDEvents = {
120+
dragstart: TEvent<DragEvent> & { target: FabricObject };
121+
drag: DragEventData;
122+
dragover: DragEventData;
123+
dragenter: DragEventData & InEvent;
124+
dragleave: DragEventData & OutEvent;
125+
dragend: DragEventData;
126+
'drop:before': DropEventData;
127+
drop: DropEventData;
128+
'drop:after': DropEventData;
129+
};
130+
131+
type CanvasDnDEvents = DnDEvents & {
132+
'drag:enter': DragEventData & InEvent;
133+
'drag:leave': DragEventData & OutEvent;
134+
};
135+
136+
type CanvasSelectionEvents = {
137+
'selection:created': TEvent & {
138+
selected: FabricObject[];
139+
};
140+
'selection:updated': TEvent & {
141+
selected: FabricObject[];
142+
deselected: FabricObject[];
143+
};
144+
'before:selection:cleared': Partial<TEvent> & {
145+
deselected: FabricObject[];
146+
};
147+
'selection:cleared': Partial<TEvent> & {
148+
deselected: FabricObject[];
149+
};
150+
};
151+
152+
type BeforeSuffix<T extends string> = `${T}:before`;
153+
type WithBeforeSuffix<T extends string> = T | BeforeSuffix<T>;
154+
155+
type TPointerEvents<Prefix extends string, E = Record<string, never>> = Record<
156+
`${Prefix}${
157+
| WithBeforeSuffix<'down'>
158+
| WithBeforeSuffix<'move'>
159+
| WithBeforeSuffix<'up'>
160+
| 'dblclick'}`,
161+
TransformEvent & E
162+
> &
163+
Record<`${Prefix}wheel`, TransformEvent<WheelEvent> & E> &
164+
Record<`${Prefix}over`, TransformEvent & InEvent & E> &
165+
Record<`${Prefix}out`, TransformEvent & OutEvent & E>;
166+
167+
export type ObjectPointerEvents = TPointerEvents<'mouse'>;
168+
export type CanvasPointerEvents = TPointerEvents<'mouse:'>;
169+
170+
export type ObjectEvents = ObjectPointerEvents &
171+
DnDEvents &
172+
ObjectModifiedEvents & {
173+
// selection
174+
selected: {
175+
e: TEvent;
176+
target: FabricObject;
177+
};
178+
deselected: {
179+
e?: TEvent;
180+
target: FabricObject;
181+
};
182+
183+
// tree
184+
added: { target: Group | Canvas };
185+
removed: { target: Group | Canvas };
186+
187+
// erasing
188+
'erasing:end': { path: FabricObject };
189+
};
190+
191+
export type StaticCanvasEvents = {
192+
// tree
193+
'object:added': { target: FabricObject };
194+
'object:removed': { target: FabricObject };
195+
'canvas:cleared': never;
196+
197+
// rendering
198+
'before:render': { ctx: CanvasRenderingContext2D };
199+
'after:render': { ctx: CanvasRenderingContext2D };
200+
};
201+
202+
export type CanvasEvents = StaticCanvasEvents &
203+
CanvasPointerEvents &
204+
CanvasDnDEvents &
205+
CanvasModifiedEvents &
206+
CanvasSelectionEvents & {
207+
// brushes
208+
'before:path:created': { path: FabricObject };
209+
'path:created': { path: FabricObject };
210+
211+
// erasing
212+
'erasing:start': never;
213+
'erasing:end':
214+
| never
215+
| {
216+
path: FabricObject;
217+
targets: FabricObject[];
218+
subTargets: FabricObject[];
219+
drawables: {
220+
backgroundImage?: FabricObject;
221+
overlayImage?: FabricObject;
222+
};
223+
};
224+
225+
// IText
226+
'text:selection:changed': { target: IText };
227+
'text:changed': { target: IText };
228+
'text:editing:entered': { target: IText };
229+
'text:editing:exited': { target: IText };
230+
231+
// misc
232+
'contextmenu:before': SimpleEventHandler<Event>;
233+
contextmenu: SimpleEventHandler<Event>;
234+
};

src/__types__.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { CanvasEvents, ModifierKey } from './EventTypeDefs';
12
import type { Observable } from './mixins/observable.mixin';
23
import type { Point } from './point.class';
3-
import { ModifierKey, TMat2D } from './typedefs';
4+
import { TMat2D } from './typedefs';
45

56
/**
67
* @todo remove transient
@@ -18,4 +19,4 @@ export type StaticCanvas = Record<string, any> & {
1819
br: Point;
1920
};
2021
getRetinaScaling(): number;
21-
} & Observable;
22+
} & Observable<CanvasEvents>;

src/brushes/pencil_brush.class.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { fabric } from '../../HEADER';
2+
import { ModifierKey, TEvent } from '../EventTypeDefs';
23
import { Point } from '../point.class';
34
import { Shadow } from '../shadow.class';
45
import { Path } from '../shapes/path.class';
5-
import { TEvent, ModifierKey, PathData } from '../typedefs';
6+
import { PathData } from '../typedefs';
67
import { getSmoothPathFromPoints, joinPath } from '../util/path';
78
import { Canvas } from '../__types__';
89
import { BaseBrush } from './base_brush.class';

src/canvas.class.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { dragHandler, getActionFromCorner } from './controls/actions';
33
import { Point } from './point.class';
44
import { FabricObject } from './shapes/fabricObject.class';
5-
import { Transform } from './typedefs';
5+
import { Transform } from './EventTypeDefs';
66
import { saveObjectTransform } from './util/misc/objectTransforms';
77

88
(function (global) {
@@ -441,10 +441,12 @@ import { saveObjectTransform } from './util/misc/objectTransforms';
441441
this._objectsToRender = undefined;
442442
// removing active object should fire "selection:cleared" events
443443
if (obj === this._activeObject) {
444-
this.fire('before:selection:cleared', { target: obj });
444+
this.fire('before:selection:cleared', { deselected: [obj] });
445445
this._discardActiveObject();
446-
this.fire('selection:cleared', { target: obj });
447-
obj.fire('deselected');
446+
this.fire('selection:cleared', { deselected: [obj] });
447+
obj.fire('deselected', {
448+
target: obj,
449+
});
448450
}
449451
if (obj === this._hoveredTarget) {
450452
this._hoveredTarget = null;
@@ -548,7 +550,7 @@ import { saveObjectTransform } from './util/misc/objectTransforms';
548550
var ctx = this.contextTop;
549551
this.clearContext(ctx);
550552
this.renderTopLayer(ctx);
551-
this.fire('after:render');
553+
this.fire('after:render', { ctx });
552554
return this;
553555
},
554556

@@ -1363,7 +1365,10 @@ import { saveObjectTransform } from './util/misc/objectTransforms';
13631365
var currentActives = this.getActiveObjects(),
13641366
activeObject = this.getActiveObject();
13651367
if (currentActives.length) {
1366-
this.fire('before:selection:cleared', { target: activeObject, e: e });
1368+
this.fire('before:selection:cleared', {
1369+
e,
1370+
deselected: [activeObject],
1371+
});
13671372
}
13681373
this._discardActiveObject(e);
13691374
this._fireSelectionEvents(currentActives, e);

src/controls/changeWidth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TransformActionHandler } from '../typedefs';
1+
import { TransformActionHandler } from '../EventTypeDefs';
22
import { getLocalPoint, isTransformCentered } from './util';
33
import { wrapWithFireEvent } from './wrapWithFireEvent';
44
import { wrapWithFixedAnchor } from './wrapWithFixedAnchor';

src/controls/control.class.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
/* eslint-disable @typescript-eslint/no-unused-vars */
22
import { fabric } from '../../HEADER';
33
import { halfPI } from '../constants';
4-
import { Point } from '../point.class';
5-
import type { FabricObject } from '../shapes/object.class';
64
import {
7-
TDegree,
8-
TMat2D,
95
TPointerEvent,
106
TransformAction,
117
TransformActionHandler,
12-
} from '../typedefs';
8+
} from '../EventTypeDefs';
9+
import { Point } from '../point.class';
10+
import type { FabricObject } from '../shapes/object.class';
11+
import { TDegree, TMat2D } from '../typedefs';
1312
import { cos } from '../util/misc/cos';
1413
import { degreesToRadians } from '../util/misc/radiansDegreesConversion';
1514
import { sin } from '../util/misc/sin';

src/controls/drag.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TransformActionHandler } from '../typedefs';
1+
import { TransformActionHandler } from '../EventTypeDefs';
22
import { fireEvent } from '../util/fireEvent';
33
import { commonEventInfo, isLocked } from './util';
44

src/controls/rotate.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
// @ts-nocheck
2-
3-
import { ControlCursorCallback, TransformActionHandler } from '../typedefs';
1+
import {
2+
ControlCursorCallback,
3+
TransformActionHandler,
4+
} from '../EventTypeDefs';
45
import { radiansToDegrees } from '../util/misc/radiansDegreesConversion';
56
import { isLocked, NOT_ALLOWED_CURSOR } from './util';
67
import { wrapWithFireEvent } from './wrapWithFireEvent';

src/controls/scale.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { FabricObject } from '../shapes/fabricObject.class';
21
import {
32
ControlCursorCallback,
4-
TAxis,
53
TPointerEvent,
64
Transform,
75
TransformActionHandler,
8-
} from '../typedefs';
6+
} from '../EventTypeDefs';
7+
import type { FabricObject } from '../shapes/fabricObject.class';
8+
import { TAxis } from '../typedefs';
99
import { Canvas } from '../__types__';
1010
import {
1111
findCornerQuadrant,

0 commit comments

Comments
 (0)