tldraw 4.3.0-canary.fda2775019a1 → 4.3.0-next.085293d79c32
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.js +1 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
- package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +20 -20
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/interpolate-props.js +3 -3
- package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
- package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +1 -1
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +1 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
- package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +20 -20
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +1 -1
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs +3 -3
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +1 -1
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
- package/package.json +3 -3
- package/src/lib/shapes/draw/DrawShapeUtil.test.ts +10 -10
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -2
- package/src/lib/shapes/draw/getPath.ts +1 -1
- package/src/lib/shapes/draw/toolStates/Drawing.ts +21 -21
- package/src/lib/shapes/highlight/HighlightShapeUtil.test.ts +10 -10
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +4 -2
- package/src/lib/shapes/shared/interpolate-props.ts +3 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +4 -4
- package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
- package/src/lib/utils/test-helpers.ts +4 -2
- package/src/lib/utils/tldr/buildFromV1Document.ts +1 -1
- package/src/test/__snapshots__/drawing.test.ts.snap +1 -1
- package/src/test/__snapshots__/resizing.test.ts.snap +1 -1
- package/src/test/drawing.test.ts +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/draw/DrawShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: scaleX * shape.props.scaleX,\n\t\t\t\tscaleY: scaleY * shape.props.scaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// Each point is 8 base64
|
|
5
|
-
"mappings": "AAuII,
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tPolygon2d,\n\tPolyline2d,\n\tSVGContainer,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLDrawShape,\n\tTLDrawShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVecLike,\n\tdrawShapeMigrations,\n\tdrawShapeProps,\n\tgetColorValue,\n\tlast,\n\tlerp,\n\trng,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { ShapeFill } from '../shared/ShapeFill'\nimport { STROKE_SIZES } from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { svgInk } from '../shared/freehand/svgInk'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport {\n\tgetDrawShapeStrokeDashArray,\n\tgetFreehandOptions,\n\tgetPointsFromDrawSegments,\n} from './getPath'\n\n/** @public */\nexport interface DrawShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n}\n\n/** @public */\nexport class DrawShapeUtil extends ShapeUtil<TLDrawShape> {\n\tstatic override type = 'draw' as const\n\tstatic override props = drawShapeProps\n\tstatic override migrations = drawShapeMigrations\n\n\toverride options: DrawShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t}\n\n\toverride hideResizeHandles(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLDrawShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLDrawShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tfill: 'none',\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisClosed: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLDrawShape) {\n\t\tconst points = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tconst sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// A dot\n\t\tif (shape.props.segments.length === 1) {\n\t\t\tconst box = Box.FromPoints(points)\n\t\t\tif (box.width < sw * 2 && box.height < sw * 2) {\n\t\t\t\treturn new Circle2d({\n\t\t\t\t\tx: -sw,\n\t\t\t\t\ty: -sw,\n\t\t\t\t\tradius: sw,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst strokePoints = getStrokePoints(\n\t\t\tpoints,\n\t\t\tgetFreehandOptions(shape.props, sw, shape.props.isPen, true)\n\t\t).map((p) => p.point)\n\n\t\t// A closed draw stroke\n\t\tif (shape.props.isClosed && strokePoints.length > 2) {\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: strokePoints,\n\t\t\t\tisFilled: shape.props.fill !== 'none',\n\t\t\t})\n\t\t}\n\n\t\tif (strokePoints.length === 1) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -sw,\n\t\t\t\ty: -sw,\n\t\t\t\tradius: sw,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\t// An open draw stroke\n\t\treturn new Polyline2d({\n\t\t\tpoints: strokePoints,\n\t\t})\n\t}\n\n\tcomponent(shape: TLDrawShape) {\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DrawShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLDrawShape) {\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst forceSolid = useValue(\n\t\t\t'force solid',\n\t\t\t() => {\n\t\t\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t\t},\n\t\t\t[this.editor, sw]\n\t\t)\n\n\t\tif (\n\t\t\t!forceSolid &&\n\t\t\t!shape.props.isPen &&\n\t\t\tshape.props.dash === 'draw' &&\n\t\t\tallPointsFromSegments.length === 1\n\t\t) {\n\t\t\tsw += rng(shape.id)() * (sw / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, true)\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\t\tconst solidStrokePath =\n\t\t\tstrokePoints.length > 1\n\t\t\t\t? getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\t\t\t\t: getDot(allPointsFromSegments[0], sw)\n\n\t\treturn <path d={solidStrokePath} />\n\t}\n\n\toverride toSvg(shape: TLDrawShape, ctx: SvgExportContext) {\n\t\tctx.addExportDef(getFillDefForExport(shape.props.fill))\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<DrawShapeSvg shape={shape} zoomOverride={1} />\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(shape: TLDrawShape, info: TLResizeInfo<TLDrawShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: scaleX * shape.props.scaleX,\n\t\t\t\tscaleY: scaleY * shape.props.scaleY,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride expandSelectionOutlinePx(shape: TLDrawShape): number {\n\t\tconst multiplier = shape.props.dash === 'draw' ? 1.6 : 1\n\t\treturn ((STROKE_SIZES[shape.props.size] * multiplier) / 2) * shape.props.scale\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLDrawShape,\n\t\tendShape: TLDrawShape,\n\t\tt: number\n\t): TLDrawShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getDot(point: VecLike, sw: number) {\n\tconst r = (sw + 1) * 0.5\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIsDot(shape: TLDrawShape) {\n\t// First point is 16 base64 chars (3 Float32s = 12 bytes)\n\t// Each delta point is 8 base64 chars (3 Float16s = 6 bytes)\n\t// 1 point = 16 chars, 2 points = 24 chars\n\t// Check if we have less than 2 points without decoding\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].path.length < 24\n}\n\nfunction DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverride?: number }) {\n\tconst theme = useDefaultColorTheme()\n\tconst editor = useEditor()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = (STROKE_SIZES[shape.props.size] + 1) * shape.props.scale\n\tconst forceSolid = useValue(\n\t\t'force solid',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\treturn zoomLevel < 0.5 && zoomLevel < 1.5 / sw\n\t\t},\n\t\t[editor, sw, zoomOverride]\n\t)\n\n\tconst dotAdjustment = useValue(\n\t\t'dot adjustment',\n\t\t() => {\n\t\t\tconst zoomLevel = zoomOverride ?? editor.getEfficientZoomLevel()\n\t\t\t// If we're zoomed way out (10%), then we need to make the dotted line go to 9 instead 0.1\n\t\t\t// Chrome doesn't render anything otherwise.\n\t\t\treturn zoomLevel < 0.2 ? 9 : 0.1\n\t\t},\n\t\t[editor, zoomOverride]\n\t)\n\n\tif (\n\t\t!forceSolid &&\n\t\t!shape.props.isPen &&\n\t\tshape.props.dash === 'draw' &&\n\t\tallPointsFromSegments.length === 1\n\t) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getFreehandOptions(shape.props, sw, showAsComplete, forceSolid)\n\n\tif (!forceSolid && shape.props.dash === 'draw') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{shape.props.isClosed && shape.props.fill && allPointsFromSegments.length > 1 ? (\n\t\t\t\t\t<ShapeFill\n\t\t\t\t\t\td={getSvgPathFromStrokePoints(\n\t\t\t\t\t\t\tgetStrokePoints(allPointsFromSegments, options),\n\t\t\t\t\t\t\tshape.props.isClosed\n\t\t\t\t\t\t)}\n\t\t\t\t\t\ttheme={theme}\n\t\t\t\t\t\tcolor={shape.props.color}\n\t\t\t\t\t\tfill={shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\t\t\tscale={shape.props.scale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<path\n\t\t\t\t\td={svgInk(allPointsFromSegments, options)}\n\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\t/>\n\t\t\t</>\n\t\t)\n\t}\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\tconst isDot = strokePoints.length < 2\n\tconst solidStrokePath = isDot\n\t\t? getDot(allPointsFromSegments[0], 0)\n\t\t: getSvgPathFromStrokePoints(strokePoints, shape.props.isClosed)\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill\n\t\t\t\td={solidStrokePath}\n\t\t\t\ttheme={theme}\n\t\t\t\tcolor={shape.props.color}\n\t\t\t\tfill={isDot || shape.props.isClosed ? shape.props.fill : 'none'}\n\t\t\t\tscale={shape.props.scale}\n\t\t\t/>\n\t\t\t<path\n\t\t\t\td={solidStrokePath}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tfill={isDot ? getColorValue(theme, shape.props.color, 'solid') : 'none'}\n\t\t\t\tstroke={getColorValue(theme, shape.props.color, 'solid')}\n\t\t\t\tstrokeWidth={sw}\n\t\t\t\tstrokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}\n\t\t\t\tstrokeDashoffset=\"0\"\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -82,7 +82,7 @@ function getFreehandOptions(shapeProps, strokeWidth, forceComplete, forceSolid)
|
|
|
82
82
|
return { ...solidSettings(strokeWidth), last };
|
|
83
83
|
}
|
|
84
84
|
function getPointsFromDrawSegment(segment, scaleX, scaleY, points = []) {
|
|
85
|
-
const _points = b64Vecs.decodePoints(segment.
|
|
85
|
+
const _points = b64Vecs.decodePoints(segment.path);
|
|
86
86
|
if (scaleX !== 1 || scaleY !== 1) {
|
|
87
87
|
for (const point of _points) {
|
|
88
88
|
point.x *= scaleX;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/draw/getPath.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tEASINGS,\n\tPI,\n\tSIN,\n\tTLDefaultDashStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tVec,\n\tb64Vecs,\n\tmodulate,\n} from '@tldraw/editor'\nimport { StrokeOptions } from '../shared/freehand/types'\n\nconst PEN_EASING = (t: number) => t * 0.65 + SIN((t * PI) / 2) * 0.35\n\nconst simulatePressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0.5,\n\t\tstreamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,\n\t\tsmoothing: 0.62,\n\t\teasing: EASINGS.easeOutSine,\n\t\tsimulatePressure: true,\n\t}\n}\n\nconst realPressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: 1 + strokeWidth * 1.2,\n\t\tthinning: 0.62,\n\t\tstreamline: 0.62,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: PEN_EASING,\n\t}\n}\n\nconst solidSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.linear,\n\t}\n}\n\nconst solidRealPressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: 0.62,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.linear,\n\t}\n}\n\nexport function getHighlightFreehandSettings({\n\tstrokeWidth,\n\tshowAsComplete,\n}: {\n\tstrokeWidth: number\n\tshowAsComplete: boolean\n}): StrokeOptions {\n\treturn {\n\t\tsize: 1 + strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: 0.5,\n\t\tsmoothing: 0.5,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.easeOutSine,\n\t\tlast: showAsComplete,\n\t}\n}\n\nexport function getFreehandOptions(\n\tshapeProps: { dash: TLDefaultDashStyle; isPen: boolean; isComplete: boolean },\n\tstrokeWidth: number,\n\tforceComplete: boolean,\n\tforceSolid: boolean\n): StrokeOptions {\n\tconst last = shapeProps.isComplete || forceComplete\n\n\tif (forceSolid) {\n\t\tif (shapeProps.isPen) {\n\t\t\treturn { ...solidRealPressureSettings(strokeWidth), last }\n\t\t} else {\n\t\t\treturn { ...solidSettings(strokeWidth), last }\n\t\t}\n\t}\n\n\tif (shapeProps.dash === 'draw') {\n\t\tif (shapeProps.isPen) {\n\t\t\treturn { ...realPressureSettings(strokeWidth), last }\n\t\t} else {\n\t\t\treturn { ...simulatePressureSettings(strokeWidth), last }\n\t\t}\n\t}\n\n\treturn { ...solidSettings(strokeWidth), last }\n}\n\n/** @public */\nexport function getPointsFromDrawSegment(\n\tsegment: TLDrawShapeSegment,\n\tscaleX: number,\n\tscaleY: number,\n\tpoints: Vec[] = []\n) {\n\tconst _points = b64Vecs.decodePoints(segment.
|
|
5
|
-
"mappings": "AAAA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAGP,MAAM,aAAa,CAAC,MAAc,IAAI,OAAO,IAAK,IAAI,KAAM,CAAC,IAAI;AAEjE,MAAM,2BAA2B,CAAC,gBAAuC;AACxE,SAAO;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY,SAAS,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI;AAAA;AAAA,IAC7D,WAAW;AAAA,IACX,QAAQ,QAAQ;AAAA,IAChB,kBAAkB;AAAA,EACnB;AACD;AAEA,MAAM,uBAAuB,CAAC,gBAAuC;AACpE,SAAO;AAAA,IACN,MAAM,IAAI,cAAc;AAAA,IACxB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,QAAQ;AAAA,EACT;AACD;AAEA,MAAM,gBAAgB,CAAC,gBAAuC;AAC7D,SAAO;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY,SAAS,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI;AAAA;AAAA,IAC7D,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,QAAQ,QAAQ;AAAA,EACjB;AACD;AAEA,MAAM,4BAA4B,CAAC,gBAAuC;AACzE,SAAO;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,QAAQ,QAAQ;AAAA,EACjB;AACD;AAEO,SAAS,6BAA6B;AAAA,EAC5C;AAAA,EACA;AACD,GAGkB;AACjB,SAAO;AAAA,IACN,MAAM,IAAI;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,QAAQ,QAAQ;AAAA,IAChB,MAAM;AAAA,EACP;AACD;AAEO,SAAS,mBACf,YACA,aACA,eACA,YACgB;AAChB,QAAM,OAAO,WAAW,cAAc;AAEtC,MAAI,YAAY;AACf,QAAI,WAAW,OAAO;AACrB,aAAO,EAAE,GAAG,0BAA0B,WAAW,GAAG,KAAK;AAAA,IAC1D,OAAO;AACN,aAAO,EAAE,GAAG,cAAc,WAAW,GAAG,KAAK;AAAA,IAC9C;AAAA,EACD;AAEA,MAAI,WAAW,SAAS,QAAQ;AAC/B,QAAI,WAAW,OAAO;AACrB,aAAO,EAAE,GAAG,qBAAqB,WAAW,GAAG,KAAK;AAAA,IACrD,OAAO;AACN,aAAO,EAAE,GAAG,yBAAyB,WAAW,GAAG,KAAK;AAAA,IACzD;AAAA,EACD;AAEA,SAAO,EAAE,GAAG,cAAc,WAAW,GAAG,KAAK;AAC9C;AAGO,SAAS,yBACf,SACA,QACA,QACA,SAAgB,CAAC,GAChB;AACD,QAAM,UAAU,QAAQ,aAAa,QAAQ,
|
|
4
|
+
"sourcesContent": ["import {\n\tEASINGS,\n\tPI,\n\tSIN,\n\tTLDefaultDashStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tVec,\n\tb64Vecs,\n\tmodulate,\n} from '@tldraw/editor'\nimport { StrokeOptions } from '../shared/freehand/types'\n\nconst PEN_EASING = (t: number) => t * 0.65 + SIN((t * PI) / 2) * 0.35\n\nconst simulatePressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0.5,\n\t\tstreamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,\n\t\tsmoothing: 0.62,\n\t\teasing: EASINGS.easeOutSine,\n\t\tsimulatePressure: true,\n\t}\n}\n\nconst realPressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: 1 + strokeWidth * 1.2,\n\t\tthinning: 0.62,\n\t\tstreamline: 0.62,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: PEN_EASING,\n\t}\n}\n\nconst solidSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.linear,\n\t}\n}\n\nconst solidRealPressureSettings = (strokeWidth: number): StrokeOptions => {\n\treturn {\n\t\tsize: strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: 0.62,\n\t\tsmoothing: 0.62,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.linear,\n\t}\n}\n\nexport function getHighlightFreehandSettings({\n\tstrokeWidth,\n\tshowAsComplete,\n}: {\n\tstrokeWidth: number\n\tshowAsComplete: boolean\n}): StrokeOptions {\n\treturn {\n\t\tsize: 1 + strokeWidth,\n\t\tthinning: 0,\n\t\tstreamline: 0.5,\n\t\tsmoothing: 0.5,\n\t\tsimulatePressure: false,\n\t\teasing: EASINGS.easeOutSine,\n\t\tlast: showAsComplete,\n\t}\n}\n\nexport function getFreehandOptions(\n\tshapeProps: { dash: TLDefaultDashStyle; isPen: boolean; isComplete: boolean },\n\tstrokeWidth: number,\n\tforceComplete: boolean,\n\tforceSolid: boolean\n): StrokeOptions {\n\tconst last = shapeProps.isComplete || forceComplete\n\n\tif (forceSolid) {\n\t\tif (shapeProps.isPen) {\n\t\t\treturn { ...solidRealPressureSettings(strokeWidth), last }\n\t\t} else {\n\t\t\treturn { ...solidSettings(strokeWidth), last }\n\t\t}\n\t}\n\n\tif (shapeProps.dash === 'draw') {\n\t\tif (shapeProps.isPen) {\n\t\t\treturn { ...realPressureSettings(strokeWidth), last }\n\t\t} else {\n\t\t\treturn { ...simulatePressureSettings(strokeWidth), last }\n\t\t}\n\t}\n\n\treturn { ...solidSettings(strokeWidth), last }\n}\n\n/** @public */\nexport function getPointsFromDrawSegment(\n\tsegment: TLDrawShapeSegment,\n\tscaleX: number,\n\tscaleY: number,\n\tpoints: Vec[] = []\n) {\n\tconst _points = b64Vecs.decodePoints(segment.path)\n\n\t// Apply scale factors (used for lazy resize and flipping)\n\tif (scaleX !== 1 || scaleY !== 1) {\n\t\tfor (const point of _points) {\n\t\t\tpoint.x *= scaleX\n\t\t\tpoint.y *= scaleY\n\t\t}\n\t}\n\n\tif (segment.type === 'free' || _points.length < 2) {\n\t\tpoints.push(..._points.map(Vec.From))\n\t} else {\n\t\tconst pointsToInterpolate = Math.max(4, Math.floor(Vec.Dist(_points[0], _points[1]) / 16))\n\t\tpoints.push(...Vec.PointsBetween(_points[0], _points[1], pointsToInterpolate))\n\t}\n\n\treturn points\n}\n\n/** @public */\nexport function getPointsFromDrawSegments(segments: TLDrawShapeSegment[], scaleX = 1, scaleY = 1) {\n\tconst points: Vec[] = []\n\n\tfor (const segment of segments) {\n\t\tgetPointsFromDrawSegment(segment, scaleX, scaleY, points)\n\t}\n\n\treturn points\n}\n\nexport function getDrawShapeStrokeDashArray(\n\tshape: TLDrawShape,\n\tstrokeWidth: number,\n\tdotAdjustment: number\n) {\n\treturn {\n\t\tdraw: 'none',\n\t\tsolid: `none`,\n\t\tdotted: `${dotAdjustment} ${strokeWidth * 2}`,\n\t\tdashed: `${strokeWidth * 2} ${strokeWidth * 2}`,\n\t}[shape.props.dash]\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -101,9 +101,9 @@ class Drawing extends StateNode {
|
|
|
101
101
|
getIsClosed(segments, size, scale) {
|
|
102
102
|
if (!this.canClose()) return false;
|
|
103
103
|
const strokeWidth = STROKE_SIZES[size];
|
|
104
|
-
const firstPoint = b64Vecs.decodeFirstPoint(segments[0].
|
|
104
|
+
const firstPoint = b64Vecs.decodeFirstPoint(segments[0].path);
|
|
105
105
|
const lastSegment = segments[segments.length - 1];
|
|
106
|
-
const lastPoint = b64Vecs.decodeLastPoint(lastSegment.
|
|
106
|
+
const lastPoint = b64Vecs.decodeLastPoint(lastSegment.path);
|
|
107
107
|
return firstPoint !== null && lastPoint !== null && firstPoint !== lastPoint && this.currentLineLength > strokeWidth * 4 * scale && Vec.DistMin(firstPoint, lastPoint, strokeWidth * 2 * scale);
|
|
108
108
|
}
|
|
109
109
|
startShape() {
|
|
@@ -124,12 +124,12 @@ class Drawing extends StateNode {
|
|
|
124
124
|
this.didJustShiftClickToExtendPreviousShapeLine = true;
|
|
125
125
|
const prevSegment = last(shape2.props.segments);
|
|
126
126
|
if (!prevSegment) throw Error("Expected a previous segment!");
|
|
127
|
-
const prevPoint = b64Vecs.decodeLastPoint(prevSegment.
|
|
127
|
+
const prevPoint = b64Vecs.decodeLastPoint(prevSegment.path);
|
|
128
128
|
if (!prevPoint) throw Error("Expected a previous point!");
|
|
129
129
|
const { x, y } = this.editor.getPointInShapeSpace(shape2, originPagePoint).toFixed();
|
|
130
130
|
const newSegment = {
|
|
131
131
|
type: this.segmentMode,
|
|
132
|
-
|
|
132
|
+
path: b64Vecs.encodePoints([
|
|
133
133
|
{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },
|
|
134
134
|
{ x, y, z: +pressure.toFixed(2) }
|
|
135
135
|
])
|
|
@@ -178,7 +178,7 @@ class Drawing extends StateNode {
|
|
|
178
178
|
segments: [
|
|
179
179
|
{
|
|
180
180
|
type: this.segmentMode,
|
|
181
|
-
|
|
181
|
+
path: b64Vecs.encodePoints([initialPoint])
|
|
182
182
|
}
|
|
183
183
|
]
|
|
184
184
|
}
|
|
@@ -219,7 +219,7 @@ class Drawing extends StateNode {
|
|
|
219
219
|
this.segmentMode = "straight";
|
|
220
220
|
const prevSegment = last(segments);
|
|
221
221
|
if (!prevSegment) throw Error("Expected a previous segment!");
|
|
222
|
-
const prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.
|
|
222
|
+
const prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path);
|
|
223
223
|
if (!prevLastPoint) throw Error("Expected a previous last point!");
|
|
224
224
|
let newSegment;
|
|
225
225
|
const newLastPoint = this.editor.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged).toFixed().toJson();
|
|
@@ -227,14 +227,14 @@ class Drawing extends StateNode {
|
|
|
227
227
|
this.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint);
|
|
228
228
|
newSegment = {
|
|
229
229
|
type: "straight",
|
|
230
|
-
|
|
230
|
+
path: b64Vecs.encodePoints([prevLastPoint, newLastPoint])
|
|
231
231
|
};
|
|
232
232
|
const transform = this.editor.getShapePageTransform(shape);
|
|
233
233
|
this.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint);
|
|
234
234
|
} else {
|
|
235
235
|
newSegment = {
|
|
236
236
|
type: "straight",
|
|
237
|
-
|
|
237
|
+
path: b64Vecs.encodePoints([newLastPoint, newPoint])
|
|
238
238
|
};
|
|
239
239
|
}
|
|
240
240
|
const shapePartial = {
|
|
@@ -268,7 +268,7 @@ class Drawing extends StateNode {
|
|
|
268
268
|
this.segmentMode = "free";
|
|
269
269
|
const newSegments = segments.slice();
|
|
270
270
|
const prevStraightSegment = newSegments[newSegments.length - 1];
|
|
271
|
-
const prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.
|
|
271
|
+
const prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.path);
|
|
272
272
|
if (!prevPoint) {
|
|
273
273
|
throw Error("No previous point!");
|
|
274
274
|
}
|
|
@@ -278,7 +278,7 @@ class Drawing extends StateNode {
|
|
|
278
278
|
this.currentSegmentPoints = interpolatedPoints;
|
|
279
279
|
const newFreeSegment = {
|
|
280
280
|
type: "free",
|
|
281
|
-
|
|
281
|
+
path: b64Vecs.encodePoints(interpolatedPoints)
|
|
282
282
|
};
|
|
283
283
|
const finalSegments = [...newSegments, newFreeSegment];
|
|
284
284
|
if (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {
|
|
@@ -335,8 +335,8 @@ class Drawing extends StateNode {
|
|
|
335
335
|
const segment = segments[i];
|
|
336
336
|
if (!segment) break;
|
|
337
337
|
if (segment.type === "free") continue;
|
|
338
|
-
const first = b64Vecs.decodeFirstPoint(segment.
|
|
339
|
-
const lastPoint = b64Vecs.decodeLastPoint(segment.
|
|
338
|
+
const first = b64Vecs.decodeFirstPoint(segment.path);
|
|
339
|
+
const lastPoint = b64Vecs.decodeLastPoint(segment.path);
|
|
340
340
|
if (!(first && lastPoint)) continue;
|
|
341
341
|
const nearestPointOnSegment = Vec.NearestPointOnLineSegment(
|
|
342
342
|
first,
|
|
@@ -358,8 +358,8 @@ class Drawing extends StateNode {
|
|
|
358
358
|
}
|
|
359
359
|
if (didSnap && snapSegment) {
|
|
360
360
|
const transform = this.editor.getShapePageTransform(shape);
|
|
361
|
-
const first = b64Vecs.decodeFirstPoint(snapSegment.
|
|
362
|
-
const lastPoint = b64Vecs.decodeLastPoint(snapSegment.
|
|
361
|
+
const first = b64Vecs.decodeFirstPoint(snapSegment.path);
|
|
362
|
+
const lastPoint = b64Vecs.decodeLastPoint(snapSegment.path);
|
|
363
363
|
if (!first || !lastPoint) throw Error("Expected a last point!");
|
|
364
364
|
const A = Mat.applyToPoint(transform, first);
|
|
365
365
|
const B = Mat.applyToPoint(transform, lastPoint);
|
|
@@ -387,12 +387,12 @@ class Drawing extends StateNode {
|
|
|
387
387
|
}
|
|
388
388
|
newPoint2 = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson();
|
|
389
389
|
}
|
|
390
|
-
this.currentLineLength += newSegments.length && b64Vecs.decodeFirstPoint(newSegment.
|
|
390
|
+
this.currentLineLength += newSegments.length && b64Vecs.decodeFirstPoint(newSegment.path) ? Vec.Dist(b64Vecs.decodeFirstPoint(newSegment.path), Vec.From(newPoint2)) : 0;
|
|
391
391
|
newSegments[newSegments.length - 1] = {
|
|
392
392
|
...newSegment,
|
|
393
393
|
type: "straight",
|
|
394
|
-
|
|
395
|
-
b64Vecs.decodeFirstPoint(newSegment.
|
|
394
|
+
path: b64Vecs.encodePoints([
|
|
395
|
+
b64Vecs.decodeFirstPoint(newSegment.path),
|
|
396
396
|
Vec.From(newPoint2)
|
|
397
397
|
])
|
|
398
398
|
};
|
|
@@ -429,7 +429,7 @@ class Drawing extends StateNode {
|
|
|
429
429
|
const newSegment = newSegments[newSegments.length - 1];
|
|
430
430
|
newSegments[newSegments.length - 1] = {
|
|
431
431
|
...newSegment,
|
|
432
|
-
|
|
432
|
+
path: b64Vecs.encodePoints(cachedPoints)
|
|
433
433
|
};
|
|
434
434
|
if (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {
|
|
435
435
|
this.currentLineLength = this.getLineLength(newSegments);
|
|
@@ -469,7 +469,7 @@ class Drawing extends StateNode {
|
|
|
469
469
|
segments: [
|
|
470
470
|
{
|
|
471
471
|
type: "free",
|
|
472
|
-
|
|
472
|
+
path: b64Vecs.encodePoints([initialPoint])
|
|
473
473
|
}
|
|
474
474
|
]
|
|
475
475
|
}
|
|
@@ -490,7 +490,7 @@ class Drawing extends StateNode {
|
|
|
490
490
|
getLineLength(segments) {
|
|
491
491
|
let length = 0;
|
|
492
492
|
for (let j = 0; j < segments.length; j++) {
|
|
493
|
-
const points = b64Vecs.decodePoints(segments[j].
|
|
493
|
+
const points = b64Vecs.decodePoints(segments[j].path);
|
|
494
494
|
for (let i = 0; i < points.length - 1; i++) {
|
|
495
495
|
length += Vec.Dist2(points[i], points[i + 1]);
|
|
496
496
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/draw/toolStates/Drawing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.editor.getZoomLevel()) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(segments: TLDrawShapeSegment[], size: TLDefaultSizeStyle, scale: number) {\n\t\tif (!this.canClose()) return false\n\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].points)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.points)\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, strokeWidth * 2 * scale)\n\t\t)\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\tthis.isPenOrStylus = isPen || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.points)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment: TLDrawShapeSegment = {\n\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\tpoints: b64Vecs.encodePoints([\n\t\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.user.getIsDynamicResizeMode() ? 1 / this.editor.getZoomLevel() : 1,\n\t\t\t\tsegments: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\t\tpoints: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.points)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpoints: b64Vecs.encodePoints([prevLastPoint, newLastPoint]),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpoints: b64Vecs.encodePoints([newLastPoint, newPoint]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.points)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment: TLDrawShapeSegment = {\n\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\tpoints: b64Vecs.encodePoints(interpolatedPoints),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.editor.getZoomLevel()\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.points)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.points)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.points)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.points)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.points)\n\t\t\t\t\t\t? Vec.Dist(b64Vecs.decodeFirstPoint(newSegment.points)!, Vec.From(newPoint))\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpoints: b64Vecs.encodePoints([\n\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.points)!,\n\t\t\t\t\t\tVec.From(newPoint),\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpoints: b64Vecs.encodePoints(cachedPoints),\n\t\t\t\t}\n\n\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\t\t\t\tpoints: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].points)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.editor.getZoomLevel()) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(segments: TLDrawShapeSegment[], size: TLDefaultSizeStyle, scale: number) {\n\t\tif (!this.canClose()) return false\n\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].path)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.path)\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, strokeWidth * 2 * scale)\n\t\t)\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\tthis.isPenOrStylus = isPen || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment: TLDrawShapeSegment = {\n\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.user.getIsDynamicResizeMode() ? 1 / this.editor.getZoomLevel() : 1,\n\t\t\t\tsegments: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([prevLastPoint, newLastPoint]),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([newLastPoint, newPoint]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.path)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment: TLDrawShapeSegment = {\n\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\tpath: b64Vecs.encodePoints(interpolatedPoints),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.editor.getZoomLevel()\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.path)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.path)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.path)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.path)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.path)\n\t\t\t\t\t\t? Vec.Dist(b64Vecs.decodeFirstPoint(newSegment.path)!, Vec.From(newPoint))\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.path)!,\n\t\t\t\t\t\tVec.From(newPoint),\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpath: b64Vecs.encodePoints(cachedPoints),\n\t\t\t\t}\n\n\t\t\t\tif (this.currentLineLength < STROKE_SIZES[shape.props.size] * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].path)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["shape", "inputs", "currentPagePoint", "newPoint"]
|
|
7
7
|
}
|
|
@@ -188,7 +188,7 @@ function getStrokeWidth(shape) {
|
|
|
188
188
|
return FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale;
|
|
189
189
|
}
|
|
190
190
|
function getIsDot(shape) {
|
|
191
|
-
return shape.props.segments.length === 1 && shape.props.segments[0].
|
|
191
|
+
return shape.props.segments.length === 1 && shape.props.segments[0].path.length < 24;
|
|
192
192
|
}
|
|
193
193
|
function HighlightRenderer({
|
|
194
194
|
strokeWidth,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/highlight/HighlightShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\tgetColorValue,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromDrawSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: scaleX * shape.props.scaleX,\n\t\t\t\tscaleY: scaleY * shape.props.scaleY,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\t// Each point is 8 base64
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\tgetColorValue,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromDrawSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t\tscaleX: 1,\n\t\t\tscaleY: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\t\tshape.props.segments,\n\t\t\tshape.props.scaleX,\n\t\t\tshape.props.scaleY\n\t\t)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tscaleX: scaleX * shape.props.scaleX,\n\t\t\t\tscaleY: scaleY * shape.props.scaleY,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\t// First point is 16 base64 chars (3 Float32s = 12 bytes)\n\t// Each delta point is 8 base64 chars (3 Float16s = 6 bytes)\n\t// 1 point = 16 chars, 2 points = 24 chars\n\t// Check if we have less than 2 points without decoding\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].path.length < 24\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tforceSolid,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tforceSolid: boolean\n\tshape: TLHighlightShape\n\topacity: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst allPointsFromSegments = getPointsFromDrawSegments(\n\t\tshape.props.segments,\n\t\tshape.props.scaleX,\n\t\tshape.props.scaleY\n\t)\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === 'straight',\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(allPointsFromSegments[0])\n\n\tconst colorSpace = useColorSpace()\n\n\tconst color = getColorValue(\n\t\ttheme,\n\t\tshape.props.color,\n\t\tcolorSpace === 'p3' ? 'highlightP3' : 'highlightSrgb'\n\t)\n\n\treturn (\n\t\t<path\n\t\t\td={solidStrokePath}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tfill=\"none\"\n\t\t\tpointerEvents=\"all\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={sw}\n\t\t\topacity={opacity}\n\t\t/>\n\t)\n}\n\nfunction useHighlightForceSolid(editor: Editor, shape: TLHighlightShape) {\n\treturn useValue(\n\t\t'forceSolid',\n\t\t() => {\n\t\t\tconst sw = getStrokeWidth(shape)\n\t\t\tconst zoomLevel = editor.getEfficientZoomLevel()\n\t\t\tif (sw / zoomLevel < 1.5) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\t\t[editor]\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,8 +2,8 @@ import { b64Vecs, lerp } from "@tldraw/editor";
|
|
|
2
2
|
const interpolateSegments = (startSegments, endSegments, progress) => {
|
|
3
3
|
const startPoints = [];
|
|
4
4
|
const endPoints = [];
|
|
5
|
-
startSegments.forEach((segment) => startPoints.push(...b64Vecs.decodePoints(segment.
|
|
6
|
-
endSegments.forEach((segment) => endPoints.push(...b64Vecs.decodePoints(segment.
|
|
5
|
+
startSegments.forEach((segment) => startPoints.push(...b64Vecs.decodePoints(segment.path)));
|
|
6
|
+
endSegments.forEach((segment) => endPoints.push(...b64Vecs.decodePoints(segment.path)));
|
|
7
7
|
const maxLength = Math.max(startPoints.length, endPoints.length);
|
|
8
8
|
const pointsToUseStart = [];
|
|
9
9
|
const pointsToUseEnd = [];
|
|
@@ -25,7 +25,7 @@ const interpolateSegments = (startSegments, endSegments, progress) => {
|
|
|
25
25
|
return [
|
|
26
26
|
{
|
|
27
27
|
type: "free",
|
|
28
|
-
|
|
28
|
+
path: b64Vecs.encodePoints(interpolatedPoints)
|
|
29
29
|
}
|
|
30
30
|
];
|
|
31
31
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/shared/interpolate-props.ts"],
|
|
4
|
-
"sourcesContent": ["import { TLDrawShapeSegment, VecModel, b64Vecs, lerp } from '@tldraw/editor'\n\n/** @public */\nexport const interpolateSegments = (\n\tstartSegments: TLDrawShapeSegment[],\n\tendSegments: TLDrawShapeSegment[],\n\tprogress: number\n): TLDrawShapeSegment[] => {\n\tconst startPoints: VecModel[] = []\n\tconst endPoints: VecModel[] = []\n\n\t// Extract all points from startSegments and endSegments\n\tstartSegments.forEach((segment) => startPoints.push(...b64Vecs.decodePoints(segment.
|
|
5
|
-
"mappings": "AAAA,SAAuC,SAAS,YAAY;AAGrD,MAAM,sBAAsB,CAClC,eACA,aACA,aAC0B;AAC1B,QAAM,cAA0B,CAAC;AACjC,QAAM,YAAwB,CAAC;AAG/B,gBAAc,QAAQ,CAAC,YAAY,YAAY,KAAK,GAAG,QAAQ,aAAa,QAAQ,
|
|
4
|
+
"sourcesContent": ["import { TLDrawShapeSegment, VecModel, b64Vecs, lerp } from '@tldraw/editor'\n\n/** @public */\nexport const interpolateSegments = (\n\tstartSegments: TLDrawShapeSegment[],\n\tendSegments: TLDrawShapeSegment[],\n\tprogress: number\n): TLDrawShapeSegment[] => {\n\tconst startPoints: VecModel[] = []\n\tconst endPoints: VecModel[] = []\n\n\t// Extract all points from startSegments and endSegments\n\tstartSegments.forEach((segment) => startPoints.push(...b64Vecs.decodePoints(segment.path)))\n\tendSegments.forEach((segment) => endPoints.push(...b64Vecs.decodePoints(segment.path)))\n\n\tconst maxLength = Math.max(startPoints.length, endPoints.length)\n\tconst pointsToUseStart: VecModel[] = []\n\tconst pointsToUseEnd: VecModel[] = []\n\n\t// Ensure both arrays have the same length\n\tfor (let i = 0; i < maxLength; i++) {\n\t\tpointsToUseStart.push(startPoints[i] || startPoints[startPoints.length - 1])\n\t\tpointsToUseEnd.push(endPoints[i] || endPoints[endPoints.length - 1])\n\t}\n\n\t// Interpolate points\n\tconst interpolatedPoints = pointsToUseStart.map((point, k) => {\n\t\tlet z = 0.5\n\t\tif (pointsToUseEnd[k].z !== undefined && point.z !== undefined) {\n\t\t\tz = lerp(point.z, pointsToUseEnd[k].z as number, progress)\n\t\t}\n\t\treturn {\n\t\t\tx: lerp(point.x, pointsToUseEnd[k].x, progress),\n\t\t\ty: lerp(point.y, pointsToUseEnd[k].y, progress),\n\t\t\tz,\n\t\t}\n\t})\n\t// Return all interpolated points in a single segment\n\treturn [\n\t\t{\n\t\t\ttype: 'free',\n\t\t\tpath: b64Vecs.encodePoints(interpolatedPoints),\n\t\t},\n\t]\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAuC,SAAS,YAAY;AAGrD,MAAM,sBAAsB,CAClC,eACA,aACA,aAC0B;AAC1B,QAAM,cAA0B,CAAC;AACjC,QAAM,YAAwB,CAAC;AAG/B,gBAAc,QAAQ,CAAC,YAAY,YAAY,KAAK,GAAG,QAAQ,aAAa,QAAQ,IAAI,CAAC,CAAC;AAC1F,cAAY,QAAQ,CAAC,YAAY,UAAU,KAAK,GAAG,QAAQ,aAAa,QAAQ,IAAI,CAAC,CAAC;AAEtF,QAAM,YAAY,KAAK,IAAI,YAAY,QAAQ,UAAU,MAAM;AAC/D,QAAM,mBAA+B,CAAC;AACtC,QAAM,iBAA6B,CAAC;AAGpC,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AACnC,qBAAiB,KAAK,YAAY,CAAC,KAAK,YAAY,YAAY,SAAS,CAAC,CAAC;AAC3E,mBAAe,KAAK,UAAU,CAAC,KAAK,UAAU,UAAU,SAAS,CAAC,CAAC;AAAA,EACpE;AAGA,QAAM,qBAAqB,iBAAiB,IAAI,CAAC,OAAO,MAAM;AAC7D,QAAI,IAAI;AACR,QAAI,eAAe,CAAC,EAAE,MAAM,UAAa,MAAM,MAAM,QAAW;AAC/D,UAAI,KAAK,MAAM,GAAG,eAAe,CAAC,EAAE,GAAa,QAAQ;AAAA,IAC1D;AACA,WAAO;AAAA,MACN,GAAG,KAAK,MAAM,GAAG,eAAe,CAAC,EAAE,GAAG,QAAQ;AAAA,MAC9C,GAAG,KAAK,MAAM,GAAG,eAAe,CAAC,EAAE,GAAG,QAAQ;AAAA,MAC9C;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO;AAAA,IACN;AAAA,MACC,MAAM;AAAA,MACN,MAAM,QAAQ,aAAa,kBAAkB;AAAA,IAC9C;AAAA,EACD;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "4.3.0-
|
|
1
|
+
const version = "4.3.0-next.085293d79c32";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2025-09-18T14:39:22.803Z",
|
|
4
|
-
minor: "2026-01-
|
|
5
|
-
patch: "2026-01-
|
|
4
|
+
minor: "2026-01-21T10:25:57.296Z",
|
|
5
|
+
patch: "2026-01-21T10:25:57.296Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|