{ "version": 3, "sources": ["../../../../src/lib/shapes/highlight/HighlightShapeUtil.tsx"], "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLDefaultColorTheme,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLOnResizeHandler,\n\tVecLike,\n\tgetDefaultColorTheme,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\trng,\n} from '@tldraw/editor'\nimport { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'\nimport { useDefaultColorTheme } from '../shared/ShapeFill'\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 { useColorSpace } from '../shared/useColorSpace'\nimport { useForceSolid } from '../shared/useForceSolid'\n\nconst OVERLAY_OPACITY = 0.35\nconst UNDERLAY_OPACITY = 0.82\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride hideResizeHandles = (shape: TLHighlightShape) => getIsDot(shape)\n\toverride hideRotateHandle = (shape: TLHighlightShape) => getIsDot(shape)\n\toverride hideSelectionBoundsFg = (shape: TLHighlightShape) => getIsDot(shape)\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}\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\treturn (\n\t\t\t\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\treturn (\n\t\t\t\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useForceSolid()\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet sw = strokeWidth\n\t\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t\t}\n\n\t\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\t\tconst options = getHighlightFreehandSettings({\n\t\t\tstrokeWidth,\n\t\t\tshowAsComplete,\n\t\t})\n\t\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\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 \n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })\n\t\treturn highlighterToSvg(getStrokeWidth(shape), shape, OVERLAY_OPACITY, theme)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })\n\t\treturn highlighterToSvg(getStrokeWidth(shape), shape, UNDERLAY_OPACITY, theme)\n\t}\n\n\toverride onResize: TLOnResizeHandler = (shape, info) => {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: scaleX * x,\n\t\t\t\t\t\ty: scaleY * y,\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\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 = getPointsFromSegments(shape.props.segments)\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\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getHighlightSvgPath(shape: TLHighlightShape, strokeWidth: number, forceSolid: boolean) {\n\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(shape.props.segments[0].points[0])\n\n\treturn { solidStrokePath, sw }\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tshape: TLHighlightShape\n\topacity?: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\tconst forceSolid = useForceSolid()\n\tconst { solidStrokePath, sw } = getHighlightSvgPath(shape, strokeWidth, forceSolid)\n\tconst colorSpace = useColorSpace()\n\tconst color = theme[shape.props.color].highlight[colorSpace]\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t)\n}\n\nfunction highlighterToSvg(\n\tstrokeWidth: number,\n\tshape: TLHighlightShape,\n\topacity: number,\n\ttheme: TLDefaultColorTheme\n) {\n\tconst { solidStrokePath, sw } = getHighlightSvgPath(shape, strokeWidth, false)\n\n\tconst path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n\tpath.setAttribute('d', solidStrokePath)\n\tpath.setAttribute('fill', 'none')\n\tpath.setAttribute('stroke', theme[shape.props.color].highlight.srgb)\n\tpath.setAttribute('stroke-width', `${sw}`)\n\tpath.setAttribute('opacity', `${opacity}`)\n\n\treturn path\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n"], "mappings": "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", "names": [] }