UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

8 lines (7 loc) 5.18 kB
{ "version": 3, "sources": ["../../../../../src/lib/editor/managers/SnapManager/SnapManager.ts"], "sourcesContent": ["import { EMPTY_ARRAY, atom, computed } from '@tldraw/state'\nimport { TLFrameShape, TLGroupShape, TLParentId, TLShapeId, isShapeId } from '@tldraw/tlschema'\nimport { Vec, VecLike } from '../../../primitives/Vec'\nimport type { Editor } from '../../Editor'\nimport { BoundsSnaps } from './BoundsSnaps'\nimport { HandleSnaps } from './HandleSnaps'\n\n/** @public */\nexport interface PointsSnapIndicator {\n\tid: string\n\ttype: 'points'\n\tpoints: VecLike[]\n}\n\n/** @public */\nexport interface GapsSnapIndicator {\n\tid: string\n\ttype: 'gaps'\n\tdirection: 'horizontal' | 'vertical'\n\tgaps: Array<{\n\t\tstartEdge: [VecLike, VecLike]\n\t\tendEdge: [VecLike, VecLike]\n\t}>\n}\n\n/** @public */\nexport type SnapIndicator = PointsSnapIndicator | GapsSnapIndicator\n\n/** @public */\nexport interface SnapData {\n\tnudge: Vec\n}\n\n/** @public */\nexport class SnapManager {\n\treadonly shapeBounds: BoundsSnaps\n\treadonly handles: HandleSnaps\n\n\tprivate _snapIndicators = atom<SnapIndicator[] | undefined>('snapLines', undefined)\n\n\tconstructor(public readonly editor: Editor) {\n\t\tthis.shapeBounds = new BoundsSnaps(this)\n\t\tthis.handles = new HandleSnaps(this)\n\t}\n\n\tgetIndicators() {\n\t\treturn this._snapIndicators.get() ?? (EMPTY_ARRAY as SnapIndicator[])\n\t}\n\n\tclearIndicators() {\n\t\tif (this.getIndicators().length) {\n\t\t\tthis._snapIndicators.set(undefined)\n\t\t}\n\t}\n\n\tsetIndicators(indicators: SnapIndicator[]) {\n\t\tthis._snapIndicators.set(indicators)\n\t}\n\n\t@computed getSnapThreshold() {\n\t\treturn 8 / this.editor.getZoomLevel()\n\t}\n\n\t// TODO: make this an incremental derivation\n\t@computed getSnappableShapes(): Set<TLShapeId> {\n\t\tconst { editor } = this\n\t\tconst renderingBounds = editor.getViewportPageBounds()\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\n\t\tconst snappableShapes: Set<TLShapeId> = new Set()\n\n\t\tconst collectSnappableShapesFromParent = (parentId: TLParentId) => {\n\t\t\tif (isShapeId(parentId)) {\n\t\t\t\tconst parent = editor.getShape(parentId)\n\t\t\t\tif (parent && editor.isShapeOfType<TLFrameShape>(parent, 'frame')) {\n\t\t\t\t\tsnappableShapes.add(parentId)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst sortedChildIds = editor.getSortedChildIdsForParent(parentId)\n\t\t\tfor (const childId of sortedChildIds) {\n\t\t\t\t// Skip any selected ids\n\t\t\t\tif (selectedShapeIds.includes(childId)) continue\n\t\t\t\tconst childShape = editor.getShape(childId)\n\t\t\t\tif (!childShape) continue\n\t\t\t\tconst util = editor.getShapeUtil(childShape)\n\t\t\t\t// Skip any shapes that don't allow snapping\n\t\t\t\tif (!util.canSnap(childShape)) continue\n\t\t\t\t// Only consider shapes if they're inside of the viewport page bounds\n\t\t\t\tconst pageBounds = editor.getShapePageBounds(childId)\n\t\t\t\tif (!(pageBounds && renderingBounds.includes(pageBounds))) continue\n\t\t\t\t// Snap to children of groups but not group itself\n\t\t\t\tif (editor.isShapeOfType<TLGroupShape>(childShape, 'group')) {\n\t\t\t\t\tcollectSnappableShapesFromParent(childId)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsnappableShapes.add(childId)\n\t\t\t}\n\t\t}\n\n\t\tcollectSnappableShapesFromParent(this.getCurrentCommonAncestor() ?? editor.getCurrentPageId())\n\n\t\treturn snappableShapes\n\t}\n\n\t// This needs to be external from any expensive work\n\t@computed getCurrentCommonAncestor() {\n\t\treturn this.editor.findCommonAncestor(this.editor.getSelectedShapes())\n\t}\n}\n"], "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,aAAa,MAAM,gBAAgB;AAC5C,SAA4D,iBAAiB;AAG7E,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAsD3B,yBAAC,WAKD,2BAAC,WAyCD,iCAAC;AAvEK,MAAM,YAAY;AAAA,EAMxB,YAA4B,QAAgB;AAAhB;AANtB;AACN,wBAAS;AACT,wBAAS;AAET,wBAAQ,mBAAkB,KAAkC,aAAa,MAAS;AAGjF,SAAK,cAAc,IAAI,YAAY,IAAI;AACvC,SAAK,UAAU,IAAI,YAAY,IAAI;AAAA,EACpC;AAAA,EAEA,gBAAgB;AACf,WAAO,KAAK,gBAAgB,IAAI,KAAM;AAAA,EACvC;AAAA,EAEA,kBAAkB;AACjB,QAAI,KAAK,cAAc,EAAE,QAAQ;AAChC,WAAK,gBAAgB,IAAI,MAAS;AAAA,IACnC;AAAA,EACD;AAAA,EAEA,cAAc,YAA6B;AAC1C,SAAK,gBAAgB,IAAI,UAAU;AAAA,EACpC;AAAA,EAEU,mBAAmB;AAC5B,WAAO,IAAI,KAAK,OAAO,aAAa;AAAA,EACrC;AAAA,EAGU,qBAAqC;AAC9C,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,kBAAkB,OAAO,sBAAsB;AACrD,UAAM,mBAAmB,OAAO,oBAAoB;AAEpD,UAAM,kBAAkC,oBAAI,IAAI;AAEhD,UAAM,mCAAmC,CAAC,aAAyB;AAClE,UAAI,UAAU,QAAQ,GAAG;AACxB,cAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,YAAI,UAAU,OAAO,cAA4B,QAAQ,OAAO,GAAG;AAClE,0BAAgB,IAAI,QAAQ;AAAA,QAC7B;AAAA,MACD;AACA,YAAM,iBAAiB,OAAO,2BAA2B,QAAQ;AACjE,iBAAW,WAAW,gBAAgB;AAErC,YAAI,iBAAiB,SAAS,OAAO,EAAG;AACxC,cAAM,aAAa,OAAO,SAAS,OAAO;AAC1C,YAAI,CAAC,WAAY;AACjB,cAAM,OAAO,OAAO,aAAa,UAAU;AAE3C,YAAI,CAAC,KAAK,QAAQ,UAAU,EAAG;AAE/B,cAAM,aAAa,OAAO,mBAAmB,OAAO;AACpD,YAAI,EAAE,cAAc,gBAAgB,SAAS,UAAU,GAAI;AAE3D,YAAI,OAAO,cAA4B,YAAY,OAAO,GAAG;AAC5D,2CAAiC,OAAO;AACxC;AAAA,QACD;AACA,wBAAgB,IAAI,OAAO;AAAA,MAC5B;AAAA,IACD;AAEA,qCAAiC,KAAK,yBAAyB,KAAK,OAAO,iBAAiB,CAAC;AAE7F,WAAO;AAAA,EACR;AAAA,EAGU,2BAA2B;AACpC,WAAO,KAAK,OAAO,mBAAmB,KAAK,OAAO,kBAAkB,CAAC;AAAA,EACtE;AACD;AA1EO;AAyBI,gDAAV,uBAzBY;AA8BF,kDAAV,yBA9BY;AAuEF,wDAAV,+BAvEY;AAAN,2BAAM;", "names": [] }