@alphacifer/slidev-addon-theme 0.0.7 → 0.0.8
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/README.md +106 -76
- package/components/{chevron-card → card/chevron-card}/ChevronCard.vue +2 -2
- package/components/{chevron-card → card/chevron-card}/ChevronCardBadge.vue +1 -1
- package/components/{chevron-card → card/chevron-card}/ChevronCardContent.vue +1 -1
- package/components/{chevron-card → card/chevron-card}/ChevronCardHeading.vue +1 -1
- package/components/{horiz-card → card/horiz-card}/HorizCard.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardBadge.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardContent.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardHeading.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardIcon.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCard.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardBadge.vue +5 -2
- package/components/{vert-card → card/vert-card}/VertCardContent.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardHeading.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardIcon.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardTitle.vue +2 -2
- package/components/comparisons/arc-comparison/ArcComparison.vue +654 -0
- package/components/comparisons/arc-comparison/ArcComparisonBadge.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonContent.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonContents.vue +17 -0
- package/components/comparisons/arc-comparison/ArcComparisonHeading.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonLeft.vue +268 -0
- package/components/comparisons/arc-comparison/ArcComparisonOrbit.vue +47 -0
- package/components/comparisons/arc-comparison/ArcComparisonRight.vue +271 -0
- package/components/comparisons/arc-comparison/ArcComparisonTitle.vue +29 -0
- package/components/{comparison-table/ComparisonTable.vue → comparisons/table-comparison/TableComparison.vue} +37 -27
- package/components/{comparison-table/ComparisonTableCell.vue → comparisons/table-comparison/TableComparisonCell.vue} +8 -8
- package/components/{comparison-table/ComparisonTableCol.vue → comparisons/table-comparison/TableComparisonCol.vue} +10 -10
- package/components/{comparison-table/ComparisonTableCols.vue → comparisons/table-comparison/TableComparisonCols.vue} +11 -11
- package/components/{comparison-table/ComparisonTableRow.vue → comparisons/table-comparison/TableComparisonRow.vue} +9 -9
- package/components/{comparison-table/ComparisonTableRows.vue → comparisons/table-comparison/TableComparisonRows.vue} +3 -3
- package/components/core/ReflectedTitle.vue +2 -1
- package/components/core/arc-orbit/ArcOrbit.vue +468 -0
- package/components/{arc-compare/ArcCompareBadge.vue → core/arc-orbit/ArcOrbitBadge.vue} +11 -8
- package/components/core/arc-orbit/ArcOrbitCallout.vue +400 -0
- package/components/{arc-compare/ArcCompareContent.vue → core/arc-orbit/ArcOrbitContent.vue} +8 -8
- package/components/{arc-compare/ArcCompareContents.vue → core/arc-orbit/ArcOrbitContents.vue} +3 -3
- package/components/{arc-compare/ArcCompareHeading.vue → core/arc-orbit/ArcOrbitHeading.vue} +11 -8
- package/components/core/arc-orbit/ArcOrbitTitle.vue +50 -0
- package/components/{thanks → core/thanks}/ThanksOutlineSquare.vue +1 -1
- package/components/{thanks → core/thanks}/ThanksSquare.vue +1 -1
- package/components/{quad-hub/QuadHub.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetrad.vue} +71 -69
- package/components/{quad-hub/QuadHubCallout.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCallout.vue} +45 -43
- package/components/{quad-hub/QuadHubCenter.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCenter.vue} +4 -4
- package/components/{quad-hub/QuadHubContent.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradContent.vue} +6 -6
- package/components/{quad-hub/QuadHubHeading.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradHeading.vue} +6 -6
- package/components/{quad-hub/QuadHubIcon.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradIcon.vue} +6 -6
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriad.vue +3 -3
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadCallout.vue +1 -1
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadContent.vue +1 -1
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadHeading.vue +1 -1
- package/components/facets/triad/gear-triad/GearTriad.vue +591 -0
- package/components/facets/triad/gear-triad/GearTriadCallout.vue +285 -0
- package/components/facets/triad/gear-triad/GearTriadCenter.vue +41 -0
- package/components/facets/triad/gear-triad/GearTriadContent.vue +58 -0
- package/components/facets/triad/gear-triad/GearTriadContents.vue +111 -0
- package/components/facets/triad/gear-triad/GearTriadDescription.vue +38 -0
- package/components/facets/triad/gear-triad/GearTriadHeading.vue +38 -0
- package/components/facets/triad/gear-triad/GearTriadIcon.vue +157 -0
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriad.vue +2 -2
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadBadge.vue +1 -1
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCallout.vue +1 -1
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadHeading.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcess.vue +2 -2
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessArrow.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessCallout.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessContent.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessHeading.vue +1 -1
- package/package.json +1 -1
- package/utils/arcComparison/context.ts +40 -0
- package/utils/arcComparison/createArcComparisonGeometry.ts +175 -0
- package/utils/arcComparison/index.ts +3 -0
- package/utils/{arcCompare/resolveArcCompareItems.ts → arcComparison/resolveArcComparisonItems.ts} +24 -45
- package/utils/arcOrbit/context.ts +38 -0
- package/utils/{arcCompare/createArcCompareGeometry.ts → arcOrbit/createArcOrbitGeometry.ts} +77 -108
- package/utils/arcOrbit/index.ts +3 -0
- package/utils/arcOrbit/resolveArcOrbitItems.ts +92 -0
- package/utils/gearTriad/context.ts +51 -0
- package/utils/gearTriad/createGearTriadGeometry.ts +210 -0
- package/utils/gearTriad/index.ts +3 -0
- package/utils/gearTriad/resolveGearTriadItems.ts +159 -0
- package/utils/rectOrbitTetrad/context.ts +31 -0
- package/utils/{quadHub/createQuadHubGeometry.ts → rectOrbitTetrad/createRectOrbitTetradGeometry.ts} +33 -28
- package/utils/rectOrbitTetrad/index.ts +3 -0
- package/utils/{quadHub/resolveQuadHubItems.ts → rectOrbitTetrad/resolveRectOrbitTetradItems.ts} +25 -25
- package/utils/{comparisonTable → tableComparison}/context.ts +6 -6
- package/utils/useDiagramAutoScale.ts +1 -1
- package/components/arc-compare/ArcCompare.vue +0 -443
- package/components/arc-compare/ArcCompareCallout.vue +0 -386
- package/components/arc-compare/ArcCompareLeft.vue +0 -183
- package/components/arc-compare/ArcCompareRight.vue +0 -183
- package/components/arc-compare/ArcCompareTitle.vue +0 -47
- package/utils/arcCompare/context.ts +0 -36
- package/utils/arcCompare/index.ts +0 -3
- package/utils/quadHub/context.ts +0 -26
- package/utils/quadHub/index.ts +0 -3
- /package/components/{shifting-heading → core}/TransitionHeading.vue +0 -0
- /package/components/{thanks → core/thanks}/ThanksContent.vue +0 -0
- /package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadIcon.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCenterBadge.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadContent.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadLayer.vue +0 -0
- /package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessIcon.vue +0 -0
- /package/utils/{comparisonTable → tableComparison}/constants.ts +0 -0
- /package/utils/{comparisonTable → tableComparison}/index.ts +0 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type TArcOrbitPosition = 'left' | 'right';
|
|
2
|
+
|
|
3
|
+
export interface IArcOrbitPoint {
|
|
2
4
|
readonly x: number;
|
|
3
5
|
readonly y: number;
|
|
4
6
|
}
|
|
5
7
|
|
|
6
|
-
export interface
|
|
8
|
+
export interface IArcOrbitNodeGeo {
|
|
7
9
|
readonly index: number;
|
|
8
|
-
readonly center:
|
|
10
|
+
readonly center: IArcOrbitPoint;
|
|
9
11
|
readonly radius: number;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
export interface
|
|
14
|
+
export interface IArcOrbitCalloutBox {
|
|
13
15
|
readonly index: number;
|
|
14
16
|
readonly x: number;
|
|
15
17
|
readonly y: number;
|
|
@@ -20,72 +22,58 @@ export interface IArcCompareCalloutBox {
|
|
|
20
22
|
readonly textWidth?: number;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
export interface
|
|
24
|
-
readonly
|
|
25
|
-
readonly
|
|
25
|
+
export interface IArcOrbitGeometry {
|
|
26
|
+
readonly viewBoxWidth: number;
|
|
27
|
+
readonly viewBoxHeight: number;
|
|
28
|
+
readonly position: TArcOrbitPosition;
|
|
29
|
+
readonly hubCenter: IArcOrbitPoint;
|
|
26
30
|
readonly hubRadius: number;
|
|
31
|
+
readonly hubPath: string;
|
|
27
32
|
readonly arcPath: string;
|
|
28
|
-
readonly topDot:
|
|
29
|
-
readonly bottomDot:
|
|
33
|
+
readonly topDot: IArcOrbitPoint;
|
|
34
|
+
readonly bottomDot: IArcOrbitPoint;
|
|
30
35
|
readonly dotRadius: number;
|
|
31
|
-
readonly nodes: readonly
|
|
32
|
-
readonly callouts: readonly
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface IArcCompareGeometry {
|
|
36
|
-
readonly viewBoxWidth: number;
|
|
37
|
-
readonly viewBoxHeight: number;
|
|
38
|
-
readonly centerX: number;
|
|
39
|
-
readonly centerY: number;
|
|
40
|
-
readonly vsCenter: IArcComparePoint;
|
|
41
|
-
readonly vsRadius: number;
|
|
36
|
+
readonly nodes: readonly IArcOrbitNodeGeo[];
|
|
37
|
+
readonly callouts: readonly IArcOrbitCalloutBox[];
|
|
42
38
|
readonly pointsCount: number;
|
|
43
|
-
readonly dividerLine: {
|
|
44
|
-
readonly x: number;
|
|
45
|
-
readonly y1: number;
|
|
46
|
-
readonly y2: number;
|
|
47
|
-
};
|
|
48
|
-
readonly left: IArcCompareSideGeometry;
|
|
49
|
-
readonly right: IArcCompareSideGeometry;
|
|
50
39
|
}
|
|
51
40
|
|
|
52
|
-
export interface
|
|
41
|
+
export interface ICreateArcOrbitGeometryOptions {
|
|
53
42
|
readonly viewBoxWidth?: number;
|
|
54
43
|
readonly viewBoxHeight?: number;
|
|
44
|
+
readonly position?: TArcOrbitPosition;
|
|
55
45
|
readonly hubRadius?: number;
|
|
46
|
+
readonly edgeOffset?: number;
|
|
56
47
|
readonly arcRadius?: number;
|
|
57
48
|
readonly arcOffset?: number;
|
|
58
49
|
readonly nodeRadius?: number;
|
|
59
50
|
readonly nodeAngleDeg?: number;
|
|
60
51
|
readonly arcExtentDeg?: number;
|
|
61
|
-
readonly vsRadius?: number;
|
|
62
52
|
readonly pointsCount?: number;
|
|
63
53
|
}
|
|
64
54
|
|
|
65
|
-
export function
|
|
66
|
-
options:
|
|
67
|
-
):
|
|
68
|
-
const viewBoxWidth = options.viewBoxWidth ??
|
|
55
|
+
export function createArcOrbitGeometry(
|
|
56
|
+
options: ICreateArcOrbitGeometryOptions = {},
|
|
57
|
+
): IArcOrbitGeometry {
|
|
58
|
+
const viewBoxWidth = options.viewBoxWidth ?? 500;
|
|
69
59
|
const viewBoxHeight = options.viewBoxHeight ?? 480;
|
|
60
|
+
const position: TArcOrbitPosition = options.position ?? 'left';
|
|
70
61
|
const hubRadius = options.hubRadius ?? 135;
|
|
62
|
+
const edgeOffset = options.edgeOffset !== undefined ? options.edgeOffset : 30;
|
|
71
63
|
const arcRadius = options.arcRadius ?? 235;
|
|
72
64
|
const arcOffset = options.arcOffset ?? 25;
|
|
73
65
|
const nodeRadius = options.nodeRadius ?? 26;
|
|
74
|
-
const vsRadius = options.vsRadius ?? 26;
|
|
75
66
|
const dotRadius = 3.5;
|
|
76
67
|
const pointsCount = options.pointsCount === 4 ? 4 : 3;
|
|
77
68
|
|
|
78
69
|
const defaultArcExtent = pointsCount === 4 ? 66 : 58;
|
|
79
70
|
const arcExtentDeg = options.arcExtentDeg ?? defaultArcExtent;
|
|
71
|
+
const extentRad = (arcExtentDeg * Math.PI) / 180;
|
|
80
72
|
|
|
81
|
-
const centerX = viewBoxWidth / 2;
|
|
82
73
|
const centerY = viewBoxHeight / 2;
|
|
83
|
-
const leftArcCenterX = -arcOffset;
|
|
84
|
-
|
|
85
|
-
// Angular math for left side:
|
|
86
|
-
const extentRad = (arcExtentDeg * Math.PI) / 180;
|
|
87
74
|
|
|
88
|
-
//
|
|
75
|
+
// Base left calculations (origin at x = 0)
|
|
76
|
+
const leftArcCenterX = -arcOffset;
|
|
89
77
|
const leftStartCos = Math.cos(extentRad);
|
|
90
78
|
const leftStartSin = Math.sin(extentRad);
|
|
91
79
|
const leftTopX = Number(
|
|
@@ -95,25 +83,18 @@ export function createArcCompareGeometry(
|
|
|
95
83
|
const leftBottomX = leftTopX;
|
|
96
84
|
const leftBottomY = Number((centerY + arcRadius * leftStartSin).toFixed(2));
|
|
97
85
|
|
|
98
|
-
// Left arc path
|
|
99
|
-
const leftArcPath = `M ${leftTopX} ${leftTopY} A ${arcRadius} ${arcRadius} 0 0 1 ${leftBottomX} ${leftBottomY}`;
|
|
100
|
-
|
|
101
|
-
// Left hub path (semicircle centered at 0, centerY)
|
|
102
|
-
const leftHubPath = `M 0 ${centerY - hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 0 ${centerY + hubRadius} Z`;
|
|
103
|
-
|
|
104
86
|
// Determine node angles for 3 or 4 points
|
|
105
87
|
const nodeAnglesDeg: readonly number[] =
|
|
106
88
|
pointsCount === 4
|
|
107
89
|
? [50, 16.5, -16.5, -50]
|
|
108
90
|
: [options.nodeAngleDeg ?? 38, 0, -(options.nodeAngleDeg ?? 38)];
|
|
109
91
|
|
|
110
|
-
// Left nodes and callouts
|
|
111
|
-
const leftCalloutGap = 26;
|
|
112
|
-
const leftNodes: IArcCompareNodeGeo[] = [];
|
|
113
|
-
const leftCallouts: IArcCompareCalloutBox[] = [];
|
|
114
92
|
const defaultTextGap = 28;
|
|
115
93
|
const textWidth = pointsCount === 4 ? 215 : 205;
|
|
116
94
|
|
|
95
|
+
const leftNodes: IArcOrbitNodeGeo[] = [];
|
|
96
|
+
const leftCallouts: IArcOrbitCalloutBox[] = [];
|
|
97
|
+
|
|
117
98
|
for (let i = 0; i < pointsCount; i++) {
|
|
118
99
|
const angleDeg = nodeAnglesDeg[i] ?? 0;
|
|
119
100
|
const angleRad = (angleDeg * Math.PI) / 180;
|
|
@@ -133,14 +114,12 @@ export function createArcCompareGeometry(
|
|
|
133
114
|
|
|
134
115
|
const badgeOffset = Math.round(nodeX - nodeRadius);
|
|
135
116
|
const top = Math.round(nodeY - nodeRadius);
|
|
136
|
-
// Only adjust position for 01 (index 0) so its text does not overlay the arc curve.
|
|
137
|
-
// 02, 03, and 04 keep their standard natural gap.
|
|
138
117
|
const textGap = i === 0 ? (pointsCount === 4 ? 46 : 36) : defaultTextGap;
|
|
139
118
|
const width = Math.round(nodeRadius * 2 + textGap + textWidth);
|
|
140
119
|
|
|
141
120
|
leftCallouts.push({
|
|
142
121
|
index: i,
|
|
143
|
-
x: nodeX +
|
|
122
|
+
x: nodeX + 26,
|
|
144
123
|
y: nodeY - 32,
|
|
145
124
|
width,
|
|
146
125
|
badgeOffset,
|
|
@@ -150,17 +129,46 @@ export function createArcCompareGeometry(
|
|
|
150
129
|
});
|
|
151
130
|
}
|
|
152
131
|
|
|
153
|
-
|
|
132
|
+
if (position === 'left') {
|
|
133
|
+
const leftArcPath = `M ${leftTopX} ${leftTopY} A ${arcRadius} ${arcRadius} 0 0 1 ${leftBottomX} ${leftBottomY}`;
|
|
134
|
+
const leftHubCenterX = edgeOffset;
|
|
135
|
+
const leftHubPath =
|
|
136
|
+
edgeOffset > 0
|
|
137
|
+
? `M ${leftHubCenterX} ${centerY - hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 ${leftHubCenterX} ${centerY + hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 ${leftHubCenterX} ${centerY - hubRadius} Z`
|
|
138
|
+
: `M 0 ${centerY - hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 0 ${centerY + hubRadius} Z`;
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
viewBoxWidth,
|
|
142
|
+
viewBoxHeight,
|
|
143
|
+
position: 'left',
|
|
144
|
+
hubCenter: { x: leftHubCenterX, y: centerY },
|
|
145
|
+
hubRadius,
|
|
146
|
+
hubPath: leftHubPath,
|
|
147
|
+
arcPath: leftArcPath,
|
|
148
|
+
topDot: { x: leftTopX, y: leftTopY },
|
|
149
|
+
bottomDot: { x: leftBottomX, y: leftBottomY },
|
|
150
|
+
dotRadius,
|
|
151
|
+
nodes: leftNodes,
|
|
152
|
+
callouts: leftCallouts,
|
|
153
|
+
pointsCount,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Right position: mirrored across viewBoxWidth
|
|
154
158
|
const rightTopX = Number((viewBoxWidth - leftTopX).toFixed(2));
|
|
155
159
|
const rightTopY = leftTopY;
|
|
156
160
|
const rightBottomX = rightTopX;
|
|
157
161
|
const rightBottomY = leftBottomY;
|
|
158
162
|
|
|
159
163
|
const rightArcPath = `M ${rightTopX} ${rightTopY} A ${arcRadius} ${arcRadius} 0 0 0 ${rightBottomX} ${rightBottomY}`;
|
|
160
|
-
const
|
|
164
|
+
const rightHubCenterX = viewBoxWidth - edgeOffset;
|
|
165
|
+
const rightHubPath =
|
|
166
|
+
edgeOffset > 0
|
|
167
|
+
? `M ${rightHubCenterX} ${centerY - hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 ${rightHubCenterX} ${centerY + hubRadius} A ${hubRadius} ${hubRadius} 0 0 1 ${rightHubCenterX} ${centerY - hubRadius} Z`
|
|
168
|
+
: `M ${viewBoxWidth} ${centerY - hubRadius} A ${hubRadius} ${hubRadius} 0 0 0 ${viewBoxWidth} ${centerY + hubRadius} Z`;
|
|
161
169
|
|
|
162
|
-
const rightNodes:
|
|
163
|
-
const rightCallouts:
|
|
170
|
+
const rightNodes: IArcOrbitNodeGeo[] = [];
|
|
171
|
+
const rightCallouts: IArcOrbitCalloutBox[] = [];
|
|
164
172
|
|
|
165
173
|
for (let i = 0; i < pointsCount; i++) {
|
|
166
174
|
const leftNode = leftNodes[i];
|
|
@@ -184,7 +192,7 @@ export function createArcCompareGeometry(
|
|
|
184
192
|
|
|
185
193
|
rightCallouts.push({
|
|
186
194
|
index: i,
|
|
187
|
-
x:
|
|
195
|
+
x: rightNodeX - leftCallout.width,
|
|
188
196
|
y: rightNodeY - 32,
|
|
189
197
|
width: leftCallout.width,
|
|
190
198
|
badgeOffset: leftCallout.badgeOffset,
|
|
@@ -197,58 +205,19 @@ export function createArcCompareGeometry(
|
|
|
197
205
|
return {
|
|
198
206
|
viewBoxWidth,
|
|
199
207
|
viewBoxHeight,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
x: centerX,
|
|
208
|
+
position: 'right',
|
|
209
|
+
hubCenter: {
|
|
210
|
+
x: rightHubCenterX,
|
|
204
211
|
y: centerY,
|
|
205
212
|
},
|
|
206
|
-
|
|
213
|
+
hubRadius,
|
|
214
|
+
hubPath: rightHubPath,
|
|
215
|
+
arcPath: rightArcPath,
|
|
216
|
+
topDot: { x: rightTopX, y: rightTopY },
|
|
217
|
+
bottomDot: { x: rightBottomX, y: rightBottomY },
|
|
218
|
+
dotRadius,
|
|
219
|
+
nodes: rightNodes,
|
|
220
|
+
callouts: rightCallouts,
|
|
207
221
|
pointsCount,
|
|
208
|
-
dividerLine: {
|
|
209
|
-
x: centerX,
|
|
210
|
-
y1: 20,
|
|
211
|
-
y2: viewBoxHeight - 20,
|
|
212
|
-
},
|
|
213
|
-
left: {
|
|
214
|
-
hubPath: leftHubPath,
|
|
215
|
-
hubCenter: {
|
|
216
|
-
x: 55,
|
|
217
|
-
y: centerY,
|
|
218
|
-
},
|
|
219
|
-
hubRadius,
|
|
220
|
-
arcPath: leftArcPath,
|
|
221
|
-
topDot: {
|
|
222
|
-
x: leftTopX,
|
|
223
|
-
y: leftTopY,
|
|
224
|
-
},
|
|
225
|
-
bottomDot: {
|
|
226
|
-
x: leftBottomX,
|
|
227
|
-
y: leftBottomY,
|
|
228
|
-
},
|
|
229
|
-
dotRadius,
|
|
230
|
-
nodes: leftNodes,
|
|
231
|
-
callouts: leftCallouts,
|
|
232
|
-
},
|
|
233
|
-
right: {
|
|
234
|
-
hubPath: rightHubPath,
|
|
235
|
-
hubCenter: {
|
|
236
|
-
x: viewBoxWidth - 55,
|
|
237
|
-
y: centerY,
|
|
238
|
-
},
|
|
239
|
-
hubRadius,
|
|
240
|
-
arcPath: rightArcPath,
|
|
241
|
-
topDot: {
|
|
242
|
-
x: rightTopX,
|
|
243
|
-
y: rightTopY,
|
|
244
|
-
},
|
|
245
|
-
bottomDot: {
|
|
246
|
-
x: rightBottomX,
|
|
247
|
-
y: rightBottomY,
|
|
248
|
-
},
|
|
249
|
-
dotRadius,
|
|
250
|
-
nodes: rightNodes,
|
|
251
|
-
callouts: rightCallouts,
|
|
252
|
-
},
|
|
253
222
|
};
|
|
254
223
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export interface IArcOrbitItem {
|
|
2
|
+
readonly id?: string | number;
|
|
3
|
+
readonly title?: string;
|
|
4
|
+
readonly description?: string;
|
|
5
|
+
readonly color?: string;
|
|
6
|
+
readonly textColor?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IResolvedArcOrbitItem {
|
|
10
|
+
readonly id: string | number;
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly description: string;
|
|
13
|
+
readonly color: string;
|
|
14
|
+
readonly textColor?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const DEFAULT_ARC_ORBIT_COLOR = '#ea580c';
|
|
18
|
+
|
|
19
|
+
export const DEFAULT_LOREM_TEXT =
|
|
20
|
+
'Lorem ipsum dolor sit amet, constitutor adipiscing elit. Nam vulputate augue vel ligula.';
|
|
21
|
+
|
|
22
|
+
export const DEFAULT_ARC_ORBIT_ITEMS: readonly [
|
|
23
|
+
IResolvedArcOrbitItem,
|
|
24
|
+
IResolvedArcOrbitItem,
|
|
25
|
+
IResolvedArcOrbitItem,
|
|
26
|
+
IResolvedArcOrbitItem,
|
|
27
|
+
] = [
|
|
28
|
+
{
|
|
29
|
+
id: '01',
|
|
30
|
+
title: 'Add Text Here',
|
|
31
|
+
description: DEFAULT_LOREM_TEXT,
|
|
32
|
+
color: DEFAULT_ARC_ORBIT_COLOR,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: '02',
|
|
36
|
+
title: 'Add Text Here',
|
|
37
|
+
description: DEFAULT_LOREM_TEXT,
|
|
38
|
+
color: DEFAULT_ARC_ORBIT_COLOR,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: '03',
|
|
42
|
+
title: 'Add Text Here',
|
|
43
|
+
description: DEFAULT_LOREM_TEXT,
|
|
44
|
+
color: DEFAULT_ARC_ORBIT_COLOR,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: '04',
|
|
48
|
+
title: 'Add Text Here',
|
|
49
|
+
description: DEFAULT_LOREM_TEXT,
|
|
50
|
+
color: DEFAULT_ARC_ORBIT_COLOR,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
export interface IResolveArcOrbitItemsOptions {
|
|
55
|
+
readonly items?: readonly IArcOrbitItem[];
|
|
56
|
+
readonly defaultColor?: string;
|
|
57
|
+
readonly count?: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function resolveArcOrbitItems(
|
|
61
|
+
options: IResolveArcOrbitItemsOptions = {},
|
|
62
|
+
): readonly IResolvedArcOrbitItem[] {
|
|
63
|
+
const { items, defaultColor = DEFAULT_ARC_ORBIT_COLOR, count = 3 } = options;
|
|
64
|
+
|
|
65
|
+
const result: IResolvedArcOrbitItem[] = [];
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < count; i++) {
|
|
68
|
+
const custom = items?.[i];
|
|
69
|
+
const defaultItem = DEFAULT_ARC_ORBIT_ITEMS[i];
|
|
70
|
+
|
|
71
|
+
const id =
|
|
72
|
+
custom?.id !== undefined
|
|
73
|
+
? custom.id
|
|
74
|
+
: (defaultItem?.id ?? String(i + 1).padStart(2, '0'));
|
|
75
|
+
|
|
76
|
+
const title = custom?.title ?? defaultItem?.title ?? 'Add Text Here';
|
|
77
|
+
const description =
|
|
78
|
+
custom?.description ?? defaultItem?.description ?? DEFAULT_LOREM_TEXT;
|
|
79
|
+
const color = custom?.color ?? defaultColor;
|
|
80
|
+
const textColor = custom?.textColor ?? defaultItem?.textColor;
|
|
81
|
+
|
|
82
|
+
result.push({
|
|
83
|
+
id,
|
|
84
|
+
title,
|
|
85
|
+
description,
|
|
86
|
+
color,
|
|
87
|
+
textColor,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ComputedRef, InjectionKey } from 'vue';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
IGearTriadItem,
|
|
5
|
+
IResolvedGearTriadItem,
|
|
6
|
+
} from './resolveGearTriadItems';
|
|
7
|
+
|
|
8
|
+
export interface IGearTriadRegistration {
|
|
9
|
+
readonly index: number;
|
|
10
|
+
readonly item: ComputedRef<IResolvedGearTriadItem>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IGearTriadRootContext {
|
|
14
|
+
readonly animation: ComputedRef<boolean>;
|
|
15
|
+
readonly isShifted: ComputedRef<boolean>;
|
|
16
|
+
readonly currentStep: ComputedRef<number>;
|
|
17
|
+
readonly activeOptionIndex: ComputedRef<number>;
|
|
18
|
+
readonly hasContents: ComputedRef<boolean>;
|
|
19
|
+
readonly registerCallout: (
|
|
20
|
+
override?: ComputedRef<IGearTriadItem> | (() => IGearTriadItem),
|
|
21
|
+
) => IGearTriadRegistration;
|
|
22
|
+
readonly registerContents: () => void;
|
|
23
|
+
readonly items: ComputedRef<
|
|
24
|
+
readonly [
|
|
25
|
+
IResolvedGearTriadItem,
|
|
26
|
+
IResolvedGearTriadItem,
|
|
27
|
+
IResolvedGearTriadItem,
|
|
28
|
+
]
|
|
29
|
+
>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface IGearTriadCalloutContext {
|
|
33
|
+
readonly item: ComputedRef<IResolvedGearTriadItem>;
|
|
34
|
+
readonly index: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface IGearTriadContentsContext {
|
|
38
|
+
readonly activeItem: ComputedRef<IResolvedGearTriadItem>;
|
|
39
|
+
readonly activeOptionIndex: ComputedRef<number>;
|
|
40
|
+
readonly registerContent: (option?: number) => { index: number };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const GEAR_TRIAD_ROOT_KEY: InjectionKey<IGearTriadRootContext> = Symbol(
|
|
44
|
+
'GEAR_TRIAD_ROOT_KEY',
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export const GEAR_TRIAD_CALLOUT_KEY: InjectionKey<IGearTriadCalloutContext> =
|
|
48
|
+
Symbol('GEAR_TRIAD_CALLOUT_KEY');
|
|
49
|
+
|
|
50
|
+
export const GEAR_TRIAD_CONTENTS_KEY: InjectionKey<IGearTriadContentsContext> =
|
|
51
|
+
Symbol('GEAR_TRIAD_CONTENTS_KEY');
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
export interface IGearTriadPoint {
|
|
2
|
+
readonly x: number;
|
|
3
|
+
readonly y: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface IGearTriadPetalGeometry {
|
|
7
|
+
readonly facePath: string;
|
|
8
|
+
readonly valleyPath: string;
|
|
9
|
+
readonly leftFoldPath: string;
|
|
10
|
+
readonly rightFoldPath: string;
|
|
11
|
+
readonly iconPosition: IGearTriadPoint;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IGearTriadSectorGeometry extends IGearTriadPetalGeometry {}
|
|
15
|
+
|
|
16
|
+
export interface IGearTriadGeometry {
|
|
17
|
+
readonly viewBoxWidth: number;
|
|
18
|
+
readonly viewBoxHeight: number;
|
|
19
|
+
readonly centerX: number;
|
|
20
|
+
readonly centerY: number;
|
|
21
|
+
readonly hubRadius: number;
|
|
22
|
+
readonly baseGearPath: string;
|
|
23
|
+
readonly valleyPath: string;
|
|
24
|
+
/**
|
|
25
|
+
* One canonical petal geometry (facing South, 270 deg).
|
|
26
|
+
* Reused for all 3 sectors via 0 deg (Pink), 120 deg (Cyan), and 240 deg (Orange).
|
|
27
|
+
*/
|
|
28
|
+
readonly petal: IGearTriadPetalGeometry;
|
|
29
|
+
readonly cyanSector: IGearTriadSectorGeometry;
|
|
30
|
+
readonly orangeSector: IGearTriadSectorGeometry;
|
|
31
|
+
readonly pinkSector: IGearTriadSectorGeometry;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Polar to Cartesian conversion in SVG screen space:
|
|
36
|
+
* - 0 deg = East (3 o'clock)
|
|
37
|
+
* - 90 deg = North (12 o'clock, straight UP)
|
|
38
|
+
* - 180 deg = West (9 o'clock)
|
|
39
|
+
* - 270 deg = South (6 o'clock, straight DOWN)
|
|
40
|
+
*/
|
|
41
|
+
function polarToCartesian(
|
|
42
|
+
cx: number,
|
|
43
|
+
cy: number,
|
|
44
|
+
radius: number,
|
|
45
|
+
angleInDegrees: number,
|
|
46
|
+
): IGearTriadPoint {
|
|
47
|
+
const radians = (angleInDegrees * Math.PI) / 180;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
x: Number((cx + radius * Math.cos(radians)).toFixed(2)),
|
|
51
|
+
y: Number((cy - radius * Math.sin(radians)).toFixed(2)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function rotatePoint(
|
|
56
|
+
p: IGearTriadPoint,
|
|
57
|
+
cx: number,
|
|
58
|
+
cy: number,
|
|
59
|
+
degrees: number,
|
|
60
|
+
): IGearTriadPoint {
|
|
61
|
+
const rad = (degrees * Math.PI) / 180;
|
|
62
|
+
const dx = p.x - cx;
|
|
63
|
+
const dy = p.y - cy;
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
x: Number((dx * Math.cos(rad) - dy * Math.sin(rad) + cx).toFixed(2)),
|
|
67
|
+
y: Number((dx * Math.sin(rad) + dy * Math.cos(rad) + cy).toFixed(2)),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function createGearTriadGeometry(): IGearTriadGeometry {
|
|
72
|
+
const viewBoxWidth = 540;
|
|
73
|
+
const viewBoxHeight = 480;
|
|
74
|
+
const centerX = 270;
|
|
75
|
+
const centerY = 220;
|
|
76
|
+
const rOut = 180;
|
|
77
|
+
const rNotch = 128;
|
|
78
|
+
const hubRadius = 54;
|
|
79
|
+
|
|
80
|
+
// Base 6-tooth gear with rounded valleys (6 teeth at 0, 60, 120, 180, 240, 300 deg)
|
|
81
|
+
const toothCenters = [0, 60, 120, 180, 240, 300];
|
|
82
|
+
let baseGearPath = '';
|
|
83
|
+
for (let i = 0; i < toothCenters.length; i++) {
|
|
84
|
+
const th = toothCenters[i] ?? 0;
|
|
85
|
+
const p1 = polarToCartesian(centerX, centerY, rOut, th - 10);
|
|
86
|
+
const p2 = polarToCartesian(centerX, centerY, rOut, th + 10);
|
|
87
|
+
const p3 = polarToCartesian(centerX, centerY, rNotch, th + 20);
|
|
88
|
+
const p4 = polarToCartesian(centerX, centerY, rNotch, th + 40);
|
|
89
|
+
if (i === 0) {
|
|
90
|
+
baseGearPath += `M ${p1.x} ${p1.y}`;
|
|
91
|
+
} else {
|
|
92
|
+
baseGearPath += ` L ${p1.x} ${p1.y}`;
|
|
93
|
+
}
|
|
94
|
+
baseGearPath += ` L ${p2.x} ${p2.y} L ${p3.x} ${p3.y} A ${rNotch} ${rNotch} 0 0 0 ${p4.x} ${p4.y}`;
|
|
95
|
+
}
|
|
96
|
+
baseGearPath += ' Z';
|
|
97
|
+
|
|
98
|
+
// ONE CANONICAL PETAL SHAPE (pointing South / 270 deg):
|
|
99
|
+
// Reused across all 3 sectors via 0 deg (Pink), 120 deg (Cyan), and 240 deg (Orange)
|
|
100
|
+
const p0 = polarToCartesian(centerX, centerY, hubRadius, 230);
|
|
101
|
+
const p1 = polarToCartesian(centerX, centerY, rOut, 230);
|
|
102
|
+
const p2 = polarToCartesian(centerX, centerY, rOut, 250);
|
|
103
|
+
const p3a = polarToCartesian(centerX, centerY, rNotch, 260);
|
|
104
|
+
const p3b = polarToCartesian(centerX, centerY, rNotch, 280);
|
|
105
|
+
const p4 = polarToCartesian(centerX, centerY, rOut, 290);
|
|
106
|
+
const p5 = polarToCartesian(centerX, centerY, rOut, 310);
|
|
107
|
+
const p6 = polarToCartesian(centerX, centerY, hubRadius, 310);
|
|
108
|
+
|
|
109
|
+
const petalFacePath = [
|
|
110
|
+
`M ${p0.x} ${p0.y}`,
|
|
111
|
+
`L ${p1.x} ${p1.y}`,
|
|
112
|
+
`L ${p2.x} ${p2.y}`,
|
|
113
|
+
`L ${p3a.x} ${p3a.y}`,
|
|
114
|
+
`A ${rNotch} ${rNotch} 0 0 0 ${p3b.x} ${p3b.y}`,
|
|
115
|
+
`L ${p4.x} ${p4.y}`,
|
|
116
|
+
`L ${p5.x} ${p5.y}`,
|
|
117
|
+
`L ${p6.x} ${p6.y}`,
|
|
118
|
+
`A ${hubRadius} ${hubRadius} 0 0 1 ${p0.x} ${p0.y}`,
|
|
119
|
+
'Z',
|
|
120
|
+
].join(' ');
|
|
121
|
+
|
|
122
|
+
// The unified canonical shape between the colored petals (centered at 210 deg):
|
|
123
|
+
// Reused across all 3 inter-sector positions via 0 deg, 120 deg, and 240 deg rotations.
|
|
124
|
+
const pvFlankPink = polarToCartesian(centerX, centerY, rOut, 230);
|
|
125
|
+
const pvNotchPink = polarToCartesian(centerX, centerY, rNotch, 220);
|
|
126
|
+
const pvNotchCyan = polarToCartesian(centerX, centerY, rNotch, 200);
|
|
127
|
+
const pvFlankCyan = polarToCartesian(centerX, centerY, rOut, 190);
|
|
128
|
+
const pvHubCyan = polarToCartesian(centerX, centerY, hubRadius, 190);
|
|
129
|
+
const pvHubPink = polarToCartesian(centerX, centerY, hubRadius, 230);
|
|
130
|
+
|
|
131
|
+
const valleyPath = [
|
|
132
|
+
`M ${pvFlankPink.x} ${pvFlankPink.y}`,
|
|
133
|
+
`L ${pvNotchPink.x} ${pvNotchPink.y}`,
|
|
134
|
+
`A ${rNotch} ${rNotch} 0 0 1 ${pvNotchCyan.x} ${pvNotchCyan.y}`,
|
|
135
|
+
`L ${pvFlankCyan.x} ${pvFlankCyan.y}`,
|
|
136
|
+
`L ${pvHubCyan.x} ${pvHubCyan.y}`,
|
|
137
|
+
`A ${hubRadius} ${hubRadius} 0 0 0 ${pvHubPink.x} ${pvHubPink.y}`,
|
|
138
|
+
'Z',
|
|
139
|
+
].join(' ');
|
|
140
|
+
|
|
141
|
+
// Legacy fold paths maintained for backwards compatibility
|
|
142
|
+
const pValley220 = polarToCartesian(centerX, centerY, rNotch, 220);
|
|
143
|
+
const pValley210 = polarToCartesian(centerX, centerY, rNotch, 210);
|
|
144
|
+
const pHub210 = polarToCartesian(centerX, centerY, hubRadius, 210);
|
|
145
|
+
|
|
146
|
+
const leftFoldPath = [
|
|
147
|
+
`M ${p1.x} ${p1.y}`,
|
|
148
|
+
`L ${pValley220.x} ${pValley220.y}`,
|
|
149
|
+
`A ${rNotch} ${rNotch} 0 0 0 ${pValley210.x} ${pValley210.y}`,
|
|
150
|
+
`L ${pHub210.x} ${pHub210.y}`,
|
|
151
|
+
`A ${hubRadius} ${hubRadius} 0 0 1 ${p0.x} ${p0.y}`,
|
|
152
|
+
'Z',
|
|
153
|
+
].join(' ');
|
|
154
|
+
|
|
155
|
+
const pValley320 = polarToCartesian(centerX, centerY, rNotch, 320);
|
|
156
|
+
const pValley330 = polarToCartesian(centerX, centerY, rNotch, 330);
|
|
157
|
+
const pHub330 = polarToCartesian(centerX, centerY, hubRadius, 330);
|
|
158
|
+
|
|
159
|
+
const rightFoldPath = [
|
|
160
|
+
`M ${p5.x} ${p5.y}`,
|
|
161
|
+
`L ${pValley320.x} ${pValley320.y}`,
|
|
162
|
+
`A ${rNotch} ${rNotch} 0 0 1 ${pValley330.x} ${pValley330.y}`,
|
|
163
|
+
`L ${pHub330.x} ${pHub330.y}`,
|
|
164
|
+
`A ${hubRadius} ${hubRadius} 0 0 0 ${p6.x} ${p6.y}`,
|
|
165
|
+
'Z',
|
|
166
|
+
].join(' ');
|
|
167
|
+
|
|
168
|
+
const canonicalIconPos = polarToCartesian(centerX, centerY, 105, 270);
|
|
169
|
+
|
|
170
|
+
const canonicalPetal: IGearTriadPetalGeometry = {
|
|
171
|
+
facePath: petalFacePath,
|
|
172
|
+
valleyPath,
|
|
173
|
+
leftFoldPath,
|
|
174
|
+
rightFoldPath,
|
|
175
|
+
iconPosition: canonicalIconPos,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// The 3 sectors reuse the canonical petal rotated by 120 deg intervals:
|
|
179
|
+
// - Pink (Option 3, Bottom): rotation 0 deg
|
|
180
|
+
// - Cyan (Option 1, Top-Left): rotation 120 deg
|
|
181
|
+
// - Orange (Option 2, Top-Right): rotation 240 deg
|
|
182
|
+
const pinkSector: IGearTriadSectorGeometry = {
|
|
183
|
+
...canonicalPetal,
|
|
184
|
+
iconPosition: canonicalIconPos,
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const cyanSector: IGearTriadSectorGeometry = {
|
|
188
|
+
...canonicalPetal,
|
|
189
|
+
iconPosition: rotatePoint(canonicalIconPos, centerX, centerY, 120),
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const orangeSector: IGearTriadSectorGeometry = {
|
|
193
|
+
...canonicalPetal,
|
|
194
|
+
iconPosition: rotatePoint(canonicalIconPos, centerX, centerY, 240),
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
viewBoxWidth,
|
|
199
|
+
viewBoxHeight,
|
|
200
|
+
centerX,
|
|
201
|
+
centerY,
|
|
202
|
+
hubRadius,
|
|
203
|
+
baseGearPath,
|
|
204
|
+
valleyPath,
|
|
205
|
+
petal: canonicalPetal,
|
|
206
|
+
cyanSector,
|
|
207
|
+
orangeSector,
|
|
208
|
+
pinkSector,
|
|
209
|
+
};
|
|
210
|
+
}
|