{
  "version": 3,
  "sources": ["../../../src/lib/overlays/CollaboratorScribbleOverlayUtil.ts"],
  "sourcesContent": ["import { EASINGS, OverlayUtil, TLOverlay, TLScribble, getSvgPathFromPoints } from '@tldraw/editor'\nimport { getStroke } from '../shapes/shared/freehand/getStroke'\n\n/** @public */\nexport interface TLCollaboratorScribbleOverlay extends TLOverlay {\n\tprops: {\n\t\tscribble: TLScribble\n\t\tcolor: string\n\t}\n}\n\n// Cache Path2D results for collaborator scribbles similarly to local scribbles\ninterface CollaboratorScribbleCacheEntry {\n\tlen: number\n\tlastX: number\n\tlastY: number\n\tzoom: number\n\tsize: number\n\ttaper: boolean\n\tstate: TLCollaboratorScribbleOverlay['props']['scribble']['state']\n\tpath: Path2D\n}\n\n/**\n * Overlay util for collaborator scribble strokes (eraser, lasso, etc.).\n *\n * @public\n */\nexport class CollaboratorScribbleOverlayUtil extends OverlayUtil<TLCollaboratorScribbleOverlay> {\n\tstatic override type = 'collaborator_scribble'\n\toverride options = { zIndex: 800, streamline: 0.32, cacheSize: 500 }\n\n\t// String-keyed (not a WeakMap) because the cache key is a logical identity\n\t// \u2014 `${overlay.id}` derived from `scribble.id` \u2014 not the scribble object.\n\t// Tldraw's store replaces record objects on every update, so a WeakMap\n\t// keyed on the `TLScribble` instance would cache-miss every frame. Lifetime\n\t// is bounded by the Util instance (so, by the editor) plus the `cacheSize`\n\t// cap in `render` below.\n\tprivate _collabScribblePathCache = new Map<string, CollaboratorScribbleCacheEntry>()\n\n\toverride isActive(): boolean {\n\t\treturn this.editor.getVisibleCollaboratorsOnCurrentPage().some((c) => c.scribbles.length > 0)\n\t}\n\n\toverride getOverlays(): TLCollaboratorScribbleOverlay[] {\n\t\tconst overlays: TLCollaboratorScribbleOverlay[] = []\n\t\tfor (const presence of this.editor.getVisibleCollaboratorsOnCurrentPage()) {\n\t\t\tconst { scribbles, color, userId } = presence\n\t\t\tfor (const scribble of scribbles) {\n\t\t\t\toverlays.push({\n\t\t\t\t\tid: `collaborator_scribble:${userId}:${scribble.id}`,\n\t\t\t\t\ttype: 'collaborator_scribble',\n\t\t\t\t\tprops: { scribble, color },\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn overlays\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, overlays: TLCollaboratorScribbleOverlay[]): void {\n\t\tconst zoom = this.editor.getZoomLevel()\n\n\t\tfor (const overlay of overlays) {\n\t\t\tconst { scribble, color } = overlay.props\n\t\t\tconst ptsLen = scribble.points.length\n\t\t\tif (!ptsLen) continue\n\n\t\t\tconst last = scribble.points[ptsLen - 1]\n\t\t\tconst cacheKey = overlay.id\n\t\t\tconst cached = this._collabScribblePathCache.get(cacheKey)\n\t\t\tlet path: Path2D\n\t\t\tif (\n\t\t\t\tcached &&\n\t\t\t\tcached.len === ptsLen &&\n\t\t\t\tcached.lastX === last.x &&\n\t\t\t\tcached.lastY === last.y &&\n\t\t\t\tcached.zoom === zoom &&\n\t\t\t\tcached.size === scribble.size &&\n\t\t\t\tcached.taper === scribble.taper &&\n\t\t\t\tcached.state === scribble.state\n\t\t\t) {\n\t\t\t\tpath = cached.path\n\t\t\t} else {\n\t\t\t\tconst stroke = getStroke(scribble.points, {\n\t\t\t\t\tsize: scribble.size / zoom,\n\t\t\t\t\tstart: { taper: scribble.taper, easing: EASINGS.linear },\n\t\t\t\t\tlast: scribble.state === 'complete' || scribble.state === 'stopping',\n\t\t\t\t\tsimulatePressure: false,\n\t\t\t\t\tstreamline: this.options.streamline,\n\t\t\t\t})\n\n\t\t\t\tlet d: string\n\t\t\t\tif (stroke.length < 4) {\n\t\t\t\t\tconst r = scribble.size / zoom / 2\n\t\t\t\t\tconst { x, y } = last\n\t\t\t\t\td = `M ${x - r},${y} a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 ${-r * 2},0`\n\t\t\t\t} else {\n\t\t\t\t\td = getSvgPathFromPoints(stroke)\n\t\t\t\t}\n\n\t\t\t\tpath = new Path2D(d)\n\t\t\t\tthis._collabScribblePathCache.set(cacheKey, {\n\t\t\t\t\tlen: ptsLen,\n\t\t\t\t\tlastX: last.x,\n\t\t\t\t\tlastY: last.y,\n\t\t\t\t\tzoom,\n\t\t\t\t\tsize: scribble.size,\n\t\t\t\t\ttaper: scribble.taper,\n\t\t\t\t\tstate: scribble.state,\n\t\t\t\t\tpath,\n\t\t\t\t})\n\t\t\t\tif (this._collabScribblePathCache.size > this.options.cacheSize)\n\t\t\t\t\tthis._collabScribblePathCache.clear()\n\t\t\t}\n\n\t\t\tctx.fillStyle = color\n\t\t\tctx.globalAlpha = scribble.color === 'laser' ? 0.5 : 0.1\n\t\t\tctx.fill(path)\n\t\t\tctx.globalAlpha = 1\n\t\t}\n\t}\n}\n"],
  "mappings": "AAAA,SAAS,SAAS,aAAoC,4BAA4B;AAClF,SAAS,iBAAiB;AA2BnB,MAAM,wCAAwC,YAA2C;AAAA,EAC/F,OAAgB,OAAO;AAAA,EACd,UAAU,EAAE,QAAQ,KAAK,YAAY,MAAM,WAAW,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ3D,2BAA2B,oBAAI,IAA4C;AAAA,EAE1E,WAAoB;AAC5B,WAAO,KAAK,OAAO,qCAAqC,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,CAAC;AAAA,EAC7F;AAAA,EAES,cAA+C;AACvD,UAAM,WAA4C,CAAC;AACnD,eAAW,YAAY,KAAK,OAAO,qCAAqC,GAAG;AAC1E,YAAM,EAAE,WAAW,OAAO,OAAO,IAAI;AACrC,iBAAW,YAAY,WAAW;AACjC,iBAAS,KAAK;AAAA,UACb,IAAI,yBAAyB,MAAM,IAAI,SAAS,EAAE;AAAA,UAClD,MAAM;AAAA,UACN,OAAO,EAAE,UAAU,MAAM;AAAA,QAC1B,CAAC;AAAA,MACF;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAES,OAAO,KAA+B,UAAiD;AAC/F,UAAM,OAAO,KAAK,OAAO,aAAa;AAEtC,eAAW,WAAW,UAAU;AAC/B,YAAM,EAAE,UAAU,MAAM,IAAI,QAAQ;AACpC,YAAM,SAAS,SAAS,OAAO;AAC/B,UAAI,CAAC,OAAQ;AAEb,YAAM,OAAO,SAAS,OAAO,SAAS,CAAC;AACvC,YAAM,WAAW,QAAQ;AACzB,YAAM,SAAS,KAAK,yBAAyB,IAAI,QAAQ;AACzD,UAAI;AACJ,UACC,UACA,OAAO,QAAQ,UACf,OAAO,UAAU,KAAK,KACtB,OAAO,UAAU,KAAK,KACtB,OAAO,SAAS,QAChB,OAAO,SAAS,SAAS,QACzB,OAAO,UAAU,SAAS,SAC1B,OAAO,UAAU,SAAS,OACzB;AACD,eAAO,OAAO;AAAA,MACf,OAAO;AACN,cAAM,SAAS,UAAU,SAAS,QAAQ;AAAA,UACzC,MAAM,SAAS,OAAO;AAAA,UACtB,OAAO,EAAE,OAAO,SAAS,OAAO,QAAQ,QAAQ,OAAO;AAAA,UACvD,MAAM,SAAS,UAAU,cAAc,SAAS,UAAU;AAAA,UAC1D,kBAAkB;AAAA,UAClB,YAAY,KAAK,QAAQ;AAAA,QAC1B,CAAC;AAED,YAAI;AACJ,YAAI,OAAO,SAAS,GAAG;AACtB,gBAAM,IAAI,SAAS,OAAO,OAAO;AACjC,gBAAM,EAAE,GAAG,EAAE,IAAI;AACjB,cAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;AAAA,QAC7E,OAAO;AACN,cAAI,qBAAqB,MAAM;AAAA,QAChC;AAEA,eAAO,IAAI,OAAO,CAAC;AACnB,aAAK,yBAAyB,IAAI,UAAU;AAAA,UAC3C,KAAK;AAAA,UACL,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,UACZ;AAAA,UACA,MAAM,SAAS;AAAA,UACf,OAAO,SAAS;AAAA,UAChB,OAAO,SAAS;AAAA,UAChB;AAAA,QACD,CAAC;AACD,YAAI,KAAK,yBAAyB,OAAO,KAAK,QAAQ;AACrD,eAAK,yBAAyB,MAAM;AAAA,MACtC;AAEA,UAAI,YAAY;AAChB,UAAI,cAAc,SAAS,UAAU,UAAU,MAAM;AACrD,UAAI,KAAK,IAAI;AACb,UAAI,cAAc;AAAA,IACnB;AAAA,EACD;AACD;",
  "names": []
}
