@principal-ai/logo-component 0.1.4 → 0.1.6
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/OpenTypeTextReveal.d.ts +47 -0
- package/dist/OpenTypeTextReveal.js +471 -0
- package/dist/SquareLogo.d.ts +9 -0
- package/dist/SquareLogo.js +57 -0
- package/dist/TelemetryReveal.d.ts +28 -0
- package/dist/TelemetryReveal.js +185 -0
- package/dist/TextReveal.d.ts +34 -0
- package/dist/TextReveal.js +196 -0
- package/dist/WreathLogo.d.ts +12 -0
- package/dist/WreathLogo.js +92 -0
- package/dist/esm/OpenTypeTextReveal.js +431 -0
- package/dist/esm/SquareLogo.js +50 -0
- package/dist/esm/TelemetryReveal.js +148 -0
- package/dist/esm/TextReveal.js +159 -0
- package/dist/esm/WreathLogo.js +85 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/presets.js +88 -0
- package/dist/esm/strokeCharacters.js +517 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.esm.js +7 -0
- package/dist/index.js +16 -1
- package/dist/presets.d.ts +10 -0
- package/dist/presets.js +91 -0
- package/dist/strokeCharacters.d.ts +33 -0
- package/dist/strokeCharacters.js +521 -0
- package/package.json +5 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React, { useMemo, useRef, useState, useEffect } from "react";
|
|
2
|
+
import { layoutText } from "./strokeCharacters";
|
|
3
|
+
let globalIdCounter = 0;
|
|
4
|
+
/**
|
|
5
|
+
* Estimates path length from SVG path data.
|
|
6
|
+
*/
|
|
7
|
+
function estimatePathLength(d) {
|
|
8
|
+
const coords = d.match(/-?\d+\.?\d*/g);
|
|
9
|
+
if (!coords || coords.length < 4)
|
|
10
|
+
return 100;
|
|
11
|
+
let totalLength = 0;
|
|
12
|
+
for (let i = 2; i < coords.length; i += 2) {
|
|
13
|
+
const x1 = parseFloat(coords[i - 2]);
|
|
14
|
+
const y1 = parseFloat(coords[i - 1]);
|
|
15
|
+
const x2 = parseFloat(coords[i]);
|
|
16
|
+
const y2 = parseFloat(coords[i + 1]);
|
|
17
|
+
totalLength += Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
|
|
18
|
+
}
|
|
19
|
+
return totalLength || 100;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse start and end points from path data
|
|
23
|
+
*/
|
|
24
|
+
function getPathEndpoints(d) {
|
|
25
|
+
const coords = d.match(/-?\d+\.?\d*/g);
|
|
26
|
+
if (!coords || coords.length < 4) {
|
|
27
|
+
return { start: { x: 0, y: 0 }, end: { x: 0, y: 0 } };
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
start: { x: parseFloat(coords[0]), y: parseFloat(coords[1]) },
|
|
31
|
+
end: { x: parseFloat(coords[coords.length - 2]), y: parseFloat(coords[coords.length - 1]) },
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Seeded random for consistent chaos patterns
|
|
36
|
+
*/
|
|
37
|
+
function seededRandom(seed) {
|
|
38
|
+
return () => {
|
|
39
|
+
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
|
|
40
|
+
return seed / 0x7fffffff;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export const TextReveal = ({ text, width = 400, height = 100, scale = 1, letterSpacing = 4, centerText = true, chaosMode = "none", chaosDuration = 2, dotsDuration = 1.5, flowDuration = 2, flowDelay = 0.3, particlesPerPath = 1, particleRadius = 2.5, color = "currentColor", particleColor, strokeWidth = 2, opacity = 0.9, showGlow = true, fadeAfterAssembly = true, fadeOpacity = 0.5, loop = true, loopDelay = 1, }) => {
|
|
44
|
+
const idRef = useRef(null);
|
|
45
|
+
if (idRef.current === null) {
|
|
46
|
+
idRef.current = `txr${globalIdCounter++}`;
|
|
47
|
+
}
|
|
48
|
+
const uniqueId = idRef.current;
|
|
49
|
+
const finalParticleColor = particleColor || color;
|
|
50
|
+
const isFragmented = chaosMode === "fragmented";
|
|
51
|
+
// Loop via remount
|
|
52
|
+
const [cycle, setCycle] = useState(0);
|
|
53
|
+
// Layout the text into paths
|
|
54
|
+
const { paths: layoutPaths, width: textWidth, height: textHeight } = useMemo(() => {
|
|
55
|
+
return layoutText(text, { letterSpacing, scale });
|
|
56
|
+
}, [text, letterSpacing, scale]);
|
|
57
|
+
// Calculate centering offset
|
|
58
|
+
const offsetX = centerText ? (width - textWidth) / 2 : 0;
|
|
59
|
+
const offsetY = centerText ? (height - textHeight) / 2 : 0;
|
|
60
|
+
// Apply offset to paths
|
|
61
|
+
const resolvedPaths = useMemo(() => {
|
|
62
|
+
return layoutPaths.map((path) => (Object.assign(Object.assign({}, path), { d: offsetPath(path.d, offsetX, offsetY) })));
|
|
63
|
+
}, [layoutPaths, offsetX, offsetY]);
|
|
64
|
+
// Calculate path data
|
|
65
|
+
const pathData = useMemo(() => {
|
|
66
|
+
return resolvedPaths.map((p) => ({
|
|
67
|
+
length: estimatePathLength(p.d),
|
|
68
|
+
endpoints: getPathEndpoints(p.d),
|
|
69
|
+
}));
|
|
70
|
+
}, [resolvedPaths]);
|
|
71
|
+
// Generate offsets for fragmented mode
|
|
72
|
+
const fragmentOffsets = useMemo(() => {
|
|
73
|
+
const random = seededRandom(42);
|
|
74
|
+
return resolvedPaths.map(() => ({
|
|
75
|
+
x: (random() - 0.5) * 120,
|
|
76
|
+
y: (random() - 0.5) * 80,
|
|
77
|
+
}));
|
|
78
|
+
}, [resolvedPaths]);
|
|
79
|
+
// Timing calculations
|
|
80
|
+
const numPaths = resolvedPaths.length || 1;
|
|
81
|
+
const perItemDotsDuration = (dotsDuration * 0.5) / numPaths;
|
|
82
|
+
const perItemLinesDuration = (dotsDuration * 0.5) / numPaths;
|
|
83
|
+
const perItemAssemblyDuration = chaosDuration / numPaths;
|
|
84
|
+
const dotsPhaseEnd = dotsDuration * 0.5;
|
|
85
|
+
const linesPhaseEnd = dotsDuration;
|
|
86
|
+
const assemblyEndTime = isFragmented ? dotsDuration + chaosDuration : 0;
|
|
87
|
+
const flowBeginTime = assemblyEndTime + flowDelay;
|
|
88
|
+
// Total animation duration
|
|
89
|
+
const totalDuration = flowBeginTime + flowDuration;
|
|
90
|
+
// Remount-based loop
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!loop)
|
|
93
|
+
return;
|
|
94
|
+
const timeout = setTimeout(() => {
|
|
95
|
+
setCycle((c) => c + 1);
|
|
96
|
+
}, (totalDuration + loopDelay) * 1000);
|
|
97
|
+
return () => clearTimeout(timeout);
|
|
98
|
+
}, [loop, totalDuration, loopDelay, cycle]);
|
|
99
|
+
// Calculate viewBox to fit content
|
|
100
|
+
const viewBox = `0 0 ${width} ${height}`;
|
|
101
|
+
return (React.createElement("svg", { key: cycle, width: width, height: height, viewBox: viewBox, xmlns: "http://www.w3.org/2000/svg", style: { opacity } },
|
|
102
|
+
React.createElement("defs", null,
|
|
103
|
+
showGlow && (React.createElement("filter", { id: `glow-${uniqueId}`, x: "-50%", y: "-50%", width: "200%", height: "200%" },
|
|
104
|
+
React.createElement("feGaussianBlur", { stdDeviation: "2", result: "blur" }),
|
|
105
|
+
React.createElement("feMerge", null,
|
|
106
|
+
React.createElement("feMergeNode", { in: "blur" }),
|
|
107
|
+
React.createElement("feMergeNode", { in: "SourceGraphic" })))),
|
|
108
|
+
React.createElement("radialGradient", { id: `particleGradient-${uniqueId}`, cx: "50%", cy: "50%", r: "50%" },
|
|
109
|
+
React.createElement("stop", { offset: "0%", style: { stopColor: finalParticleColor, stopOpacity: 1 } }),
|
|
110
|
+
React.createElement("stop", { offset: "100%", style: { stopColor: finalParticleColor, stopOpacity: 0.3 } }))),
|
|
111
|
+
React.createElement("g", { className: "text-paths" }, resolvedPaths.map((path, index) => {
|
|
112
|
+
const offset = fragmentOffsets[index];
|
|
113
|
+
const { length: pathLength, endpoints } = pathData[index] || {
|
|
114
|
+
length: 100,
|
|
115
|
+
endpoints: { start: { x: 0, y: 0 }, end: { x: 0, y: 0 } },
|
|
116
|
+
};
|
|
117
|
+
const dotRadius = strokeWidth / 2;
|
|
118
|
+
return (React.createElement("g", { key: path.id, transform: isFragmented ? `translate(${offset.x}, ${offset.y})` : undefined },
|
|
119
|
+
isFragmented && (React.createElement(React.Fragment, null,
|
|
120
|
+
React.createElement("circle", { cx: endpoints.start.x, cy: endpoints.start.y, r: dotRadius, fill: color, opacity: "0" },
|
|
121
|
+
React.createElement("animate", { attributeName: "opacity", from: "0", to: "1", dur: "0.15s", begin: `${index * perItemDotsDuration}s`, fill: "freeze" }),
|
|
122
|
+
React.createElement("animate", { attributeName: "opacity", from: "1", to: "0", dur: "0.2s", begin: `${dotsPhaseEnd + (index + 1) * perItemLinesDuration}s`, fill: "freeze" })),
|
|
123
|
+
React.createElement("circle", { cx: endpoints.end.x, cy: endpoints.end.y, r: dotRadius, fill: color, opacity: "0" },
|
|
124
|
+
React.createElement("animate", { attributeName: "opacity", from: "0", to: "1", dur: "0.15s", begin: `${index * perItemDotsDuration}s`, fill: "freeze" }),
|
|
125
|
+
React.createElement("animate", { attributeName: "opacity", from: "1", to: "0", dur: "0.2s", begin: `${dotsPhaseEnd + (index + 1) * perItemLinesDuration}s`, fill: "freeze" })))),
|
|
126
|
+
React.createElement("path", { d: path.d, fill: "none", stroke: color, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", opacity: isFragmented ? 0 : 1, strokeDasharray: isFragmented ? pathLength : undefined, strokeDashoffset: isFragmented ? pathLength : undefined },
|
|
127
|
+
isFragmented && (React.createElement(React.Fragment, null,
|
|
128
|
+
React.createElement("animate", { attributeName: "opacity", values: `0;1;1;${fadeAfterAssembly ? fadeOpacity : 1}`, keyTimes: "0;0.1;0.9;1", dur: `${perItemLinesDuration + chaosDuration}s`, begin: `${dotsPhaseEnd + index * perItemLinesDuration}s`, fill: "freeze" }),
|
|
129
|
+
React.createElement("animate", { attributeName: "stroke-dashoffset", from: pathLength, to: "0", dur: `${perItemLinesDuration}s`, begin: `${dotsPhaseEnd + index * perItemLinesDuration}s`, fill: "freeze", calcMode: "spline", keySplines: "0.4 0 0.2 1", keyTimes: "0;1" }))),
|
|
130
|
+
!isFragmented && fadeAfterAssembly && (React.createElement("animate", { attributeName: "opacity", from: "1", to: fadeOpacity, dur: "0.5s", begin: `${flowBeginTime}s`, fill: "freeze" }))),
|
|
131
|
+
isFragmented && (React.createElement("animateTransform", { attributeName: "transform", type: "translate", from: `${offset.x} ${offset.y}`, to: "0 0", dur: `${perItemAssemblyDuration}s`, begin: `${linesPhaseEnd + index * perItemAssemblyDuration}s`, fill: "freeze", calcMode: "spline", keySplines: "0.33 0 0.2 1", keyTimes: "0;1" }))));
|
|
132
|
+
})),
|
|
133
|
+
React.createElement("g", { className: "text-particles", filter: showGlow ? `url(#glow-${uniqueId})` : undefined }, resolvedPaths.flatMap((path, pathIndex) => {
|
|
134
|
+
return Array.from({ length: particlesPerPath }).map((_, particleIndex) => {
|
|
135
|
+
const particleDelay = (particleIndex / particlesPerPath) * flowDuration;
|
|
136
|
+
const beginTime = flowBeginTime + particleDelay;
|
|
137
|
+
return (React.createElement("circle", { key: `particle-${pathIndex}-${particleIndex}`, r: particleRadius, fill: `url(#particleGradient-${uniqueId})`, opacity: "0" },
|
|
138
|
+
React.createElement("animateMotion", { dur: `${flowDuration}s`, begin: `${beginTime}s`, fill: "freeze", path: path.d }),
|
|
139
|
+
React.createElement("animate", { attributeName: "opacity", values: "0;1;1;0", keyTimes: "0;0.1;0.9;1", dur: `${flowDuration}s`, begin: `${beginTime}s`, fill: "freeze" })));
|
|
140
|
+
});
|
|
141
|
+
}))));
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Offset all coordinates in a path by the given amounts
|
|
145
|
+
*/
|
|
146
|
+
function offsetPath(d, offsetX, offsetY) {
|
|
147
|
+
let coordIndex = 0;
|
|
148
|
+
return d.replace(/-?\d+\.?\d*/g, (match) => {
|
|
149
|
+
const num = parseFloat(match);
|
|
150
|
+
const isY = coordIndex % 2 === 1;
|
|
151
|
+
coordIndex++;
|
|
152
|
+
if (isY) {
|
|
153
|
+
return String(num + offsetY);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
return String(num + offsetX);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export const WreathLogo = ({ width = 150, height = 150, pColor = '#2C3E50', wreathColor = '#27AE60', leafAccentColor = '#52BE80', opacity = 0.9, animationSpeed = 3, }) => {
|
|
3
|
+
const wreathRadius = 58;
|
|
4
|
+
return (React.createElement("svg", { width: width, height: height, viewBox: "0 0 200 200", xmlns: "http://www.w3.org/2000/svg", style: { opacity } },
|
|
5
|
+
React.createElement("defs", null,
|
|
6
|
+
React.createElement("radialGradient", { id: "wreathGlow", cx: "50%", cy: "50%", r: "50%" },
|
|
7
|
+
React.createElement("stop", { offset: "0%", style: { stopColor: wreathColor, stopOpacity: 0.3 } }),
|
|
8
|
+
React.createElement("stop", { offset: "100%", style: { stopColor: wreathColor, stopOpacity: 0 } })),
|
|
9
|
+
React.createElement("filter", { id: "softGlow" },
|
|
10
|
+
React.createElement("feGaussianBlur", { stdDeviation: "2", result: "coloredBlur" }),
|
|
11
|
+
React.createElement("feMerge", null,
|
|
12
|
+
React.createElement("feMergeNode", { in: "coloredBlur" }),
|
|
13
|
+
React.createElement("feMergeNode", { in: "SourceGraphic" })))),
|
|
14
|
+
React.createElement("circle", { cx: "100", cy: "100", r: "70", fill: "url(#wreathGlow)", opacity: "0.3" }),
|
|
15
|
+
React.createElement("path", { d: (() => {
|
|
16
|
+
const numPoints = 24;
|
|
17
|
+
const waveAmplitude = 2;
|
|
18
|
+
let pathD = '';
|
|
19
|
+
const points = [];
|
|
20
|
+
// Generate all points first
|
|
21
|
+
for (let i = 0; i <= numPoints; i++) {
|
|
22
|
+
const angle = (360 / numPoints) * i;
|
|
23
|
+
const radians = (angle * Math.PI) / 180;
|
|
24
|
+
// Use sine wave for smooth variation
|
|
25
|
+
const radiusVariation = Math.sin((angle * Math.PI) / 180 * 6) * waveAmplitude;
|
|
26
|
+
const currentRadius = wreathRadius + radiusVariation;
|
|
27
|
+
const x = 100 + currentRadius * Math.cos(radians);
|
|
28
|
+
const y = 100 + currentRadius * Math.sin(radians);
|
|
29
|
+
points.push({ x, y, angle, radians });
|
|
30
|
+
}
|
|
31
|
+
// Create smooth cubic bezier path with better control points
|
|
32
|
+
pathD = `M ${points[0].x},${points[0].y}`;
|
|
33
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
34
|
+
const current = points[i];
|
|
35
|
+
const next = points[i + 1];
|
|
36
|
+
// Calculate tangent for smooth curves
|
|
37
|
+
const tangentLength = 0.4;
|
|
38
|
+
const cp1x = current.x - Math.sin(current.radians) * tangentLength * 15;
|
|
39
|
+
const cp1y = current.y + Math.cos(current.radians) * tangentLength * 15;
|
|
40
|
+
const cp2x = next.x + Math.sin(next.radians) * tangentLength * 15;
|
|
41
|
+
const cp2y = next.y - Math.cos(next.radians) * tangentLength * 15;
|
|
42
|
+
pathD += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next.x},${next.y}`;
|
|
43
|
+
}
|
|
44
|
+
return pathD + ' Z';
|
|
45
|
+
})(), fill: "none", stroke: wreathColor, strokeWidth: "7", strokeLinecap: "round", strokeLinejoin: "round", opacity: "0.75", filter: "url(#softGlow)" },
|
|
46
|
+
React.createElement("animate", { attributeName: "stroke-opacity", values: "0.65;0.85;0.65", dur: `${animationSpeed}s`, repeatCount: "indefinite" })),
|
|
47
|
+
React.createElement("path", { d: (() => {
|
|
48
|
+
const numPoints = 24;
|
|
49
|
+
const waveAmplitude = 1.5;
|
|
50
|
+
const innerRadius = wreathRadius - 9;
|
|
51
|
+
let pathD = '';
|
|
52
|
+
const points = [];
|
|
53
|
+
for (let i = 0; i <= numPoints; i++) {
|
|
54
|
+
const angle = (360 / numPoints) * i + 15; // Offset from main wreath
|
|
55
|
+
const radians = (angle * Math.PI) / 180;
|
|
56
|
+
// Use sine wave offset for smooth variation
|
|
57
|
+
const radiusVariation = Math.sin(((angle + 30) * Math.PI) / 180 * 6) * waveAmplitude;
|
|
58
|
+
const currentRadius = innerRadius + radiusVariation;
|
|
59
|
+
const x = 100 + currentRadius * Math.cos(radians);
|
|
60
|
+
const y = 100 + currentRadius * Math.sin(radians);
|
|
61
|
+
points.push({ x, y, radians });
|
|
62
|
+
}
|
|
63
|
+
pathD = `M ${points[0].x},${points[0].y}`;
|
|
64
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
65
|
+
const current = points[i];
|
|
66
|
+
const next = points[i + 1];
|
|
67
|
+
const tangentLength = 0.4;
|
|
68
|
+
const cp1x = current.x - Math.sin(current.radians) * tangentLength * 15;
|
|
69
|
+
const cp1y = current.y + Math.cos(current.radians) * tangentLength * 15;
|
|
70
|
+
const cp2x = next.x + Math.sin(next.radians) * tangentLength * 15;
|
|
71
|
+
const cp2y = next.y - Math.cos(next.radians) * tangentLength * 15;
|
|
72
|
+
pathD += ` C ${cp1x},${cp1y} ${cp2x},${cp2y} ${next.x},${next.y}`;
|
|
73
|
+
}
|
|
74
|
+
return pathD + ' Z';
|
|
75
|
+
})(), fill: "none", stroke: leafAccentColor, strokeWidth: "5", strokeLinecap: "round", strokeLinejoin: "round", opacity: "0.6", filter: "url(#softGlow)" },
|
|
76
|
+
React.createElement("animate", { attributeName: "stroke-opacity", values: "0.5;0.7;0.5", dur: `${animationSpeed}s`, repeatCount: "indefinite", begin: "0.5s" })),
|
|
77
|
+
React.createElement("g", { filter: "url(#softGlow)" },
|
|
78
|
+
React.createElement("defs", null,
|
|
79
|
+
React.createElement("linearGradient", { id: "pGradient", x1: "0%", y1: "0%", x2: "0%", y2: "100%" },
|
|
80
|
+
React.createElement("stop", { offset: "0%", style: { stopColor: pColor, stopOpacity: 1 } }),
|
|
81
|
+
React.createElement("stop", { offset: "100%", style: { stopColor: pColor, stopOpacity: 0.85 } }))),
|
|
82
|
+
React.createElement("path", { d: "M 82,70\n L 82,130\n L 90,130\n L 90,102\n L 104,102\n C 114,102 122,94 122,84\n C 122,74 114,70 104,70\n Z\n M 90,78\n L 104,78\n C 109,78 114,80 114,84\n C 114,88 109,94 104,94\n L 90,94\n Z", fill: "url(#pGradient)" },
|
|
83
|
+
React.createElement("animate", { attributeName: "opacity", values: "0.95;1;0.95", dur: `${animationSpeed}s`, repeatCount: "indefinite" })),
|
|
84
|
+
React.createElement("path", { d: "M 83,72 L 83,128 L 84,128 L 84,72 Z", fill: "white", opacity: "0.15" }))));
|
|
85
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export { Logo } from './Logo';
|
|
2
2
|
export { LogoSmall } from './LogoSmall';
|
|
3
3
|
export { ForksLogo } from './ForksLogo';
|
|
4
|
+
export { SquareLogo } from './SquareLogo';
|
|
5
|
+
export { WreathLogo } from './WreathLogo';
|
|
6
|
+
export { TelemetryReveal } from './TelemetryReveal';
|
|
7
|
+
export { TextReveal } from './TextReveal';
|
|
8
|
+
export { OpenTypeTextReveal } from './OpenTypeTextReveal';
|
|
9
|
+
export { TELEMETRY_PRESETS } from './presets';
|
|
10
|
+
export { STROKE_CHARACTERS, layoutText } from './strokeCharacters';
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export const TELEMETRY_PRESETS = {
|
|
2
|
+
network: {
|
|
3
|
+
name: "network",
|
|
4
|
+
viewBox: "0 0 200 200",
|
|
5
|
+
paths: [
|
|
6
|
+
// Cardinal directions
|
|
7
|
+
{ d: "M 100,100 L 100,30", id: "n-top" },
|
|
8
|
+
{ d: "M 100,100 L 170,100", id: "n-right" },
|
|
9
|
+
{ d: "M 100,100 L 100,170", id: "n-bottom" },
|
|
10
|
+
{ d: "M 100,100 L 30,100", id: "n-left" },
|
|
11
|
+
// Diagonals
|
|
12
|
+
{ d: "M 100,100 L 150,50", id: "n-tr" },
|
|
13
|
+
{ d: "M 100,100 L 150,150", id: "n-br" },
|
|
14
|
+
{ d: "M 100,100 L 50,150", id: "n-bl" },
|
|
15
|
+
{ d: "M 100,100 L 50,50", id: "n-tl" },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
tree: {
|
|
19
|
+
name: "tree",
|
|
20
|
+
viewBox: "0 0 200 200",
|
|
21
|
+
paths: [
|
|
22
|
+
// Root to trunk
|
|
23
|
+
{ d: "M 100,180 L 100,100", id: "trunk" },
|
|
24
|
+
// Main branches
|
|
25
|
+
{ d: "M 100,100 L 55,55", id: "branch-l1" },
|
|
26
|
+
{ d: "M 100,100 L 145,55", id: "branch-r1" },
|
|
27
|
+
// Sub-branches left
|
|
28
|
+
{ d: "M 55,55 L 30,25", id: "branch-l2" },
|
|
29
|
+
{ d: "M 55,55 L 70,25", id: "branch-l3" },
|
|
30
|
+
// Sub-branches right
|
|
31
|
+
{ d: "M 145,55 L 130,25", id: "branch-r2" },
|
|
32
|
+
{ d: "M 145,55 L 170,25", id: "branch-r3" },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
circuit: {
|
|
36
|
+
name: "circuit",
|
|
37
|
+
viewBox: "0 0 200 200",
|
|
38
|
+
paths: [
|
|
39
|
+
// Horizontal bus lines
|
|
40
|
+
{ d: "M 25,50 L 175,50", id: "h1" },
|
|
41
|
+
{ d: "M 25,100 L 175,100", id: "h2" },
|
|
42
|
+
{ d: "M 25,150 L 175,150", id: "h3" },
|
|
43
|
+
// Vertical connectors
|
|
44
|
+
{ d: "M 60,50 L 60,100", id: "v1" },
|
|
45
|
+
{ d: "M 100,50 L 100,150", id: "v2" },
|
|
46
|
+
{ d: "M 140,100 L 140,150", id: "v3" },
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
hexagon: {
|
|
50
|
+
name: "hexagon",
|
|
51
|
+
viewBox: "0 0 200 200",
|
|
52
|
+
paths: [
|
|
53
|
+
// Hexagon edges (clockwise from top)
|
|
54
|
+
{ d: "M 100,25 L 160,55", id: "hex1" },
|
|
55
|
+
{ d: "M 160,55 L 160,125", id: "hex2" },
|
|
56
|
+
{ d: "M 160,125 L 100,155", id: "hex3" },
|
|
57
|
+
{ d: "M 100,155 L 40,125", id: "hex4" },
|
|
58
|
+
{ d: "M 40,125 L 40,55", id: "hex5" },
|
|
59
|
+
{ d: "M 40,55 L 100,25", id: "hex6" },
|
|
60
|
+
// Spokes to center
|
|
61
|
+
{ d: "M 100,90 L 100,25", id: "spoke1" },
|
|
62
|
+
{ d: "M 100,90 L 160,55", id: "spoke2" },
|
|
63
|
+
{ d: "M 100,90 L 160,125", id: "spoke3" },
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
codebase: {
|
|
67
|
+
name: "codebase",
|
|
68
|
+
viewBox: "0 0 200 200",
|
|
69
|
+
paths: [
|
|
70
|
+
// Root vertical line
|
|
71
|
+
{ d: "M 35,35 L 35,165", id: "root" },
|
|
72
|
+
// First level directories
|
|
73
|
+
{ d: "M 35,55 L 75,55", id: "dir1" },
|
|
74
|
+
{ d: "M 35,90 L 75,90", id: "dir2" },
|
|
75
|
+
{ d: "M 35,125 L 75,125", id: "dir3" },
|
|
76
|
+
// Nested structure from dir1
|
|
77
|
+
{ d: "M 75,55 L 75,80", id: "sub1" },
|
|
78
|
+
{ d: "M 75,65 L 115,65", id: "file1" },
|
|
79
|
+
// Nested structure from dir2
|
|
80
|
+
{ d: "M 75,90 L 75,115", id: "sub2" },
|
|
81
|
+
{ d: "M 75,100 L 135,100", id: "file2" },
|
|
82
|
+
{ d: "M 75,110 L 105,110", id: "file3" },
|
|
83
|
+
// Cross-references (dependencies)
|
|
84
|
+
{ d: "M 115,65 L 155,45", id: "link1" },
|
|
85
|
+
{ d: "M 135,100 L 165,80", id: "link2" },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
};
|