tldraw
Version:
A tiny little drawing editor.
8 lines (7 loc) • 7.48 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../src/lib/shapes/arrow/arrowheads.ts"],
"sourcesContent": ["import { HALF_PI, PI, Vec, VecLike, intersectCircleCircle } from '@tldraw/editor'\nimport { TLArrowInfo } from './arrow-types'\n\ninterface TLArrowPointsInfo {\n\tpoint: VecLike\n\tint: VecLike\n}\n\nfunction getArrowPoints(\n\tinfo: TLArrowInfo,\n\tside: 'start' | 'end',\n\tstrokeWidth: number\n): TLArrowPointsInfo {\n\tconst PT = side === 'end' ? info.end.point : info.start.point\n\tconst PB = side === 'end' ? info.start.point : info.end.point\n\n\tconst compareLength = info.isStraight ? Vec.Dist(PB, PT) : Math.abs(info.bodyArc.length) // todo: arc length for curved arrows\n\n\tconst length = Math.max(Math.min(compareLength / 5, strokeWidth * 3), strokeWidth)\n\n\tlet P0: VecLike\n\n\tif (info.isStraight) {\n\t\tP0 = Vec.Nudge(PT, PB, length)\n\t} else {\n\t\tconst ints = intersectCircleCircle(PT, length, info.handleArc.center, info.handleArc.radius)\n\t\tP0 =\n\t\t\tside === 'end'\n\t\t\t\t? info.handleArc.sweepFlag\n\t\t\t\t\t? ints[0]\n\t\t\t\t\t: ints[1]\n\t\t\t\t: info.handleArc.sweepFlag\n\t\t\t\t\t? ints[1]\n\t\t\t\t\t: ints[0]\n\t}\n\n\tif (Vec.IsNaN(P0)) {\n\t\tP0 = info.start.point\n\t}\n\n\treturn {\n\t\tpoint: PT,\n\t\tint: P0,\n\t}\n}\n\nfunction getArrowhead({ point, int }: TLArrowPointsInfo) {\n\tconst PL = Vec.RotWith(int, point, PI / 6)\n\tconst PR = Vec.RotWith(int, point, -PI / 6)\n\n\treturn `M ${PL.x} ${PL.y} L ${point.x} ${point.y} L ${PR.x} ${PR.y}`\n}\n\nfunction getTriangleHead({ point, int }: TLArrowPointsInfo) {\n\tconst PL = Vec.RotWith(int, point, PI / 6)\n\tconst PR = Vec.RotWith(int, point, -PI / 6)\n\n\treturn `M ${PL.x} ${PL.y} L ${PR.x} ${PR.y} L ${point.x} ${point.y} Z`\n}\n\nfunction getInvertedTriangleHead({ point, int }: TLArrowPointsInfo) {\n\tconst d = Vec.Sub(int, point).div(2)\n\tconst PL = Vec.Add(point, Vec.Rot(d, HALF_PI))\n\tconst PR = Vec.Sub(point, Vec.Rot(d, HALF_PI))\n\n\treturn `M ${PL.x} ${PL.y} L ${int.x} ${int.y} L ${PR.x} ${PR.y} Z`\n}\n\nfunction getDotHead({ point, int }: TLArrowPointsInfo) {\n\tconst A = Vec.Lrp(point, int, 0.45)\n\tconst r = Vec.Dist(A, point)\n\n\treturn `M ${A.x - r},${A.y}\n a ${r},${r} 0 1,0 ${r * 2},0\n a ${r},${r} 0 1,0 -${r * 2},0 `\n}\n\nfunction getDiamondHead({ point, int }: TLArrowPointsInfo) {\n\tconst PB = Vec.Lrp(point, int, 0.75)\n\tconst PL = Vec.RotWith(PB, point, PI / 4)\n\tconst PR = Vec.RotWith(PB, point, -PI / 4)\n\n\tconst PQ = Vec.Lrp(PL, PR, 0.5)\n\tPQ.add(Vec.Sub(PQ, point))\n\n\treturn `M ${PQ.x} ${PQ.y} L ${PR.x} ${PR.y} ${point.x} ${point.y} L ${PL.x} ${PL.y} Z`\n}\n\nfunction getSquareHead({ int, point }: TLArrowPointsInfo) {\n\tconst PB = Vec.Lrp(point, int, 0.85)\n\tconst d = Vec.Sub(PB, point).div(2)\n\tconst PL1 = Vec.Add(point, Vec.Rot(d, HALF_PI))\n\tconst PR1 = Vec.Sub(point, Vec.Rot(d, HALF_PI))\n\tconst PL2 = Vec.Add(PB, Vec.Rot(d, HALF_PI))\n\tconst PR2 = Vec.Sub(PB, Vec.Rot(d, HALF_PI))\n\n\treturn `M ${PL1.x} ${PL1.y} L ${PL2.x} ${PL2.y} L ${PR2.x} ${PR2.y} L ${PR1.x} ${PR1.y} Z`\n}\n\nfunction getBarHead({ int, point }: TLArrowPointsInfo) {\n\tconst d = Vec.Sub(int, point).div(2)\n\n\tconst PL = Vec.Add(point, Vec.Rot(d, HALF_PI))\n\tconst PR = Vec.Sub(point, Vec.Rot(d, HALF_PI))\n\n\treturn `M ${PL.x} ${PL.y} L ${PR.x} ${PR.y}`\n}\n\n/** @public */\nexport function getArrowheadPathForType(\n\tinfo: TLArrowInfo,\n\tside: 'start' | 'end',\n\tstrokeWidth: number\n): string | undefined {\n\tconst type = side === 'end' ? info.end.arrowhead : info.start.arrowhead\n\tif (type === 'none') return\n\n\tconst points = getArrowPoints(info, side, strokeWidth)\n\tif (!points) return\n\n\tswitch (type) {\n\t\tcase 'bar':\n\t\t\treturn getBarHead(points)\n\t\tcase 'square':\n\t\t\treturn getSquareHead(points)\n\t\tcase 'diamond':\n\t\t\treturn getDiamondHead(points)\n\t\tcase 'dot':\n\t\t\treturn getDotHead(points)\n\t\tcase 'inverted':\n\t\t\treturn getInvertedTriangleHead(points)\n\t\tcase 'arrow':\n\t\t\treturn getArrowhead(points)\n\t\tcase 'triangle':\n\t\t\treturn getTriangleHead(points)\n\t}\n\n\treturn ''\n}\n"],
"mappings": "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",
"names": []
}