@tldraw/editor 3.13.0-canary.8e04030e54fe → 3.13.0-canary.8f8ae1660cdb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +74 -96
- package/dist-cjs/index.js +7 -22
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +3 -5
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +16 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Mat.js +1 -1
- package/dist-cjs/lib/primitives/Mat.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +20 -0
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +91 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +55 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/utils/debug-flags.js +5 -2
- package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +74 -96
- package/dist-esm/index.mjs +9 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +3 -5
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +16 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Mat.mjs +1 -1
- package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +20 -0
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +92 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +55 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/utils/debug-flags.mjs +5 -2
- package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +29 -0
- package/package.json +7 -7
- package/src/index.ts +16 -31
- package/src/lib/editor/Editor.test.ts +1 -1
- package/src/lib/editor/Editor.ts +3 -5
- package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +0 -1
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
- package/src/lib/primitives/Box.ts +20 -0
- package/src/lib/primitives/Mat.ts +5 -4
- package/src/lib/primitives/Vec.ts +23 -0
- package/src/lib/primitives/geometry/Arc2d.ts +5 -5
- package/src/lib/primitives/geometry/Circle2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
- package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
- package/src/lib/primitives/geometry/Edge2d.ts +3 -3
- package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
- package/src/lib/primitives/geometry/Geometry2d.test.ts +42 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +123 -35
- package/src/lib/primitives/geometry/Group2d.ts +70 -7
- package/src/lib/primitives/geometry/Point2d.ts +2 -2
- package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
- package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
- package/src/lib/test/currentToolIdMask.test.ts +1 -1
- package/src/lib/test/user.test.ts +1 -1
- package/src/lib/utils/debug-flags.ts +7 -2
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/primitives/geometry/Stadium2d.ts"],
|
|
4
|
-
"sourcesContent": ["import { Box } from '../Box'\nimport { Vec } from '../Vec'\nimport { PI } from '../utils'\nimport { Arc2d } from './Arc2d'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Stadium2d extends Geometry2d {\n\tw: number\n\th: number\n\n\ta: Arc2d\n\tb: Edge2d\n\tc: Arc2d\n\td: Edge2d\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width: w, height: h } = config\n\t\tthis.w = w\n\t\tthis.h = h\n\n\t\tif (h > w) {\n\t\t\tconst r = w / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(0, r),\n\t\t\t\tend: new Vec(w, r),\n\t\t\t\tcenter: new Vec(w / 2, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w, h - r),\n\t\t\t\tend: new Vec(0, h - r),\n\t\t\t\tcenter: new Vec(w / 2, h - r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) })\n\t\t} else {\n\t\t\tconst r = h / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(r, h),\n\t\t\t\tend: new Vec(r, 0),\n\t\t\t\tcenter: new Vec(r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w - r, 0),\n\t\t\t\tend: new Vec(w - r, h),\n\t\t\t\tcenter: new Vec(w - r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) })\n\t\t}\n\t}\n\n\tnearestPoint(A:
|
|
5
|
-
"mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,
|
|
4
|
+
"sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI } from '../utils'\nimport { Arc2d } from './Arc2d'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Stadium2d extends Geometry2d {\n\tw: number\n\th: number\n\n\ta: Arc2d\n\tb: Edge2d\n\tc: Arc2d\n\td: Edge2d\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width: w, height: h } = config\n\t\tthis.w = w\n\t\tthis.h = h\n\n\t\tif (h > w) {\n\t\t\tconst r = w / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(0, r),\n\t\t\t\tend: new Vec(w, r),\n\t\t\t\tcenter: new Vec(w / 2, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w, h - r),\n\t\t\t\tend: new Vec(0, h - r),\n\t\t\t\tcenter: new Vec(w / 2, h - r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) })\n\t\t} else {\n\t\t\tconst r = h / 2\n\t\t\tthis.a = new Arc2d({\n\t\t\t\tstart: new Vec(r, h),\n\t\t\t\tend: new Vec(r, 0),\n\t\t\t\tcenter: new Vec(r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) })\n\t\t\tthis.c = new Arc2d({\n\t\t\t\tstart: new Vec(w - r, 0),\n\t\t\t\tend: new Vec(w - r, h),\n\t\t\t\tcenter: new Vec(w - r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis.d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) })\n\t\t}\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet _d: number\n\t\tlet p: Vec\n\n\t\tconst { a, b, c, d } = this\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tp = part.nearestPoint(A)\n\t\t\t_d = Vec.Dist2(p, A)\n\t\t\tif (_d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = _d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetVertices() {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].reduce<Vec[]>((a, p) => {\n\t\t\ta.push(...p.vertices)\n\t\t\treturn a\n\t\t}, [])\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this.w, this.h)\n\t}\n\n\tgetLength() {\n\t\tconst { h, w } = this\n\t\tif (h > w) return (PI * (w / 2) + (h - w)) * 2\n\t\telse return (PI * (h / 2) + (w - h)) * 2\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { a, b, c, d } = this\n\t\treturn [a, b, c, d].map((p, i) => p.getSvgPathData(i === 0)).join(' ') + ' Z'\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["a"]
|
|
7
7
|
}
|
|
@@ -41,7 +41,8 @@ const debugFlags = {
|
|
|
41
41
|
debugGeometry: createDebugValue("debugGeometry", { defaults: { all: false } }),
|
|
42
42
|
hideShapes: createDebugValue("hideShapes", { defaults: { all: false } }),
|
|
43
43
|
editOnType: createDebugValue("editOnType", { defaults: { all: false } }),
|
|
44
|
-
a11y: createDebugValue("a11y", { defaults: { all: false } })
|
|
44
|
+
a11y: createDebugValue("a11y", { defaults: { all: false } }),
|
|
45
|
+
debugElbowArrows: createDebugValue("debugElbowArrows", { defaults: { all: false } })
|
|
45
46
|
};
|
|
46
47
|
if (typeof Element !== "undefined") {
|
|
47
48
|
const nativeElementRemoveChild = Element.prototype.removeChild;
|
|
@@ -91,7 +92,9 @@ function createDebugValueBase(def) {
|
|
|
91
92
|
configurable: true
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
|
-
return Object.assign(valueAtom, def
|
|
95
|
+
return Object.assign(valueAtom, def, {
|
|
96
|
+
reset: () => valueAtom.set(defaultValue)
|
|
97
|
+
});
|
|
95
98
|
}
|
|
96
99
|
function getStoredInitialValue(name) {
|
|
97
100
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/debug-flags.ts"],
|
|
4
|
-
"sourcesContent": ["import { Atom, atom, react } from '@tldraw/state'\nimport { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from '@tldraw/utils'\n\n// --- 1. DEFINE ---\n//\n// Define your debug values and feature flags here. Use `createDebugValue` to\n// create an arbitrary value with defaults for production, staging, and\n// development. Use `createFeatureFlag` to create a boolean flag which will be\n// `true` by default in development and staging, and `false` in production.\n/** @internal */\nexport const featureFlags: Record<string, DebugFlag<boolean>> = {}\n\n/** @internal */\nexport const pointerCaptureTrackingObject = createDebugValue(\n\t'pointerCaptureTrackingObject',\n\t// ideally we wouldn't store this mutable value in an atom but it's not\n\t// a big deal for debug values\n\t{\n\t\tdefaults: { all: new Map<Element, number>() },\n\t\tshouldStoreForSession: false,\n\t}\n)\n\n/** @internal */\nexport const debugFlags = {\n\t// --- DEBUG VALUES ---\n\tlogPreventDefaults: createDebugValue('logPreventDefaults', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogPointerCaptures: createDebugValue('logPointerCaptures', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogElementRemoves: createDebugValue('logElementRemoves', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugSvg: createDebugValue('debugSvg', {\n\t\tdefaults: { all: false },\n\t}),\n\tshowFps: createDebugValue('showFps', {\n\t\tdefaults: { all: false },\n\t}),\n\tmeasurePerformance: createDebugValue('measurePerformance', { defaults: { all: false } }),\n\tthrowToBlob: createDebugValue('throwToBlob', {\n\t\tdefaults: { all: false },\n\t}),\n\treconnectOnPing: createDebugValue('reconnectOnPing', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugCursors: createDebugValue('debugCursors', {\n\t\tdefaults: { all: false },\n\t}),\n\tforceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),\n\tdebugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),\n\thideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),\n\teditOnType: createDebugValue('editOnType', { defaults: { all: false } }),\n\ta11y: createDebugValue('a11y', { defaults: { all: false } }),\n} as const\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawLog(message: any): void\n\t}\n}\n\n// --- 2. USE ---\n// In normal code, read from debug flags directly by calling .value on them:\n// if (debugFlags.preventDefaultLogging.value) { ... }\n//\n// In react, wrap your reads in `useValue` (or your component in `track`)\n// so they react to changes:\n// const shouldLog = useValue(debugFlags.preventDefaultLogging)\n\n// --- 3. GET FUNKY ---\n// If you need to do fun stuff like monkey-patching in response to flag changes,\n// add that here. Make sure you wrap your code in `react` so it runs\n// automatically when values change!\n\nif (typeof Element !== 'undefined') {\n\tconst nativeElementRemoveChild = Element.prototype.removeChild\n\treact('element removal logging', () => {\n\t\tif (debugFlags.logElementRemoves.get()) {\n\t\t\tElement.prototype.removeChild = function <T extends Node>(this: any, child: Node): T {\n\t\t\t\tconsole.warn('[tldraw] removing child:', child)\n\t\t\t\treturn nativeElementRemoveChild.call(this, child) as T\n\t\t\t}\n\t\t} else {\n\t\t\tElement.prototype.removeChild = nativeElementRemoveChild\n\t\t}\n\t})\n}\n\n// --- IMPLEMENTATION ---\n// you probably don't need to read this if you're just using the debug values system\nfunction createDebugValue<T>(\n\tname: string,\n\t{\n\t\tdefaults,\n\t\tshouldStoreForSession = true,\n\t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n) {\n\treturn createDebugValueBase({\n\t\tname,\n\t\tdefaults,\n\t\tshouldStoreForSession,\n\t})\n}\n\n// function createFeatureFlag<T>(\n// \tname: string,\n// \t{\n// \t\tdefaults,\n// \t\tshouldStoreForSession = true,\n// \t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n// ) {\n// \treturn createDebugValueBase({\n// \t\tname,\n// \t\tdefaults,\n// \t\tshouldStoreForSession,\n// \t})\n// }\n\nfunction createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {\n\tconst defaultValue = getDefaultValue(def)\n\tconst storedValue = def.shouldStoreForSession\n\t\t? (getStoredInitialValue(def.name) as T | null)\n\t\t: null\n\tconst valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue)\n\n\tif (typeof window !== 'undefined') {\n\t\tif (def.shouldStoreForSession) {\n\t\t\treact(`debug:${def.name}`, () => {\n\t\t\t\tconst currentValue = valueAtom.get()\n\t\t\t\tif (currentValue === defaultValue) {\n\t\t\t\t\tdeleteFromSessionStorage(`tldraw_debug:${def.name}`)\n\t\t\t\t} else {\n\t\t\t\t\tsetInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue))\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tObject.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {\n\t\t\tget() {\n\t\t\t\treturn valueAtom.get()\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalueAtom.set(newValue)\n\t\t\t},\n\t\t\tconfigurable: true,\n\t\t})\n\t}\n\n\treturn Object.assign(valueAtom, def)\n}\n\nfunction getStoredInitialValue(name: string) {\n\ttry {\n\t\treturn JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? 'null')\n\t} catch {\n\t\treturn null\n\t}\n}\n\n// process.env might not be defined, but we can't access it using optional\n// chaining because some bundlers search for `process.env.SOMETHING` as a string\n// and replace it with its value.\nfunction readEnv(fn: () => string | undefined) {\n\ttry {\n\t\treturn fn()\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getDefaultValue<T>(def: DebugFlagDef<T>): T {\n\tconst env =\n\t\treadEnv(() => process.env.TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ??\n\t\t// default to production because if we don't have one of these, this is probably a library use\n\t\t'production'\n\n\tswitch (env) {\n\t\tcase 'production':\n\t\t\treturn def.defaults.production ?? def.defaults.all\n\t\tcase 'preview':\n\t\tcase 'staging':\n\t\t\treturn def.defaults.staging ?? def.defaults.all\n\t\tdefault:\n\t\t\treturn def.defaults.development ?? def.defaults.all\n\t}\n}\n\n/** @internal */\nexport interface DebugFlagDefaults<T> {\n\tdevelopment?: T\n\tstaging?: T\n\tproduction?: T\n\tall: T\n}\n\n/** @internal */\nexport interface DebugFlagDef<T> {\n\tname: string\n\tdefaults: DebugFlagDefaults<T>\n\tshouldStoreForSession: boolean\n}\n\n/** @internal */\nexport
|
|
5
|
-
"mappings": "AAAA,SAAe,MAAM,aAAa;AAClC,SAAS,0BAA0B,uBAAuB,2BAA2B;AAS9E,MAAM,eAAmD,CAAC;AAG1D,MAAM,+BAA+B;AAAA,EAC3C;AAAA;AAAA;AAAA,EAGA;AAAA,IACC,UAAU,EAAE,KAAK,oBAAI,IAAqB,EAAE;AAAA,IAC5C,uBAAuB;AAAA,EACxB;AACD;AAGO,MAAM,aAAa;AAAA;AAAA,EAEzB,oBAAoB,iBAAiB,sBAAsB;AAAA,IAC1D,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,oBAAoB,iBAAiB,sBAAsB;AAAA,IAC1D,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,mBAAmB,iBAAiB,qBAAqB;AAAA,IACxD,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,UAAU,iBAAiB,YAAY;AAAA,IACtC,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,SAAS,iBAAiB,WAAW;AAAA,IACpC,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,oBAAoB,iBAAiB,sBAAsB,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;AAAA,EACvF,aAAa,iBAAiB,eAAe;AAAA,IAC5C,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,iBAAiB,iBAAiB,mBAAmB;AAAA,IACpD,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,cAAc,iBAAiB,gBAAgB;AAAA,IAC9C,UAAU,EAAE,KAAK,MAAM;AAAA,EACxB,CAAC;AAAA,EACD,WAAW,iBAAiB,mBAAmB,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;AAAA,EAC3E,eAAe,iBAAiB,iBAAiB,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;AAAA,EAC7E,YAAY,iBAAiB,cAAc,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;AAAA,EACvE,YAAY,iBAAiB,cAAc,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;AAAA,EACvE,MAAM,iBAAiB,QAAQ,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;
|
|
4
|
+
"sourcesContent": ["import { Atom, atom, react } from '@tldraw/state'\nimport { deleteFromSessionStorage, getFromSessionStorage, setInSessionStorage } from '@tldraw/utils'\n\n// --- 1. DEFINE ---\n//\n// Define your debug values and feature flags here. Use `createDebugValue` to\n// create an arbitrary value with defaults for production, staging, and\n// development. Use `createFeatureFlag` to create a boolean flag which will be\n// `true` by default in development and staging, and `false` in production.\n/** @internal */\nexport const featureFlags: Record<string, DebugFlag<boolean>> = {}\n\n/** @internal */\nexport const pointerCaptureTrackingObject = createDebugValue(\n\t'pointerCaptureTrackingObject',\n\t// ideally we wouldn't store this mutable value in an atom but it's not\n\t// a big deal for debug values\n\t{\n\t\tdefaults: { all: new Map<Element, number>() },\n\t\tshouldStoreForSession: false,\n\t}\n)\n\n/** @internal */\nexport const debugFlags = {\n\t// --- DEBUG VALUES ---\n\tlogPreventDefaults: createDebugValue('logPreventDefaults', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogPointerCaptures: createDebugValue('logPointerCaptures', {\n\t\tdefaults: { all: false },\n\t}),\n\tlogElementRemoves: createDebugValue('logElementRemoves', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugSvg: createDebugValue('debugSvg', {\n\t\tdefaults: { all: false },\n\t}),\n\tshowFps: createDebugValue('showFps', {\n\t\tdefaults: { all: false },\n\t}),\n\tmeasurePerformance: createDebugValue('measurePerformance', { defaults: { all: false } }),\n\tthrowToBlob: createDebugValue('throwToBlob', {\n\t\tdefaults: { all: false },\n\t}),\n\treconnectOnPing: createDebugValue('reconnectOnPing', {\n\t\tdefaults: { all: false },\n\t}),\n\tdebugCursors: createDebugValue('debugCursors', {\n\t\tdefaults: { all: false },\n\t}),\n\tforceSrgb: createDebugValue('forceSrgbColors', { defaults: { all: false } }),\n\tdebugGeometry: createDebugValue('debugGeometry', { defaults: { all: false } }),\n\thideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),\n\teditOnType: createDebugValue('editOnType', { defaults: { all: false } }),\n\ta11y: createDebugValue('a11y', { defaults: { all: false } }),\n\tdebugElbowArrows: createDebugValue('debugElbowArrows', { defaults: { all: false } }),\n} as const\n\ndeclare global {\n\tinterface Window {\n\t\ttldrawLog(message: any): void\n\t}\n}\n\n// --- 2. USE ---\n// In normal code, read from debug flags directly by calling .value on them:\n// if (debugFlags.preventDefaultLogging.value) { ... }\n//\n// In react, wrap your reads in `useValue` (or your component in `track`)\n// so they react to changes:\n// const shouldLog = useValue(debugFlags.preventDefaultLogging)\n\n// --- 3. GET FUNKY ---\n// If you need to do fun stuff like monkey-patching in response to flag changes,\n// add that here. Make sure you wrap your code in `react` so it runs\n// automatically when values change!\n\nif (typeof Element !== 'undefined') {\n\tconst nativeElementRemoveChild = Element.prototype.removeChild\n\treact('element removal logging', () => {\n\t\tif (debugFlags.logElementRemoves.get()) {\n\t\t\tElement.prototype.removeChild = function <T extends Node>(this: any, child: Node): T {\n\t\t\t\tconsole.warn('[tldraw] removing child:', child)\n\t\t\t\treturn nativeElementRemoveChild.call(this, child) as T\n\t\t\t}\n\t\t} else {\n\t\t\tElement.prototype.removeChild = nativeElementRemoveChild\n\t\t}\n\t})\n}\n\n// --- IMPLEMENTATION ---\n// you probably don't need to read this if you're just using the debug values system\nfunction createDebugValue<T>(\n\tname: string,\n\t{\n\t\tdefaults,\n\t\tshouldStoreForSession = true,\n\t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n) {\n\treturn createDebugValueBase({\n\t\tname,\n\t\tdefaults,\n\t\tshouldStoreForSession,\n\t})\n}\n\n// function createFeatureFlag<T>(\n// \tname: string,\n// \t{\n// \t\tdefaults,\n// \t\tshouldStoreForSession = true,\n// \t}: { defaults: DebugFlagDefaults<T>; shouldStoreForSession?: boolean }\n// ) {\n// \treturn createDebugValueBase({\n// \t\tname,\n// \t\tdefaults,\n// \t\tshouldStoreForSession,\n// \t})\n// }\n\nfunction createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {\n\tconst defaultValue = getDefaultValue(def)\n\tconst storedValue = def.shouldStoreForSession\n\t\t? (getStoredInitialValue(def.name) as T | null)\n\t\t: null\n\tconst valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue)\n\n\tif (typeof window !== 'undefined') {\n\t\tif (def.shouldStoreForSession) {\n\t\t\treact(`debug:${def.name}`, () => {\n\t\t\t\tconst currentValue = valueAtom.get()\n\t\t\t\tif (currentValue === defaultValue) {\n\t\t\t\t\tdeleteFromSessionStorage(`tldraw_debug:${def.name}`)\n\t\t\t\t} else {\n\t\t\t\t\tsetInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue))\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tObject.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l) => l.toUpperCase())}`, {\n\t\t\tget() {\n\t\t\t\treturn valueAtom.get()\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalueAtom.set(newValue)\n\t\t\t},\n\t\t\tconfigurable: true,\n\t\t})\n\t}\n\n\treturn Object.assign(valueAtom, def, {\n\t\treset: () => valueAtom.set(defaultValue),\n\t})\n}\n\nfunction getStoredInitialValue(name: string) {\n\ttry {\n\t\treturn JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? 'null')\n\t} catch {\n\t\treturn null\n\t}\n}\n\n// process.env might not be defined, but we can't access it using optional\n// chaining because some bundlers search for `process.env.SOMETHING` as a string\n// and replace it with its value.\nfunction readEnv(fn: () => string | undefined) {\n\ttry {\n\t\treturn fn()\n\t} catch {\n\t\treturn null\n\t}\n}\n\nfunction getDefaultValue<T>(def: DebugFlagDef<T>): T {\n\tconst env =\n\t\treadEnv(() => process.env.TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.VERCEL_PUBLIC_TLDRAW_ENV) ??\n\t\treadEnv(() => process.env.NEXT_PUBLIC_TLDRAW_ENV) ??\n\t\t// default to production because if we don't have one of these, this is probably a library use\n\t\t'production'\n\n\tswitch (env) {\n\t\tcase 'production':\n\t\t\treturn def.defaults.production ?? def.defaults.all\n\t\tcase 'preview':\n\t\tcase 'staging':\n\t\t\treturn def.defaults.staging ?? def.defaults.all\n\t\tdefault:\n\t\t\treturn def.defaults.development ?? def.defaults.all\n\t}\n}\n\n/** @internal */\nexport interface DebugFlagDefaults<T> {\n\tdevelopment?: T\n\tstaging?: T\n\tproduction?: T\n\tall: T\n}\n\n/** @internal */\nexport interface DebugFlagDef<T> {\n\tname: string\n\tdefaults: DebugFlagDefaults<T>\n\tshouldStoreForSession: boolean\n}\n\n/** @internal */\nexport interface DebugFlag<T> extends DebugFlagDef<T>, Atom<T> {\n\treset(): void\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "3.13.0-canary.
|
|
1
|
+
const version = "3.13.0-canary.8f8ae1660cdb";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2024-09-13T14:36:29.063Z",
|
|
4
|
-
minor: "2025-05-
|
|
5
|
-
patch: "2025-05-
|
|
4
|
+
minor: "2025-05-08T11:53:57.810Z",
|
|
5
|
+
patch: "2025-05-08T11:53:57.810Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.13.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.13.0-canary.8f8ae1660cdb'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-05-08T11:53:57.810Z',\n\tpatch: '2025-05-08T11:53:57.810Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/editor.css
CHANGED
|
@@ -600,6 +600,31 @@ input,
|
|
|
600
600
|
}
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
+
/* --------------------- Arrow Hints -------------------- */
|
|
604
|
+
|
|
605
|
+
.tl-arrow-hint-handle {
|
|
606
|
+
fill: var(--color-selected-contrast);
|
|
607
|
+
stroke: var(--color-selection-stroke);
|
|
608
|
+
stroke-width: calc(1.5px * var(--tl-scale));
|
|
609
|
+
r: calc(4px * var(--tl-scale));
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.tl-arrow-hint-snap {
|
|
613
|
+
stroke: transparent;
|
|
614
|
+
fill: var(--color-selection-fill);
|
|
615
|
+
r: calc(12px * var(--tl-scale));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.tl-arrow-hint-snap__none,
|
|
619
|
+
.tl-arrow-hint-snap__center,
|
|
620
|
+
.tl-arrow-hint-snap__axis {
|
|
621
|
+
display: none;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.tl-arrow-hint-snap__edge {
|
|
625
|
+
r: calc(8px * var(--tl-scale));
|
|
626
|
+
}
|
|
627
|
+
|
|
603
628
|
/* ------------------ Bounds Detail ----------------- */
|
|
604
629
|
|
|
605
630
|
.tl-image,
|
|
@@ -969,6 +994,8 @@ input,
|
|
|
969
994
|
|
|
970
995
|
.tl-rich-text p {
|
|
971
996
|
margin: 0;
|
|
997
|
+
/* Depending on the extensions, <p> tags can be empty, without a <br />. */
|
|
998
|
+
min-height: 1lh;
|
|
972
999
|
}
|
|
973
1000
|
|
|
974
1001
|
.tl-rich-text ul,
|
|
@@ -976,6 +1003,8 @@ input,
|
|
|
976
1003
|
text-align: left;
|
|
977
1004
|
margin: 0;
|
|
978
1005
|
padding-left: 3.25ch;
|
|
1006
|
+
/* Some resets, like Tailwind, nix the list styling. */
|
|
1007
|
+
list-style: revert;
|
|
979
1008
|
}
|
|
980
1009
|
|
|
981
1010
|
.tl-rich-text ol:has(> li:nth-child(10)) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "A tiny little drawing app (editor).",
|
|
4
|
-
"version": "3.13.0-canary.
|
|
4
|
+
"version": "3.13.0-canary.8f8ae1660cdb",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"@tiptap/core": "^2.9.1",
|
|
49
49
|
"@tiptap/pm": "^2.9.1",
|
|
50
50
|
"@tiptap/react": "^2.9.1",
|
|
51
|
-
"@tldraw/state": "3.13.0-canary.
|
|
52
|
-
"@tldraw/state-react": "3.13.0-canary.
|
|
53
|
-
"@tldraw/store": "3.13.0-canary.
|
|
54
|
-
"@tldraw/tlschema": "3.13.0-canary.
|
|
55
|
-
"@tldraw/utils": "3.13.0-canary.
|
|
56
|
-
"@tldraw/validate": "3.13.0-canary.
|
|
51
|
+
"@tldraw/state": "3.13.0-canary.8f8ae1660cdb",
|
|
52
|
+
"@tldraw/state-react": "3.13.0-canary.8f8ae1660cdb",
|
|
53
|
+
"@tldraw/store": "3.13.0-canary.8f8ae1660cdb",
|
|
54
|
+
"@tldraw/tlschema": "3.13.0-canary.8f8ae1660cdb",
|
|
55
|
+
"@tldraw/utils": "3.13.0-canary.8f8ae1660cdb",
|
|
56
|
+
"@tldraw/validate": "3.13.0-canary.8f8ae1660cdb",
|
|
57
57
|
"@types/core-js": "^2.5.8",
|
|
58
58
|
"@use-gesture/react": "^10.3.1",
|
|
59
59
|
"classnames": "^2.5.1",
|
package/src/index.ts
CHANGED
|
@@ -4,37 +4,11 @@ import 'core-js/stable/array/flat-map.js'
|
|
|
4
4
|
import 'core-js/stable/array/flat.js'
|
|
5
5
|
import 'core-js/stable/string/at.js'
|
|
6
6
|
import 'core-js/stable/string/replace-all.js'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
react,
|
|
13
|
-
transact,
|
|
14
|
-
transaction,
|
|
15
|
-
whyAmIRunning,
|
|
16
|
-
type Atom,
|
|
17
|
-
type Signal,
|
|
18
|
-
} from '@tldraw/state'
|
|
19
|
-
export {
|
|
20
|
-
track,
|
|
21
|
-
useAtom,
|
|
22
|
-
useComputed,
|
|
23
|
-
useQuickReactor,
|
|
24
|
-
useReactor,
|
|
25
|
-
useStateTracking,
|
|
26
|
-
useValue,
|
|
27
|
-
} from '@tldraw/state-react'
|
|
28
|
-
export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
|
|
29
|
-
export {
|
|
30
|
-
getFontsFromRichText,
|
|
31
|
-
type RichTextFontVisitor,
|
|
32
|
-
type RichTextFontVisitorState,
|
|
33
|
-
type TLTextOptions,
|
|
34
|
-
type TiptapEditor,
|
|
35
|
-
type TiptapNode,
|
|
36
|
-
} from './lib/utils/richText'
|
|
37
|
-
export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line local/no-export-star
|
|
9
|
+
export * from '@tldraw/state'
|
|
10
|
+
// eslint-disable-next-line local/no-export-star
|
|
11
|
+
export * from '@tldraw/state-react'
|
|
38
12
|
// eslint-disable-next-line local/no-export-star
|
|
39
13
|
export * from '@tldraw/store'
|
|
40
14
|
// eslint-disable-next-line local/no-export-star
|
|
@@ -43,6 +17,7 @@ export * from '@tldraw/tlschema'
|
|
|
43
17
|
export * from '@tldraw/utils'
|
|
44
18
|
// eslint-disable-next-line local/no-export-star
|
|
45
19
|
export * from '@tldraw/validate'
|
|
20
|
+
|
|
46
21
|
export {
|
|
47
22
|
ErrorScreen,
|
|
48
23
|
LoadingScreen,
|
|
@@ -212,6 +187,7 @@ export {
|
|
|
212
187
|
export { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'
|
|
213
188
|
export { getPerfectDashProps } from './lib/editor/shapes/shared/getPerfectDashProps'
|
|
214
189
|
export { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'
|
|
190
|
+
export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
|
|
215
191
|
export { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'
|
|
216
192
|
export { maybeSnapToGrid } from './lib/editor/tools/BaseBoxShapeTool/children/Pointing'
|
|
217
193
|
export { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'
|
|
@@ -459,12 +435,21 @@ export { hardResetEditor } from './lib/utils/hardResetEditor'
|
|
|
459
435
|
export { isAccelKey } from './lib/utils/keyboard'
|
|
460
436
|
export { normalizeWheel } from './lib/utils/normalizeWheel'
|
|
461
437
|
export { refreshPage } from './lib/utils/refreshPage'
|
|
438
|
+
export {
|
|
439
|
+
getFontsFromRichText,
|
|
440
|
+
type RichTextFontVisitor,
|
|
441
|
+
type RichTextFontVisitorState,
|
|
442
|
+
type TLTextOptions,
|
|
443
|
+
type TiptapEditor,
|
|
444
|
+
type TiptapNode,
|
|
445
|
+
} from './lib/utils/richText'
|
|
462
446
|
export {
|
|
463
447
|
applyRotationToSnapshotShapes,
|
|
464
448
|
getRotationSnapshot,
|
|
465
449
|
type TLRotationSnapshot,
|
|
466
450
|
} from './lib/utils/rotation'
|
|
467
451
|
export { runtime, setRuntimeOverrides } from './lib/utils/runtime'
|
|
452
|
+
export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
|
|
468
453
|
export { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'
|
|
469
454
|
export { hardReset } from './lib/utils/sync/hardReset'
|
|
470
455
|
export { uniq } from './lib/utils/uniq'
|
|
@@ -52,7 +52,7 @@ beforeEach(() => {
|
|
|
52
52
|
shapeUtils: [CustomShape],
|
|
53
53
|
bindingUtils: [],
|
|
54
54
|
tools: [],
|
|
55
|
-
store: createTLStore({ shapeUtils: [CustomShape] }),
|
|
55
|
+
store: createTLStore({ shapeUtils: [CustomShape], bindingUtils: [] }),
|
|
56
56
|
getContainer: () => document.body,
|
|
57
57
|
})
|
|
58
58
|
editor.setCameraOptions({ isLocked: true })
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -10343,12 +10343,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10343
10343
|
if (this.inputs.isPanning && this.inputs.isPointing) {
|
|
10344
10344
|
// Handle spacebar / middle mouse button panning
|
|
10345
10345
|
const { currentScreenPoint, previousScreenPoint } = this.inputs
|
|
10346
|
-
const { panSpeed } = cameraOptions
|
|
10347
10346
|
const offset = Vec.Sub(currentScreenPoint, previousScreenPoint)
|
|
10348
|
-
this.setCamera(
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
)
|
|
10347
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
10348
|
+
immediate: true,
|
|
10349
|
+
})
|
|
10352
10350
|
this.maybeTrackPerformance('Panning')
|
|
10353
10351
|
return
|
|
10354
10352
|
}
|
|
@@ -4,15 +4,15 @@ import { TLDefaultDashStyle } from '@tldraw/tlschema'
|
|
|
4
4
|
export function getPerfectDashProps(
|
|
5
5
|
totalLength: number,
|
|
6
6
|
strokeWidth: number,
|
|
7
|
-
opts
|
|
8
|
-
style
|
|
9
|
-
snap
|
|
10
|
-
end
|
|
11
|
-
start
|
|
12
|
-
lengthRatio
|
|
13
|
-
closed
|
|
14
|
-
forceSolid
|
|
15
|
-
}
|
|
7
|
+
opts: {
|
|
8
|
+
style?: TLDefaultDashStyle
|
|
9
|
+
snap?: number
|
|
10
|
+
end?: 'skip' | 'outset' | 'none'
|
|
11
|
+
start?: 'skip' | 'outset' | 'none'
|
|
12
|
+
lengthRatio?: number
|
|
13
|
+
closed?: boolean
|
|
14
|
+
forceSolid?: boolean
|
|
15
|
+
} = {}
|
|
16
16
|
): {
|
|
17
17
|
strokeDasharray: string
|
|
18
18
|
strokeDashoffset: string
|
|
@@ -57,6 +57,11 @@ export class Box {
|
|
|
57
57
|
this.x = n
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
61
|
+
get left() {
|
|
62
|
+
return this.x
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
// eslint-disable-next-line no-restricted-syntax
|
|
61
66
|
get midX() {
|
|
62
67
|
return this.x + this.w / 2
|
|
@@ -67,6 +72,11 @@ export class Box {
|
|
|
67
72
|
return this.x + this.w
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
76
|
+
get right() {
|
|
77
|
+
return this.x + this.w
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
// eslint-disable-next-line no-restricted-syntax
|
|
71
81
|
get minY() {
|
|
72
82
|
return this.y
|
|
@@ -77,6 +87,11 @@ export class Box {
|
|
|
77
87
|
this.y = n
|
|
78
88
|
}
|
|
79
89
|
|
|
90
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
91
|
+
get top() {
|
|
92
|
+
return this.y
|
|
93
|
+
}
|
|
94
|
+
|
|
80
95
|
// eslint-disable-next-line no-restricted-syntax
|
|
81
96
|
get midY() {
|
|
82
97
|
return this.y + this.h / 2
|
|
@@ -87,6 +102,11 @@ export class Box {
|
|
|
87
102
|
return this.y + this.h
|
|
88
103
|
}
|
|
89
104
|
|
|
105
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
106
|
+
get bottom() {
|
|
107
|
+
return this.y + this.h
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
// eslint-disable-next-line no-restricted-syntax
|
|
91
111
|
get width() {
|
|
92
112
|
return this.w
|
|
@@ -157,12 +157,13 @@ export class Mat {
|
|
|
157
157
|
return Mat.Compose(Mat.Translate(cx, cy!), rotationMatrix, Mat.Translate(-cx, -cy!))
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
static Scale(x: number, y: number):
|
|
161
|
-
static Scale(x: number, y: number, cx: number, cy: number):
|
|
162
|
-
static Scale(x: number, y: number, cx?: number, cy?: number):
|
|
160
|
+
static Scale(x: number, y: number): Mat
|
|
161
|
+
static Scale(x: number, y: number, cx: number, cy: number): Mat
|
|
162
|
+
static Scale(x: number, y: number, cx?: number, cy?: number): Mat {
|
|
163
163
|
const scaleMatrix = new Mat(x, 0, 0, y, 0, 0)
|
|
164
164
|
if (cx === undefined) return scaleMatrix
|
|
165
|
-
|
|
165
|
+
|
|
166
|
+
return Mat.Translate(cx, cy!).multiply(scaleMatrix).translate(-cx, -cy!)
|
|
166
167
|
}
|
|
167
168
|
static Multiply(m1: MatModel, m2: MatModel): MatModel {
|
|
168
169
|
return {
|
|
@@ -319,6 +319,11 @@ export class Vec {
|
|
|
319
319
|
return ((A.y - B.y) ** 2 + (A.x - B.x) ** 2) ** 0.5
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
// Get the Manhattan distance between two points.
|
|
323
|
+
static ManhattanDist(A: VecLike, B: VecLike): number {
|
|
324
|
+
return Math.abs(A.x - B.x) + Math.abs(A.y - B.y)
|
|
325
|
+
}
|
|
326
|
+
|
|
322
327
|
// Get whether a distance between two points is less than a number. This is faster to calulate than using `Vec.Dist(a, b) < n`.
|
|
323
328
|
static DistMin(A: VecLike, B: VecLike, n: number): boolean {
|
|
324
329
|
return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) < n ** 2
|
|
@@ -465,10 +470,28 @@ export class Vec {
|
|
|
465
470
|
return isNaN(A.x) || isNaN(A.y)
|
|
466
471
|
}
|
|
467
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Get the angle from position A to position B.
|
|
475
|
+
*/
|
|
468
476
|
static Angle(A: VecLike, B: VecLike): number {
|
|
469
477
|
return Math.atan2(B.y - A.y, B.x - A.x)
|
|
470
478
|
}
|
|
471
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Get the angle between vector A and vector B. This will return the smallest angle between the
|
|
482
|
+
* two vectors, between -π and π. The sign indicates direction of angle.
|
|
483
|
+
*/
|
|
484
|
+
static AngleBetween(A: VecLike, B: VecLike): number {
|
|
485
|
+
const p = A.x * B.x + A.y * B.y
|
|
486
|
+
const n = Math.sqrt(
|
|
487
|
+
(Math.pow(A.x, 2) + Math.pow(A.y, 2)) * (Math.pow(B.x, 2) + Math.pow(B.y, 2))
|
|
488
|
+
)
|
|
489
|
+
const sign = A.x * B.y - A.y * B.x < 0 ? -1 : 1
|
|
490
|
+
const angle = sign * Math.acos(p / n)
|
|
491
|
+
|
|
492
|
+
return angle
|
|
493
|
+
}
|
|
494
|
+
|
|
472
495
|
/**
|
|
473
496
|
* Linearly interpolate between two points.
|
|
474
497
|
* @param A - The first point.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Vec } from '../Vec'
|
|
1
|
+
import { Vec, VecLike } from '../Vec'
|
|
2
2
|
import { intersectLineSegmentCircle } from '../intersect'
|
|
3
3
|
import { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'
|
|
4
4
|
import { Geometry2d, Geometry2dOptions } from './Geometry2d'
|
|
@@ -44,14 +44,14 @@ export class Arc2d extends Geometry2d {
|
|
|
44
44
|
this._center = center
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
nearestPoint(point:
|
|
47
|
+
nearestPoint(point: VecLike): Vec {
|
|
48
48
|
const { _center, measure, radius, angleEnd, angleStart, start: A, end: B } = this
|
|
49
49
|
const t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))
|
|
50
50
|
if (t <= 0) return A
|
|
51
51
|
if (t >= 1) return B
|
|
52
52
|
|
|
53
53
|
// Get the point (P) on the arc, then pick the nearest of A, B, and P
|
|
54
|
-
const P =
|
|
54
|
+
const P = Vec.Sub(point, _center).uni().mul(radius).add(_center)
|
|
55
55
|
|
|
56
56
|
let nearest: Vec | undefined
|
|
57
57
|
let dist = Infinity
|
|
@@ -67,7 +67,7 @@ export class Arc2d extends Geometry2d {
|
|
|
67
67
|
return nearest
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
hitTestLineSegment(A:
|
|
70
|
+
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
71
71
|
const { _center, radius, measure, angleStart, angleEnd } = this
|
|
72
72
|
const intersection = intersectLineSegmentCircle(A, B, _center, radius)
|
|
73
73
|
if (intersection === null) return false
|
|
@@ -95,6 +95,6 @@ export class Arc2d extends Geometry2d {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
override getLength() {
|
|
98
|
-
return this.measure * this.radius
|
|
98
|
+
return Math.abs(this.measure * this.radius)
|
|
99
99
|
}
|
|
100
100
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Box } from '../Box'
|
|
2
|
-
import { Vec } from '../Vec'
|
|
2
|
+
import { Vec, VecLike } from '../Vec'
|
|
3
3
|
import { intersectLineSegmentCircle } from '../intersect'
|
|
4
4
|
import { PI2, getPointOnCircle } from '../utils'
|
|
5
5
|
import { Geometry2d, Geometry2dOptions } from './Geometry2d'
|
|
@@ -43,13 +43,13 @@ export class Circle2d extends Geometry2d {
|
|
|
43
43
|
return vertices
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
nearestPoint(point:
|
|
46
|
+
nearestPoint(point: VecLike): Vec {
|
|
47
47
|
const { _center, radius } = this
|
|
48
48
|
if (_center.equals(point)) return Vec.AddXY(_center, radius, 0)
|
|
49
|
-
return
|
|
49
|
+
return Vec.Sub(point, _center).uni().mul(radius).add(_center)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
hitTestLineSegment(A:
|
|
52
|
+
hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
|
|
53
53
|
const { _center, radius } = this
|
|
54
54
|
return intersectLineSegmentCircle(A, B, _center, radius + distance) !== null
|
|
55
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Vec } from '../Vec'
|
|
2
|
-
import { Geometry2dOptions } from './Geometry2d'
|
|
1
|
+
import { Vec, VecLike } from '../Vec'
|
|
2
|
+
import { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'
|
|
3
3
|
import { Polyline2d } from './Polyline2d'
|
|
4
4
|
|
|
5
5
|
/** @public */
|
|
@@ -52,7 +52,7 @@ export class CubicBezier2d extends Polyline2d {
|
|
|
52
52
|
return CubicBezier2d.GetAtT(this, 0.5)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
nearestPoint(A:
|
|
55
|
+
nearestPoint(A: VecLike): Vec {
|
|
56
56
|
let nearest: Vec | undefined
|
|
57
57
|
let dist = Infinity
|
|
58
58
|
let d: number
|
|
@@ -89,7 +89,7 @@ export class CubicBezier2d extends Polyline2d {
|
|
|
89
89
|
)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
override getLength(precision = 32) {
|
|
92
|
+
override getLength(filters?: Geometry2dFilters, precision = 32) {
|
|
93
93
|
let n1: Vec,
|
|
94
94
|
p1 = this.a,
|
|
95
95
|
length = 0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Vec } from '../Vec'
|
|
1
|
+
import { Vec, VecLike } from '../Vec'
|
|
2
2
|
import { CubicBezier2d } from './CubicBezier2d'
|
|
3
3
|
import { Geometry2d, Geometry2dOptions } from './Geometry2d'
|
|
4
4
|
|
|
@@ -58,7 +58,7 @@ export class CubicSpline2d extends Geometry2d {
|
|
|
58
58
|
return vertices
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
nearestPoint(A:
|
|
61
|
+
nearestPoint(A: VecLike): Vec {
|
|
62
62
|
let nearest: Vec | undefined
|
|
63
63
|
let dist = Infinity
|
|
64
64
|
let d: number
|
|
@@ -75,7 +75,7 @@ export class CubicSpline2d extends Geometry2d {
|
|
|
75
75
|
return nearest
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
hitTestLineSegment(A:
|
|
78
|
+
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
79
79
|
return this.segments.some((segment) => segment.hitTestLineSegment(A, B))
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Vec } from '../Vec'
|
|
2
1
|
import { linesIntersect } from '../intersect'
|
|
2
|
+
import { Vec, VecLike } from '../Vec'
|
|
3
3
|
import { Geometry2d } from './Geometry2d'
|
|
4
4
|
|
|
5
5
|
/** @public */
|
|
@@ -34,7 +34,7 @@ export class Edge2d extends Geometry2d {
|
|
|
34
34
|
return [this.start, this.end]
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
override nearestPoint(point:
|
|
37
|
+
override nearestPoint(point: VecLike): Vec {
|
|
38
38
|
const { start, end, d, u, ul: l } = this
|
|
39
39
|
if (d.len() === 0) return start // start and end are the same
|
|
40
40
|
if (l === 0) return start // no length in the unit vector
|
|
@@ -48,7 +48,7 @@ export class Edge2d extends Geometry2d {
|
|
|
48
48
|
return new Vec(cx, cy)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
override hitTestLineSegment(A:
|
|
51
|
+
override hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
|
|
52
52
|
return (
|
|
53
53
|
linesIntersect(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance
|
|
54
54
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Box } from '../Box'
|
|
2
|
-
import { Vec } from '../Vec'
|
|
2
|
+
import { Vec, VecLike } from '../Vec'
|
|
3
3
|
import { PI, PI2, perimeterOfEllipse } from '../utils'
|
|
4
4
|
import { Edge2d } from './Edge2d'
|
|
5
5
|
import { Geometry2d, Geometry2dOptions } from './Geometry2d'
|
|
@@ -73,7 +73,7 @@ export class Ellipse2d extends Geometry2d {
|
|
|
73
73
|
return vertices
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
nearestPoint(A:
|
|
76
|
+
nearestPoint(A: VecLike): Vec {
|
|
77
77
|
let nearest: Vec | undefined
|
|
78
78
|
let dist = Infinity
|
|
79
79
|
let d: number
|
|
@@ -90,7 +90,7 @@ export class Ellipse2d extends Geometry2d {
|
|
|
90
90
|
return nearest
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
hitTestLineSegment(A:
|
|
93
|
+
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
94
94
|
return this.edges.some((edge) => edge.hitTestLineSegment(A, B))
|
|
95
95
|
}
|
|
96
96
|
|