{ "version": 3, "sources": ["../../../../src/lib/shapes/shared/ScribbleManager.ts"], "sourcesContent": ["import { TLScribble, TLTickEvent, Vec2d, Vec2dModel, VecLike } from '@tldraw/editor'\n\n/** @public */\nexport class ScribbleManager implements TLScribble {\n\t// Scribble properties\n\tstate\n\tpoints\n\tsize\n\tcolor\n\topacity\n\tdelay\n\n\ttimeoutMs = 0\n\tdelayRemaining = 0\n\n\t// Callbacks\n\tprivate onUpdate: (scribble: TLScribble) => void\n\tprivate onComplete: () => void\n\n\t// Internal state\n\tprivate prev: VecLike | null = null\n\tprivate next: VecLike | null = null\n\n\tconstructor(opts: {\n\t\tonUpdate: (scribble: TLScribble) => void\n\t\tonComplete: () => void\n\t\tsize?: TLScribble['size']\n\t\tcolor?: TLScribble['color']\n\t\topacity?: TLScribble['opacity']\n\t\tdelay?: TLScribble['delay']\n\t}) {\n\t\tconst { size = 20, color = 'accent', opacity = 0.8, delay = 0, onComplete, onUpdate } = opts\n\n\t\tthis.onUpdate = onUpdate\n\t\tthis.onComplete = onComplete\n\t\tthis.size = size\n\t\tthis.color = color\n\t\tthis.delay = delay\n\t\tthis.opacity = opacity\n\t\tthis.points = [] as Vec2dModel[]\n\t\tthis.state = 'starting' as TLScribble['state']\n\n\t\tthis.prev = null\n\t\tthis.next = null\n\n\t\tthis.delayRemaining = this.delay\n\n\t\tthis.resume()\n\t}\n\n\tresume = () => {\n\t\tthis.state = 'active'\n\t}\n\n\tpause = () => {\n\t\tthis.state = 'starting'\n\t}\n\n\t/**\n\t * Start stopping the scribble. The scribble won't be removed until its last point is cleared.\n\t *\n\t * @public\n\t */\n\tstop = () => {\n\t\tthis.delayRemaining = Math.min(this.delayRemaining, 200)\n\t\tthis.state = 'stopping'\n\t}\n\n\t/**\n\t * Set the scribble's next point.\n\t *\n\t * @param point - The point to add.\n\t * @public\n\t */\n\taddPoint = (x: number, y: number) => {\n\t\tconst { prev } = this\n\t\tconst point = { x, y, z: 0.5 }\n\t\tif (prev && Vec2d.Dist(prev, point) < 1) return\n\t\tthis.next = point\n\t}\n\n\t/**\n\t * Get the current TLScribble object from the scribble manager.\n\t *\n\t * @public\n\t */\n\tgetScribble(): TLScribble {\n\t\treturn {\n\t\t\tstate: this.state,\n\t\t\tsize: this.size,\n\t\t\tcolor: this.color,\n\t\t\topacity: this.opacity,\n\t\t\tdelay: this.delay,\n\t\t\tpoints: [...this.points],\n\t\t}\n\t}\n\n\tprivate updateScribble() {\n\t\tthis.onUpdate(this.getScribble())\n\t}\n\n\ttick: TLTickEvent = (elapsed) => {\n\t\tthis.timeoutMs += elapsed\n\n\t\tif (this.delayRemaining > 0) {\n\t\t\tthis.delayRemaining = Math.max(0, this.delayRemaining - elapsed)\n\t\t}\n\n\t\tif (this.timeoutMs >= 16) {\n\t\t\tthis.timeoutMs = 0\n\t\t}\n\n\t\tconst { timeoutMs, state, prev, next, points } = this\n\n\t\tswitch (state) {\n\t\t\tcase 'active': {\n\t\t\t\tif (next && next !== prev) {\n\t\t\t\t\tthis.prev = next\n\t\t\t\t\tpoints.push(next)\n\n\t\t\t\t\tif (this.delayRemaining === 0) {\n\t\t\t\t\t\tif (points.length > 8) {\n\t\t\t\t\t\t\tpoints.shift()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.updateScribble()\n\t\t\t\t} else {\n\t\t\t\t\t// While not moving, shrink the scribble from the start\n\t\t\t\t\tif (timeoutMs === 0) {\n\t\t\t\t\t\tif (points.length > 1) {\n\t\t\t\t\t\t\tpoints.shift()\n\t\t\t\t\t\t\tthis.updateScribble()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.delayRemaining = this.delay\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'stopping': {\n\t\t\t\tif (this.delayRemaining === 0) {\n\t\t\t\t\tif (timeoutMs === 0) {\n\t\t\t\t\t\t// If the scribble is down to one point, we're done!\n\t\t\t\t\t\tif (points.length === 1) {\n\t\t\t\t\t\t\tthis.state = 'paused'\n\t\t\t\t\t\t\tthis.onComplete()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Drop the scribble's size\n\t\t\t\t\t\tthis.size *= 0.9\n\n\t\t\t\t\t\t// Drop the scribble's first point (its tail)\n\t\t\t\t\t\tpoints.shift()\n\n\t\t\t\t\t\t// otherwise, update the scribble\n\t\t\t\t\t\tthis.updateScribble()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'paused': {\n\t\t\t\t// Nothing to do while paused.\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"], "mappings": "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", "names": [] }