-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Observable types #8431
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
Observable types #8431
Changes from 34 commits
7dd2dec
853cdb4
cabf258
9af645e
a77e0fa
a80fa3d
abe7c5b
a10df06
ce34790
8b58223
ef73d35
586350c
f627e24
2159c8b
1fc674a
8602748
356d1a4
e7a4ddc
8dc94f1
6f2b877
4b2c1c6
ce006dc
2f4c681
63c8ef0
5975caf
6509e20
c83c7c6
d3ff302
6e6cdab
c1a0615
15e09bd
fca0374
152925d
683188c
c5ddb70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| import type { Control } from './controls/control.class'; | ||
| import type { Point } from './point.class'; | ||
| import type { FabricObject } from './shapes/fabricObject.class'; | ||
| import type { Group } from './shapes/group.class'; | ||
| import type { TOriginX, TOriginY, TRadian } from './typedefs'; | ||
| import type { saveObjectTransform } from './util/misc/objectTransforms'; | ||
| import type { Canvas } from './__types__'; | ||
| import type { IText } from './shapes/itext.class'; | ||
|
|
||
| export type ModifierKey = 'altKey' | 'shiftKey' | 'ctrlKey'; | ||
|
|
||
| export type TPointerEvent = MouseEvent | TouchEvent; | ||
|
|
||
| export type TransformAction<T extends Transform = Transform, R = void> = ( | ||
| eventData: TPointerEvent, | ||
| transform: T, | ||
| x: number, | ||
| y: number | ||
| ) => R; | ||
|
|
||
| export type TransformActionHandler<T extends Transform = Transform> = | ||
| TransformAction<T, boolean>; | ||
|
|
||
| export type ControlCallback<R = void> = ( | ||
| eventData: TPointerEvent, | ||
| control: Control, | ||
| fabricObject: FabricObject | ||
| ) => R; | ||
|
|
||
| export type ControlCursorCallback = ControlCallback<string>; | ||
|
|
||
| /** | ||
| * relative to target's containing coordinate plane | ||
| * both agree on every point | ||
| */ | ||
| export type Transform = { | ||
| target: FabricObject; | ||
| action: string; | ||
| actionHandler: TransformActionHandler; | ||
| corner: string; | ||
| scaleX: number; | ||
| scaleY: number; | ||
| skewX: number; | ||
| skewY: number; | ||
| offsetX: number; | ||
| offsetY: number; | ||
| originX: TOriginX; | ||
| originY: TOriginY; | ||
| ex: number; | ||
| ey: number; | ||
| lastX: number; | ||
| lastY: number; | ||
| theta: TRadian; | ||
| width: number; | ||
| height: number; | ||
| shiftKey: boolean; | ||
| altKey: boolean; | ||
| original: ReturnType<typeof saveObjectTransform>; | ||
| }; | ||
|
|
||
| export type TEvent<E extends Event = TPointerEvent> = { | ||
| e: E; | ||
| }; | ||
|
|
||
| export type BasicTransformEvent<E extends Event = TPointerEvent> = TEvent<E> & { | ||
| transform: Transform; | ||
| pointer: Point; | ||
| }; | ||
|
|
||
| export type TModificationEvents = | ||
| | 'moving' | ||
| | 'scaling' | ||
| | 'rotating' | ||
| | 'skewing' | ||
| | 'resizing'; | ||
|
|
||
| type ObjectModifiedEvents = Record<TModificationEvents, BasicTransformEvent> & { | ||
| modified: BasicTransformEvent | never; | ||
| }; | ||
|
|
||
| type CanvasModifiedEvents = Record< | ||
| `object:${keyof ObjectModifiedEvents}`, | ||
| BasicTransformEvent & { target: FabricObject } | ||
| >; | ||
|
|
||
| export type TransformEvent<T extends Event = TPointerEvent> = | ||
| BasicTransformEvent<T> & { | ||
| target: FabricObject; | ||
| subTargets: FabricObject[]; | ||
| button: number; | ||
| isClick: boolean; | ||
| pointer: Point; | ||
| absolutePointer: Point; | ||
| }; | ||
|
|
||
| type SimpleEventHandler<T extends Event = TPointerEvent> = TEvent<T> & { | ||
| target: FabricObject; | ||
| subTargets: FabricObject[]; | ||
| }; | ||
|
|
||
| type InEvent = { | ||
| previousTarget?: FabricObject; | ||
| }; | ||
|
|
||
| type OutEvent = { | ||
| nextTarget?: FabricObject; | ||
| }; | ||
|
|
||
| type DragEventData = TEvent<DragEvent> & { | ||
| target: FabricObject; | ||
| subTargets?: FabricObject[]; | ||
| dragSource?: FabricObject; | ||
| canDrop?: boolean; | ||
| dropTarget?: FabricObject; | ||
| }; | ||
|
|
||
| type DropEventData = DragEventData & { pointer: Point }; | ||
|
|
||
| type DnDEvents = { | ||
| dragstart: TEvent<DragEvent> & { target: FabricObject }; | ||
| drag: DragEventData; | ||
| dragover: DragEventData; | ||
| dragenter: DragEventData & InEvent; | ||
| dragleave: DragEventData & OutEvent; | ||
| dragend: DragEventData; | ||
| 'drop:before': DropEventData; | ||
| drop: DropEventData; | ||
| 'drop:after': DropEventData; | ||
| }; | ||
|
|
||
| type CanvasDnDEvents = DnDEvents & { | ||
| 'drag:enter': DragEventData & InEvent; | ||
| 'drag:leave': DragEventData & OutEvent; | ||
| }; | ||
|
|
||
| type CanvasSelectionEvents = { | ||
| 'selection:created': TEvent & { | ||
| selected: FabricObject[]; | ||
| }; | ||
| 'selection:updated': TEvent & { | ||
| selected: FabricObject[]; | ||
| deselected: FabricObject[]; | ||
| }; | ||
| 'before:selection:cleared': Partial<TEvent> & { | ||
| deselected: FabricObject[]; | ||
| }; | ||
| 'selection:cleared': Partial<TEvent> & { | ||
| deselected: FabricObject[]; | ||
| }; | ||
| }; | ||
|
|
||
| type BeforeSuffix<T extends string> = `${T}:before`; | ||
| type WithBeforeSuffix<T extends string> = T | BeforeSuffix<T>; | ||
|
|
||
| type TPointerEvents<Prefix extends string, E = Record<string, never>> = Record< | ||
| `${Prefix}${ | ||
| | WithBeforeSuffix<'down'> | ||
| | WithBeforeSuffix<'move'> | ||
| | WithBeforeSuffix<'up'> | ||
| | 'dblclick'}`, | ||
| TransformEvent & E | ||
| > & | ||
| Record<`${Prefix}wheel`, TransformEvent<WheelEvent> & E> & | ||
| Record<`${Prefix}over`, TransformEvent & InEvent & E> & | ||
| Record<`${Prefix}out`, TransformEvent & OutEvent & E>; | ||
|
|
||
| export type ObjectPointerEvents = TPointerEvents<'mouse'>; | ||
| export type CanvasPointerEvents = TPointerEvents<'mouse:'>; | ||
|
|
||
| export type ObjectEvents = ObjectPointerEvents & | ||
| DnDEvents & | ||
| ObjectModifiedEvents & { | ||
| // selection | ||
| selected: never; | ||
| deselected: never; | ||
|
||
|
|
||
| // tree | ||
| added: { target: Group | Canvas }; | ||
| removed: { target: Group | Canvas }; | ||
|
|
||
| // erasing | ||
| 'erasing:end': { path: FabricObject }; | ||
| }; | ||
|
|
||
| export type StaticCanvasEvents = { | ||
| // tree | ||
| 'object:added': { target: FabricObject }; | ||
| 'object:removed': { target: FabricObject }; | ||
| 'canvas:cleared': never; | ||
|
|
||
| // rendering | ||
| 'before:render': { ctx: CanvasRenderingContext2D }; | ||
| 'after:render': { ctx: CanvasRenderingContext2D }; | ||
| }; | ||
|
|
||
| export type CanvasEvents = StaticCanvasEvents & | ||
| CanvasPointerEvents & | ||
| CanvasDnDEvents & | ||
| CanvasModifiedEvents & | ||
| CanvasSelectionEvents & { | ||
| // brushes | ||
| 'before:path:created': { path: FabricObject }; | ||
| 'path:created': { path: FabricObject }; | ||
|
|
||
| // erasing | ||
| 'erasing:start': never; | ||
| 'erasing:end': | ||
| | never | ||
| | { | ||
| path: FabricObject; | ||
| targets: FabricObject[]; | ||
| subTargets: FabricObject[]; | ||
| drawables: { | ||
| backgroundImage?: FabricObject; | ||
| overlayImage?: FabricObject; | ||
| }; | ||
| }; | ||
|
|
||
| // IText | ||
| 'text:selection:changed': { target: IText }; | ||
| 'text:changed': { target: IText }; | ||
| 'text:editing:entered': { target: IText }; | ||
| 'text:editing:exited': { target: IText }; | ||
|
|
||
| // misc | ||
| 'contextmenu:before': SimpleEventHandler<Event>; | ||
| contextmenu: SimpleEventHandler<Event>; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
| import { dragHandler, getActionFromCorner } from './controls/actions'; | ||
| import { Point } from './point.class'; | ||
| import { FabricObject } from './shapes/fabricObject.class'; | ||
| import { Transform } from './typedefs'; | ||
| import { Transform } from './EventTypeDefs'; | ||
| import { saveObjectTransform } from './util/misc/objectTransforms'; | ||
|
|
||
| (function (global) { | ||
|
|
@@ -441,10 +441,12 @@ import { saveObjectTransform } from './util/misc/objectTransforms'; | |
| this._objectsToRender = undefined; | ||
| // removing active object should fire "selection:cleared" events | ||
| if (obj === this._activeObject) { | ||
| this.fire('before:selection:cleared', { target: obj }); | ||
| this.fire('before:selection:cleared', { deselected: [obj] }); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So here i m thorn between deselected and maybeDeselected or something like that. Ideas?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get your point. A good point indeed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MaybeDeselcted is bad naming. Target or deselectionTarget are better |
||
| this._discardActiveObject(); | ||
| this.fire('selection:cleared', { target: obj }); | ||
| obj.fire('deselected'); | ||
| this.fire('selection:cleared', { deselected: [obj] }); | ||
| obj.fire('deselected', { | ||
| target: obj, | ||
| }); | ||
| } | ||
| if (obj === this._hoveredTarget) { | ||
| this._hoveredTarget = null; | ||
|
|
@@ -548,7 +550,7 @@ import { saveObjectTransform } from './util/misc/objectTransforms'; | |
| var ctx = this.contextTop; | ||
| this.clearContext(ctx); | ||
| this.renderTopLayer(ctx); | ||
| this.fire('after:render'); | ||
| this.fire('after:render', { ctx }); | ||
| return this; | ||
| }, | ||
|
|
||
|
|
@@ -1363,7 +1365,10 @@ import { saveObjectTransform } from './util/misc/objectTransforms'; | |
| var currentActives = this.getActiveObjects(), | ||
| activeObject = this.getActiveObject(); | ||
| if (currentActives.length) { | ||
| this.fire('before:selection:cleared', { target: activeObject, e: e }); | ||
| this.fire('before:selection:cleared', { | ||
| e, | ||
| deselected: [activeObject], | ||
| }); | ||
| } | ||
| this._discardActiveObject(e); | ||
| this._fireSelectionEvents(currentActives, e); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to here are types from typedefs