diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md index e3a6d8906..d2df6ea09 100644 --- a/packages/editor/api-report.md +++ b/packages/editor/api-report.md @@ -1782,7 +1782,7 @@ export abstract class StateNode implements Partial { // (undocumented) onRightClick?: TLEventHandlers['onRightClick']; // (undocumented) - onTick?: TLTickEventHandler; + onTick?: TLEventHandlers['onTick']; // (undocumented) onTripleClick?: TLEventHandlers['onTripleClick']; // (undocumented) @@ -2102,13 +2102,15 @@ export interface TLEventHandlers { // (undocumented) onRightClick: TLPointerEvent; // (undocumented) + onTick: TLTickEvent; + // (undocumented) onTripleClick: TLClickEvent; // (undocumented) onWheel: TLWheelEvent; } // @public (undocumented) -export type TLEventInfo = TLCancelEventInfo | TLClickEventInfo | TLCompleteEventInfo | TLInterruptEventInfo | TLKeyboardEventInfo | TLPinchEventInfo | TLPointerEventInfo | TLWheelEventInfo; +export type TLEventInfo = TLCancelEventInfo | TLClickEventInfo | TLCompleteEventInfo | TLInterruptEventInfo | TLKeyboardEventInfo | TLPinchEventInfo | TLPointerEventInfo | TLTickEventInfo | TLWheelEventInfo; // @public (undocumented) export interface TLEventMap { @@ -2155,7 +2157,7 @@ export interface TLEventMap { export type TLEventMapHandler = (...args: TLEventMap[T]) => void; // @public (undocumented) -export type TLEventName = 'cancel' | 'complete' | 'interrupt' | 'wheel' | TLCLickEventName | TLKeyboardEventName | TLPinchEventName | TLPointerEventName; +export type TLEventName = 'cancel' | 'complete' | 'interrupt' | 'tick' | 'wheel' | TLCLickEventName | TLKeyboardEventName | TLPinchEventName | TLPointerEventName; // @public (undocumented) export type TLExitEventHandler = (info: any, to: string) => void; @@ -2571,10 +2573,7 @@ export type TLSvgOptions = { }; // @public (undocumented) -export type TLTickEvent = (elapsed: number) => void; - -// @public (undocumented) -export type TLTickEventHandler = () => void; +export type TLTickEvent = (info: TLTickEventInfo) => void; // @public export interface TLUserPreferences { diff --git a/packages/editor/api/api.json b/packages/editor/api/api.json index 0b38a1d21..6f5d87ed9 100644 --- a/packages/editor/api/api.json +++ b/packages/editor/api/api.json @@ -34154,8 +34154,12 @@ }, { "kind": "Reference", - "text": "TLTickEventHandler", - "canonicalReference": "@tldraw/editor!TLTickEventHandler:type" + "text": "TLEventHandlers", + "canonicalReference": "@tldraw/editor!TLEventHandlers:interface" + }, + { + "kind": "Content", + "text": "['onTick']" }, { "kind": "Content", @@ -34168,7 +34172,7 @@ "name": "onTick", "propertyTypeTokenRange": { "startIndex": 1, - "endIndex": 2 + "endIndex": 3 }, "isStatic": false, "isProtected": false, @@ -37534,6 +37538,34 @@ "endIndex": 2 } }, + { + "kind": "PropertySignature", + "canonicalReference": "@tldraw/editor!TLEventHandlers#onTick:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "onTick: " + }, + { + "kind": "Reference", + "text": "TLTickEvent", + "canonicalReference": "@tldraw/editor!TLTickEvent:type" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": false, + "isOptional": false, + "releaseTag": "Public", + "name": "onTick", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, { "kind": "PropertySignature", "canonicalReference": "@tldraw/editor!TLEventHandlers#onTripleClick:member", @@ -37665,6 +37697,15 @@ "kind": "Content", "text": " | " }, + { + "kind": "Reference", + "text": "TLTickEventInfo", + "canonicalReference": "@tldraw/editor!~TLTickEventInfo:type" + }, + { + "kind": "Content", + "text": " | " + }, { "kind": "Reference", "text": "TLWheelEventInfo", @@ -37680,7 +37721,7 @@ "name": "TLEventInfo", "typeTokenRange": { "startIndex": 1, - "endIndex": 16 + "endIndex": 18 } }, { @@ -38133,7 +38174,7 @@ }, { "kind": "Content", - "text": "'cancel' | 'complete' | 'interrupt' | 'wheel' | " + "text": "'cancel' | 'complete' | 'interrupt' | 'tick' | 'wheel' | " }, { "kind": "Reference", @@ -41562,7 +41603,16 @@ }, { "kind": "Content", - "text": "(elapsed: number) => void" + "text": "(info: " + }, + { + "kind": "Reference", + "text": "TLTickEventInfo", + "canonicalReference": "@tldraw/editor!~TLTickEventInfo:type" + }, + { + "kind": "Content", + "text": ") => void" }, { "kind": "Content", @@ -41574,33 +41624,7 @@ "name": "TLTickEvent", "typeTokenRange": { "startIndex": 1, - "endIndex": 2 - } - }, - { - "kind": "TypeAlias", - "canonicalReference": "@tldraw/editor!TLTickEventHandler:type", - "docComment": "/**\n * @public\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "export type TLTickEventHandler = " - }, - { - "kind": "Content", - "text": "() => void" - }, - { - "kind": "Content", - "text": ";" - } - ], - "fileUrlPath": "packages/editor/src/lib/editor/types/event-types.ts", - "releaseTag": "Public", - "name": "TLTickEventHandler", - "typeTokenRange": { - "startIndex": 1, - "endIndex": 2 + "endIndex": 4 } }, { diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index b9650e506..8f7f42c9f 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -223,7 +223,6 @@ export { type TLPointerEventName, type TLPointerEventTarget, type TLTickEvent, - type TLTickEventHandler, type TLWheelEvent, type TLWheelEventInfo, type UiEvent, diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index de43e3bc5..b22a3b4bc 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -637,6 +637,8 @@ export class Editor extends EventEmitter { this.updateRenderingBounds() + this.on('tick', this.tick) + requestAnimationFrame(() => { this._tickManager.start() }) @@ -8380,6 +8382,12 @@ export class Editor extends EventEmitter { ]) } + /** @internal */ + private tick = (elapsed = 0) => { + this.dispatch({ type: 'misc', name: 'tick', elapsed }) + this.scribbles.tick(elapsed) + } + /** * Dispatch a cancel event. * diff --git a/packages/editor/src/lib/editor/managers/ScribbleManager.ts b/packages/editor/src/lib/editor/managers/ScribbleManager.ts index 11c45bfe2..5b232caf5 100644 --- a/packages/editor/src/lib/editor/managers/ScribbleManager.ts +++ b/packages/editor/src/lib/editor/managers/ScribbleManager.ts @@ -2,7 +2,6 @@ import { TLScribble, VecModel } from '@tldraw/tlschema' import { Vec } from '../../primitives/Vec' import { uniqueId } from '../../utils/uniqueId' import { Editor } from '../Editor' -import { TLTickEvent } from '../types/event-types' type ScribbleItem = { id: string @@ -41,26 +40,12 @@ export class ScribbleManager { next: null, } this.scribbleItems.set(id, item) - if (this.state === 'paused') { - this.resume() - } return item } - resume() { - this.state = 'running' - this.editor.addListener('tick', this.tick) - } - - pause() { - this.editor.removeListener('tick', this.tick) - this.state = 'paused' - } - reset() { this.editor.updateInstanceState({ scribbles: [] }) this.scribbleItems.clear() - this.pause() } /** @@ -99,7 +84,8 @@ export class ScribbleManager { * @param elapsed - The number of milliseconds since the last tick. * @public */ - tick: TLTickEvent = (elapsed) => { + tick = (elapsed: number) => { + if (this.scribbleItems.size === 0) return this.editor.batch(() => { this.scribbleItems.forEach((item) => { // let the item get at least eight points before @@ -190,11 +176,6 @@ export class ScribbleManager { })) .slice(-5), // limit to three as a minor sanity check }) - - // If we've removed all the scribbles, stop ticking - if (this.scribbleItems.size === 0) { - this.pause() - } }) } } diff --git a/packages/editor/src/lib/editor/tools/StateNode.ts b/packages/editor/src/lib/editor/tools/StateNode.ts index 4744c7d67..5c5378b63 100644 --- a/packages/editor/src/lib/editor/tools/StateNode.ts +++ b/packages/editor/src/lib/editor/tools/StateNode.ts @@ -7,7 +7,6 @@ import { TLEventInfo, TLExitEventHandler, TLPinchEventInfo, - TLTickEventHandler, } from '../types/event-types' type TLStateNodeType = 'branch' | 'leaf' | 'root' @@ -158,7 +157,7 @@ export abstract class StateNode implements Partial { enter = (info: any, from: string) => { this._isActive.set(true) this.onEnter?.(info, from) - if (this.onTick) this.editor.on('tick', this.onTick) + if (this.children && this.initial && this.getIsActive()) { const initial = this.children[this.initial] this._current.set(initial) @@ -169,8 +168,8 @@ export abstract class StateNode implements Partial { // todo: move this logic into transition exit = (info: any, from: string) => { this._isActive.set(false) - if (this.onTick) this.editor.off('tick', this.onTick) this.onExit?.(info, from) + if (!this.getIsActive()) { this.getCurrent()?.exit(info, from) } @@ -211,8 +210,8 @@ export abstract class StateNode implements Partial { onCancel?: TLEventHandlers['onCancel'] onComplete?: TLEventHandlers['onComplete'] onInterrupt?: TLEventHandlers['onInterrupt'] + onTick?: TLEventHandlers['onTick'] onEnter?: TLEnterEventHandler onExit?: TLExitEventHandler - onTick?: TLTickEventHandler } diff --git a/packages/editor/src/lib/editor/types/event-types.ts b/packages/editor/src/lib/editor/types/event-types.ts index d1959c9a3..5fa41deb8 100644 --- a/packages/editor/src/lib/editor/types/event-types.ts +++ b/packages/editor/src/lib/editor/types/event-types.ts @@ -39,6 +39,7 @@ export type TLEventName = | 'cancel' | 'complete' | 'interrupt' + | 'tick' /** @public */ export interface TLBaseEventInfo { @@ -99,6 +100,8 @@ export type TLCancelEventInfo = { type: 'misc'; name: 'cancel' } export type TLCompleteEventInfo = { type: 'misc'; name: 'complete' } /** @public */ export type TLInterruptEventInfo = { type: 'misc'; name: 'interrupt' } +/** @public */ +export type TLTickEventInfo = { type: 'misc'; name: 'tick'; elapsed: number } /** @public */ export type TLEventInfo = @@ -110,6 +113,7 @@ export type TLEventInfo = | TLCancelEventInfo | TLCompleteEventInfo | TLInterruptEventInfo + | TLTickEventInfo /** @public */ export type TLPointerEvent = (info: TLPointerEventInfo) => void @@ -127,6 +131,8 @@ export type TLCancelEvent = (info: TLCancelEventInfo) => void export type TLCompleteEvent = (info: TLCompleteEventInfo) => void /** @public */ export type TLInterruptEvent = (info: TLInterruptEventInfo) => void +/** @public */ +export type TLTickEvent = (info: TLTickEventInfo) => void /** @public */ export type UiEvent = @@ -137,8 +143,6 @@ export type UiEvent = | TLCancelEvent | TLCompleteEvent -/** @public */ -export type TLTickEventHandler = () => void /** @public */ export type TLEnterEventHandler = (info: any, from: string) => void /** @public */ @@ -161,6 +165,7 @@ export interface TLEventHandlers { onCancel: TLCancelEvent onComplete: TLCompleteEvent onInterrupt: TLInterruptEvent + onTick: TLTickEvent } /** @public */ @@ -183,7 +188,5 @@ export const EVENT_NAME_MAP: Record< double_click: 'onDoubleClick', triple_click: 'onTripleClick', quadruple_click: 'onQuadrupleClick', + tick: 'onTick', } - -/** @public */ -export type TLTickEvent = (elapsed: number) => void diff --git a/packages/tldraw/api-report.md b/packages/tldraw/api-report.md index 45da508ec..5b45dafe6 100644 --- a/packages/tldraw/api-report.md +++ b/packages/tldraw/api-report.md @@ -114,7 +114,6 @@ import { TLStore } from '@tldraw/editor'; import { TLStoreWithStatus } from '@tldraw/editor'; import { TLSvgOptions } from '@tldraw/editor'; import { TLTextShape } from '@tldraw/editor'; -import { TLTickEventHandler } from '@tldraw/editor'; import { TLUnknownShape } from '@tldraw/editor'; import { TLVideoShape } from '@tldraw/editor'; import { UnionValidator } from '@tldraw/editor'; diff --git a/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts b/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts index 4258dbd0e..5cc228b00 100644 --- a/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts +++ b/packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts @@ -13,7 +13,6 @@ import { TLPointerEventInfo, TLShape, TLShapeId, - TLTickEventHandler, Vec, moveCameraWhenCloseToEdge, pointInPolygon, @@ -67,7 +66,7 @@ export class Brushing extends StateNode { this.editor.updateInstanceState({ brush: null }) } - override onTick: TLTickEventHandler = () => { + override onTick = () => { moveCameraWhenCloseToEdge(this.editor) if (this.isDirty) { this.isDirty = false diff --git a/packages/tldraw/src/lib/tools/SelectTool/childStates/Resizing.ts b/packages/tldraw/src/lib/tools/SelectTool/childStates/Resizing.ts index 6c9a76280..69a921c81 100644 --- a/packages/tldraw/src/lib/tools/SelectTool/childStates/Resizing.ts +++ b/packages/tldraw/src/lib/tools/SelectTool/childStates/Resizing.ts @@ -13,7 +13,6 @@ import { TLShape, TLShapeId, TLShapePartial, - TLTickEventHandler, Vec, VecLike, areAnglesCompatible, @@ -74,7 +73,7 @@ export class Resizing extends StateNode { this.updateShapes() } - override onTick: TLTickEventHandler = () => { + override onTick = () => { moveCameraWhenCloseToEdge(this.editor) if (!this.isDirty) return this.isDirty = false diff --git a/packages/tldraw/src/lib/tools/SelectTool/childStates/Translating.ts b/packages/tldraw/src/lib/tools/SelectTool/childStates/Translating.ts index 2952c3857..2b4c75d5b 100644 --- a/packages/tldraw/src/lib/tools/SelectTool/childStates/Translating.ts +++ b/packages/tldraw/src/lib/tools/SelectTool/childStates/Translating.ts @@ -10,7 +10,6 @@ import { TLPointerEventInfo, TLShape, TLShapePartial, - TLTickEventHandler, Vec, compact, isPageId, @@ -95,7 +94,7 @@ export class Translating extends StateNode { this.dragAndDropManager.clear() } - override onTick: TLTickEventHandler = () => { + override onTick = () => { this.dragAndDropManager.updateDroppingNode( this.snapshot.movingShapes, this.updateParentTransforms