worldorbit 3.2.2 → 5.0.0
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 +543 -543
- package/dist/browser/core/dist/atlas-edit.js +146 -1
- package/dist/browser/core/dist/atlas-validate.js +105 -10
- package/dist/browser/core/dist/draft-parse.js +461 -17
- package/dist/browser/core/dist/draft.d.ts +2 -1
- package/dist/browser/core/dist/draft.js +26 -4
- package/dist/browser/core/dist/format.js +126 -5
- package/dist/browser/core/dist/index.d.ts +1 -0
- package/dist/browser/core/dist/index.js +1 -0
- package/dist/browser/core/dist/load.js +12 -2
- package/dist/browser/core/dist/normalize.js +1 -0
- package/dist/browser/core/dist/scene.js +226 -5
- package/dist/browser/core/dist/schema.js +11 -1
- package/dist/browser/core/dist/solver.d.ts +33 -0
- package/dist/browser/core/dist/solver.js +99 -0
- package/dist/browser/core/dist/spatial-scene.js +56 -0
- package/dist/browser/core/dist/types.d.ts +130 -4
- package/dist/browser/editor/dist/editor.js +844 -719
- package/dist/browser/editor/dist/types.d.ts +2 -1
- package/dist/browser/viewer/dist/minimap.js +9 -7
- package/dist/browser/viewer/dist/render.js +78 -18
- package/dist/browser/viewer/dist/runtime-3d.js +2 -0
- package/dist/browser/viewer/dist/theme.js +1 -0
- package/dist/browser/viewer/dist/types.d.ts +7 -0
- package/dist/browser/viewer/dist/viewer.js +34 -3
- package/dist/obsidian-plugin/README.md +141 -124
- package/dist/obsidian-plugin/main.js +82 -68
- package/dist/unpkg/core/dist/atlas-edit.js +146 -1
- package/dist/unpkg/core/dist/atlas-validate.js +105 -10
- package/dist/unpkg/core/dist/draft-parse.js +461 -17
- package/dist/unpkg/core/dist/draft.d.ts +2 -1
- package/dist/unpkg/core/dist/draft.js +26 -4
- package/dist/unpkg/core/dist/format.js +126 -5
- package/dist/unpkg/core/dist/index.d.ts +1 -0
- package/dist/unpkg/core/dist/index.js +1 -0
- package/dist/unpkg/core/dist/load.js +12 -2
- package/dist/unpkg/core/dist/normalize.js +1 -0
- package/dist/unpkg/core/dist/scene.js +226 -5
- package/dist/unpkg/core/dist/schema.js +11 -1
- package/dist/unpkg/core/dist/solver.d.ts +33 -0
- package/dist/unpkg/core/dist/solver.js +99 -0
- package/dist/unpkg/core/dist/spatial-scene.js +56 -0
- package/dist/unpkg/core/dist/types.d.ts +130 -4
- package/dist/unpkg/editor/dist/editor.js +844 -719
- package/dist/unpkg/editor/dist/types.d.ts +2 -1
- package/dist/unpkg/viewer/dist/minimap.js +9 -7
- package/dist/unpkg/viewer/dist/render.js +78 -18
- package/dist/unpkg/viewer/dist/runtime-3d.js +2 -0
- package/dist/unpkg/viewer/dist/theme.js +1 -0
- package/dist/unpkg/viewer/dist/types.d.ts +7 -0
- package/dist/unpkg/viewer/dist/viewer.js +34 -3
- package/dist/unpkg/worldorbit-core.min.js +12 -12
- package/dist/unpkg/worldorbit-editor.min.js +381 -340
- package/dist/unpkg/worldorbit-markdown.min.js +47 -33
- package/dist/unpkg/worldorbit-viewer.min.js +238 -224
- package/dist/unpkg/worldorbit.js +1218 -46
- package/dist/unpkg/worldorbit.min.js +242 -228
- package/package.json +5 -1
- package/packages/core/dist/atlas-edit.js +146 -1
- package/packages/core/dist/atlas-validate.js +105 -10
- package/packages/core/dist/draft-parse.js +461 -17
- package/packages/core/dist/draft.d.ts +2 -1
- package/packages/core/dist/draft.js +26 -4
- package/packages/core/dist/format.js +126 -5
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/load.js +12 -2
- package/packages/core/dist/normalize.js +1 -0
- package/packages/core/dist/scene.js +226 -5
- package/packages/core/dist/schema.js +11 -1
- package/packages/core/dist/solver.d.ts +33 -0
- package/packages/core/dist/solver.js +99 -0
- package/packages/core/dist/spatial-scene.js +56 -0
- package/packages/core/dist/types.d.ts +130 -4
- package/packages/editor/dist/editor.js +844 -719
- package/packages/editor/dist/types.d.ts +2 -1
- package/packages/viewer/dist/minimap.js +9 -7
- package/packages/viewer/dist/render.js +78 -18
- package/packages/viewer/dist/runtime-3d.js +2 -0
- package/packages/viewer/dist/theme.js +1 -0
- package/packages/viewer/dist/types.d.ts +7 -0
- package/packages/viewer/dist/viewer.js +34 -3
|
@@ -9,6 +9,7 @@ export interface WorldOrbitEditorSnapshot {
|
|
|
9
9
|
diagnostics: AtlasResolvedDiagnostic[];
|
|
10
10
|
selection: WorldOrbitEditorSelection | null;
|
|
11
11
|
}
|
|
12
|
+
export type WorldOrbitEditorObjectType = WorldOrbitObject["type"] | "craft";
|
|
12
13
|
export interface WorldOrbitEditorOptions {
|
|
13
14
|
source?: string;
|
|
14
15
|
atlasDocument?: WorldOrbitAtlasDocument;
|
|
@@ -40,7 +41,7 @@ export interface WorldOrbitEditor {
|
|
|
40
41
|
canRedo(): boolean;
|
|
41
42
|
undo(): boolean;
|
|
42
43
|
redo(): boolean;
|
|
43
|
-
addObject(type?:
|
|
44
|
+
addObject(type?: WorldOrbitEditorObjectType): string;
|
|
44
45
|
addEvent(): string;
|
|
45
46
|
addViewpoint(): string;
|
|
46
47
|
addAnnotation(): string;
|
|
@@ -28,13 +28,13 @@ export function renderViewerMinimap(scene, state, visibleObjects) {
|
|
|
28
28
|
return `<circle cx="${formatNumber(x)}" cy="${formatNumber(y)}" r="${formatNumber(radius)}" fill="${fill}" fill-opacity="0.92" />`;
|
|
29
29
|
})
|
|
30
30
|
.join("");
|
|
31
|
-
return `<div data-worldorbit-minimap="true" style="position:absolute;right:16px;bottom:16px;width:${MINIMAP_WIDTH}px;height:${MINIMAP_HEIGHT}px;padding:8px;border-radius:16px;background:rgba(5, 14, 22, 0.78);border:1px solid rgba(179, 216, 255, 0.16);box-shadow:0 14px 28px rgba(0, 0, 0, 0.24);backdrop-filter:blur(8px);pointer-events:none;">
|
|
32
|
-
<svg width="${MINIMAP_WIDTH}" height="${MINIMAP_HEIGHT}" viewBox="0 0 ${MINIMAP_WIDTH} ${MINIMAP_HEIGHT}" role="presentation" aria-hidden="true">
|
|
33
|
-
<rect x="0.5" y="0.5" width="${MINIMAP_WIDTH - 1}" height="${MINIMAP_HEIGHT - 1}" rx="12" ry="12" fill="rgba(7, 17, 27, 0.85)" stroke="rgba(179, 216, 255, 0.18)" />
|
|
34
|
-
<rect x="${formatNumber(bounds.minX * scale + translateX)}" y="${formatNumber(bounds.minY * scale + translateY)}" width="${formatNumber(bounds.width * scale)}" height="${formatNumber(bounds.height * scale)}" rx="10" ry="10" fill="rgba(163, 209, 255, 0.04)" stroke="rgba(163, 209, 255, 0.16)" />
|
|
35
|
-
${objectsMarkup}
|
|
36
|
-
<rect x="${formatNumber(viewport.minX * scale + translateX)}" y="${formatNumber(viewport.minY * scale + translateY)}" width="${formatNumber(viewport.width * scale)}" height="${formatNumber(viewport.height * scale)}" rx="8" ry="8" fill="rgba(255, 180, 100, 0.09)" stroke="rgba(255, 180, 100, 0.88)" stroke-width="1.4" />
|
|
37
|
-
</svg>
|
|
31
|
+
return `<div data-worldorbit-minimap="true" style="position:absolute;right:16px;bottom:16px;width:${MINIMAP_WIDTH}px;height:${MINIMAP_HEIGHT}px;padding:8px;border-radius:16px;background:rgba(5, 14, 22, 0.78);border:1px solid rgba(179, 216, 255, 0.16);box-shadow:0 14px 28px rgba(0, 0, 0, 0.24);backdrop-filter:blur(8px);pointer-events:none;">
|
|
32
|
+
<svg width="${MINIMAP_WIDTH}" height="${MINIMAP_HEIGHT}" viewBox="0 0 ${MINIMAP_WIDTH} ${MINIMAP_HEIGHT}" role="presentation" aria-hidden="true">
|
|
33
|
+
<rect x="0.5" y="0.5" width="${MINIMAP_WIDTH - 1}" height="${MINIMAP_HEIGHT - 1}" rx="12" ry="12" fill="rgba(7, 17, 27, 0.85)" stroke="rgba(179, 216, 255, 0.18)" />
|
|
34
|
+
<rect x="${formatNumber(bounds.minX * scale + translateX)}" y="${formatNumber(bounds.minY * scale + translateY)}" width="${formatNumber(bounds.width * scale)}" height="${formatNumber(bounds.height * scale)}" rx="10" ry="10" fill="rgba(163, 209, 255, 0.04)" stroke="rgba(163, 209, 255, 0.16)" />
|
|
35
|
+
${objectsMarkup}
|
|
36
|
+
<rect x="${formatNumber(viewport.minX * scale + translateX)}" y="${formatNumber(viewport.minY * scale + translateY)}" width="${formatNumber(viewport.width * scale)}" height="${formatNumber(viewport.height * scale)}" rx="8" ry="8" fill="rgba(255, 180, 100, 0.09)" stroke="rgba(255, 180, 100, 0.88)" stroke-width="1.4" />
|
|
37
|
+
</svg>
|
|
38
38
|
</div>`;
|
|
39
39
|
}
|
|
40
40
|
function minimapColorForObject(type) {
|
|
@@ -52,6 +52,8 @@ function minimapColorForObject(type) {
|
|
|
52
52
|
return "#a7a5b8";
|
|
53
53
|
case "comet":
|
|
54
54
|
return "#9ce7ff";
|
|
55
|
+
case "craft":
|
|
56
|
+
return "#ffb47f";
|
|
55
57
|
case "structure":
|
|
56
58
|
return "#ff7f5f";
|
|
57
59
|
case "phenomenon":
|
|
@@ -40,6 +40,13 @@ export function renderSceneToSvg(scene, options = {}) {
|
|
|
40
40
|
.map((relation) => `<line class="wo-relation" x1="${relation.x1}" y1="${relation.y1}" x2="${relation.x2}" y2="${relation.y2}" data-render-id="${escapeXml(relation.renderId)}" data-relation-id="${escapeAttribute(relation.relationId)}" />`)
|
|
41
41
|
.join("")
|
|
42
42
|
: "";
|
|
43
|
+
const trajectoryMarkup = layers.trajectories
|
|
44
|
+
? renderTrajectoryLayer(scene, visibleObjectIds, {
|
|
45
|
+
showLabels: options.showTrajectoryLabels ?? true,
|
|
46
|
+
showWaypoints: options.showTrajectoryWaypoints ?? true,
|
|
47
|
+
includeStructures: layers.structures,
|
|
48
|
+
})
|
|
49
|
+
: "";
|
|
43
50
|
const eventMarkup = layers.events
|
|
44
51
|
? scene.events
|
|
45
52
|
.filter((event) => !event.hidden)
|
|
@@ -78,25 +85,32 @@ export function renderSceneToSvg(scene, options = {}) {
|
|
|
78
85
|
<stop offset="0%" stop-color="${theme.starGlow}" stop-opacity="0.95" />
|
|
79
86
|
<stop offset="100%" stop-color="${theme.starCore}" stop-opacity="0" />
|
|
80
87
|
</radialGradient>
|
|
81
|
-
<radialGradient id="wo-bg-glow" cx="20%" cy="10%" r="90%">
|
|
82
|
-
<stop offset="0%" stop-color="${theme.backgroundGlow}" />
|
|
83
|
-
<stop offset="100%" stop-color="transparent" />
|
|
84
|
-
</radialGradient>
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
<radialGradient id="wo-bg-glow" cx="20%" cy="10%" r="90%">
|
|
89
|
+
<stop offset="0%" stop-color="${theme.backgroundGlow}" />
|
|
90
|
+
<stop offset="100%" stop-color="transparent" />
|
|
91
|
+
</radialGradient>
|
|
92
|
+
<marker id="wo-trajectory-arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto" markerUnits="strokeWidth">
|
|
93
|
+
<path d="M 0 0 L 12 6 L 0 12 z" fill="${theme.accent}" />
|
|
94
|
+
</marker>
|
|
95
|
+
${imageDefinitions}
|
|
96
|
+
</defs>
|
|
87
97
|
<style>
|
|
88
98
|
.wo-bg { fill: url(#wo-bg); }
|
|
89
99
|
.wo-bg-glow { fill: url(#wo-bg-glow); }
|
|
90
100
|
.wo-grid { fill: none; stroke: ${theme.guide}; stroke-width: 1; }
|
|
91
101
|
.wo-orbit { fill: none; stroke: ${theme.orbit}; stroke-width: 1.5; }
|
|
92
|
-
.wo-orbit-back { opacity: 0.38; stroke-dasharray: 8 6; }
|
|
93
|
-
.wo-orbit-front { opacity: 0.9; }
|
|
102
|
+
.wo-orbit-back { opacity: 0.38; stroke-dasharray: 8 6; }
|
|
103
|
+
.wo-orbit-front { opacity: 0.9; }
|
|
94
104
|
.wo-orbit-band { stroke: ${theme.orbitBand}; stroke-linecap: round; }
|
|
95
105
|
.wo-relation { stroke: ${theme.relation}; stroke-width: 2; stroke-dasharray: 10 6; }
|
|
106
|
+
.wo-trajectory { fill: none; stroke: ${theme.accent}; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; opacity: 0.92; }
|
|
107
|
+
.wo-trajectory-waypoint { fill: ${theme.spaceFog}; stroke: ${theme.selected}; stroke-width: 1.4; }
|
|
108
|
+
.wo-trajectory-label { fill: ${theme.accent}; font-family: ${theme.fontFamily}; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
|
|
109
|
+
.wo-trajectory-date { fill: ${theme.muted}; font-family: ${theme.fontFamily}; font-weight: 500; }
|
|
96
110
|
.wo-event-line { stroke: ${theme.accent}; stroke-width: 1.6; stroke-dasharray: 5 5; opacity: 0.72; }
|
|
97
|
-
.wo-event-node { fill: ${theme.accent}; stroke: ${theme.selected}; stroke-width: 1.4; opacity: 0.92; }
|
|
98
|
-
.wo-event-label { fill: ${theme.accent}; font-family: ${theme.fontFamily}; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
|
|
99
|
-
.wo-leader { stroke: ${theme.leader}; stroke-width: 1.5; stroke-dasharray: 6 5; }
|
|
111
|
+
.wo-event-node { fill: ${theme.accent}; stroke: ${theme.selected}; stroke-width: 1.4; opacity: 0.92; }
|
|
112
|
+
.wo-event-label { fill: ${theme.accent}; font-family: ${theme.fontFamily}; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
|
|
113
|
+
.wo-leader { stroke: ${theme.leader}; stroke-width: 1.5; stroke-dasharray: 6 5; }
|
|
100
114
|
.wo-label { fill: ${theme.ink}; font-family: ${theme.fontFamily}; font-weight: 600; letter-spacing: 0.02em; }
|
|
101
115
|
.wo-label-secondary { fill: ${theme.muted}; font-family: ${theme.fontFamily}; font-weight: 500; }
|
|
102
116
|
.wo-title { fill: ${theme.ink}; font: 700 24px ${theme.displayFont}; letter-spacing: 0.06em; text-transform: uppercase; }
|
|
@@ -127,14 +141,15 @@ export function renderSceneToSvg(scene, options = {}) {
|
|
|
127
141
|
<g data-worldorbit-world="true">
|
|
128
142
|
<g data-worldorbit-camera-root="${WORLD_LAYER_ID}" id="${WORLD_LAYER_ID}">
|
|
129
143
|
<g data-worldorbit-world-content="true">
|
|
130
|
-
${layers.orbits ? `<g data-layer-id="orbits-back">${orbitMarkup.back}</g>` : ""}
|
|
131
|
-
${layers.guides ? `<g data-layer-id="guides">${leaderMarkup}</g>` : ""}
|
|
144
|
+
${layers.orbits ? `<g data-layer-id="orbits-back">${orbitMarkup.back}</g>` : ""}
|
|
145
|
+
${layers.guides ? `<g data-layer-id="guides">${leaderMarkup}</g>` : ""}
|
|
132
146
|
${layers.relations ? `<g data-layer-id="relations">${relationMarkup}</g>` : ""}
|
|
133
147
|
${layers.events ? `<g data-layer-id="events">${eventMarkup}</g>` : ""}
|
|
134
148
|
${layers.objects ? `<g data-layer-id="objects">${objectMarkup}</g>` : ""}
|
|
135
149
|
${layers.orbits ? `<g data-layer-id="orbits-front">${orbitMarkup.front}</g>` : ""}
|
|
150
|
+
${layers.trajectories ? `<g data-layer-id="trajectories">${trajectoryMarkup}</g>` : ""}
|
|
136
151
|
${layers.labels ? `<g data-layer-id="labels">${labelMarkup}</g>` : ""}
|
|
137
|
-
</g>
|
|
152
|
+
</g>
|
|
138
153
|
</g>
|
|
139
154
|
</g>
|
|
140
155
|
</svg>`;
|
|
@@ -152,10 +167,51 @@ function renderSceneEventOverlay(scene, event, visibleObjectIds, theme) {
|
|
|
152
167
|
const lineMarkup = participants
|
|
153
168
|
.map((object) => `<line class="wo-event-line" x1="${event.x}" y1="${event.y}" x2="${object.x}" y2="${object.y}" stroke="${escapeAttribute(stroke)}" data-event-id="${escapeAttribute(event.eventId)}" data-object-id="${escapeAttribute(object.objectId)}" />`)
|
|
154
169
|
.join("");
|
|
155
|
-
return `<g class="wo-event" data-render-id="${escapeXml(event.renderId)}" data-event-id="${escapeAttribute(event.eventId)}">
|
|
156
|
-
${lineMarkup}
|
|
157
|
-
<circle class="wo-event-node" cx="${event.x}" cy="${event.y}" r="5" fill="${escapeAttribute(stroke)}" />
|
|
158
|
-
<text class="wo-event-label" x="${event.x}" y="${event.y - 10}" text-anchor="middle" font-size="10">${escapeXml(label)}</text>
|
|
170
|
+
return `<g class="wo-event" data-render-id="${escapeXml(event.renderId)}" data-event-id="${escapeAttribute(event.eventId)}">
|
|
171
|
+
${lineMarkup}
|
|
172
|
+
<circle class="wo-event-node" cx="${event.x}" cy="${event.y}" r="5" fill="${escapeAttribute(stroke)}" />
|
|
173
|
+
<text class="wo-event-label" x="${event.x}" y="${event.y - 10}" text-anchor="middle" font-size="10">${escapeXml(label)}</text>
|
|
174
|
+
</g>`;
|
|
175
|
+
}
|
|
176
|
+
function renderTrajectoryLayer(scene, visibleObjectIds, options) {
|
|
177
|
+
return scene.trajectories
|
|
178
|
+
.filter((trajectory) => !trajectory.hidden)
|
|
179
|
+
.filter((trajectory) => trajectory.objectIds.length === 0 || trajectory.objectIds.some((objectId) => visibleObjectIds.has(objectId)))
|
|
180
|
+
.filter((trajectory) => options.includeStructures ||
|
|
181
|
+
!trajectory.objectIds.some((objectId) => {
|
|
182
|
+
const object = scene.objects.find((entry) => entry.objectId === objectId)?.object;
|
|
183
|
+
return object ? isStructureLike(object) : false;
|
|
184
|
+
}))
|
|
185
|
+
.map((trajectory) => {
|
|
186
|
+
const stroke = trajectory.stroke ?? "#f0b464";
|
|
187
|
+
const markerEnd = trajectory.marker === "none" ? "" : ` marker-end="url(#wo-trajectory-arrow)"`;
|
|
188
|
+
const waypointMarkup = trajectory.showWaypoints && options.showWaypoints
|
|
189
|
+
? trajectory.waypoints
|
|
190
|
+
.filter((waypoint) => !waypoint.hidden)
|
|
191
|
+
.map((waypoint) => renderTrajectoryWaypoint(trajectory, waypoint, options.showLabels))
|
|
192
|
+
.join("")
|
|
193
|
+
: "";
|
|
194
|
+
return `<g class="wo-trajectory-group" data-render-id="${escapeXml(trajectory.renderId)}" data-trajectory-id="${escapeAttribute(trajectory.trajectoryId)}">
|
|
195
|
+
<path class="wo-trajectory wo-trajectory-${trajectory.mode}" d="${trajectory.path}" stroke="${escapeAttribute(stroke)}" stroke-width="${trajectory.strokeWidth}"${markerEnd} />
|
|
196
|
+
${waypointMarkup}
|
|
197
|
+
</g>`;
|
|
198
|
+
})
|
|
199
|
+
.join("");
|
|
200
|
+
}
|
|
201
|
+
function renderTrajectoryWaypoint(trajectory, waypoint, showLabels) {
|
|
202
|
+
const labelMarkup = showLabels && trajectory.labelMode !== "hidden"
|
|
203
|
+
? [
|
|
204
|
+
waypoint.label
|
|
205
|
+
? `<text class="wo-trajectory-label" x="${waypoint.x + 10}" y="${waypoint.y - 10}" font-size="10">${escapeXml(waypoint.label)}</text>`
|
|
206
|
+
: "",
|
|
207
|
+
waypoint.dateLabel
|
|
208
|
+
? `<text class="wo-trajectory-date" x="${waypoint.x + 10}" y="${waypoint.y + 4}" font-size="9">${escapeXml(waypoint.dateLabel)}</text>`
|
|
209
|
+
: "",
|
|
210
|
+
].join("")
|
|
211
|
+
: "";
|
|
212
|
+
return `<g class="wo-trajectory-waypoint-group" data-render-id="${escapeXml(waypoint.renderId)}" data-trajectory-id="${escapeAttribute(waypoint.trajectoryId)}">
|
|
213
|
+
<circle class="wo-trajectory-waypoint" cx="${waypoint.x}" cy="${waypoint.y}" r="4.5" />
|
|
214
|
+
${labelMarkup}
|
|
159
215
|
</g>`;
|
|
160
216
|
}
|
|
161
217
|
export function renderDocumentToSvg(document, options = {}) {
|
|
@@ -259,6 +315,8 @@ function renderObjectBody(object, x, y, radius, palette, options = {}) {
|
|
|
259
315
|
? `<circle cx="${x}" cy="${y}" r="${radius}" fill="transparent" stroke="${palette.stroke}" stroke-width="1.4" />`
|
|
260
316
|
: `<path d="M ${x - radius * 2} ${y + radius * 1.3} Q ${x - radius * 0.7} ${y + radius * 0.3} ${x - radius * 0.45} ${y}" fill="none" stroke="${tail}" stroke-width="${Math.max(2, radius * 0.8)}" stroke-linecap="round" opacity="0.85" />
|
|
261
317
|
<circle cx="${x}" cy="${y}" r="${radius}" fill="${fill}" stroke="${palette.stroke}" stroke-width="1.4" />`;
|
|
318
|
+
case "craft":
|
|
319
|
+
return `<polygon points="${diamondPoints(x, y, radius * 0.85)}" fill="${fill}" stroke="${palette.stroke}" stroke-width="1.4" />`;
|
|
262
320
|
case "structure":
|
|
263
321
|
return `<polygon points="${diamondPoints(x, y, radius)}" fill="${fill}" stroke="${palette.stroke}" stroke-width="1.4" />`;
|
|
264
322
|
case "phenomenon": {
|
|
@@ -443,6 +501,8 @@ function basePaletteForType(type, kind, theme) {
|
|
|
443
501
|
return { fill: "#9ce7ff", stroke: "#e7fbff" };
|
|
444
502
|
case "ring":
|
|
445
503
|
return { fill: "#e59f7d", stroke: "#fff0d3" };
|
|
504
|
+
case "craft":
|
|
505
|
+
return { fill: "#ffb47f", stroke: "#fff0d3" };
|
|
446
506
|
case "structure":
|
|
447
507
|
return { fill: theme.accentStrong, stroke: "#fff2ea" };
|
|
448
508
|
case "phenomenon":
|
|
@@ -43,6 +43,7 @@ export interface ViewerLayerOptions {
|
|
|
43
43
|
relations?: boolean;
|
|
44
44
|
events?: boolean;
|
|
45
45
|
orbits?: boolean;
|
|
46
|
+
trajectories?: boolean;
|
|
46
47
|
objects?: boolean;
|
|
47
48
|
labels?: boolean;
|
|
48
49
|
structures?: boolean;
|
|
@@ -77,6 +78,9 @@ export interface ViewerRenderOptions extends Omit<SvgRenderOptions, "selectedObj
|
|
|
77
78
|
viewMode?: WorldOrbitViewMode;
|
|
78
79
|
quality?: WorldOrbit3DQuality;
|
|
79
80
|
style3d?: WorldOrbit3DStyle;
|
|
81
|
+
trajectoryMode?: "illustrative" | "solver" | "auto";
|
|
82
|
+
showTrajectoryWaypoints?: boolean;
|
|
83
|
+
showTrajectoryLabels?: boolean;
|
|
80
84
|
}
|
|
81
85
|
export interface ViewerState {
|
|
82
86
|
scale: number;
|
|
@@ -130,6 +134,9 @@ export interface ViewerAtlasState {
|
|
|
130
134
|
layers?: ViewerLayerOptions;
|
|
131
135
|
scaleModel?: Partial<RenderScaleModel>;
|
|
132
136
|
bodyScaleMode?: SceneRenderOptions["bodyScaleMode"];
|
|
137
|
+
trajectoryMode?: SceneRenderOptions["trajectoryMode"];
|
|
138
|
+
showTrajectoryWaypoints?: boolean;
|
|
139
|
+
showTrajectoryLabels?: boolean;
|
|
133
140
|
activeEventId?: string | null;
|
|
134
141
|
viewMode?: WorldOrbitViewMode;
|
|
135
142
|
quality?: WorldOrbit3DQuality;
|
|
@@ -1086,7 +1086,7 @@ export function createInteractiveViewer(container, options) {
|
|
|
1086
1086
|
tooltipRoot.hidden = false;
|
|
1087
1087
|
tooltipRoot.dataset.mode = resolved.mode;
|
|
1088
1088
|
tooltipRoot.classList.toggle("is-pinned", resolved.mode === "pinned");
|
|
1089
|
-
tooltipRoot.style.pointerEvents = "auto";
|
|
1089
|
+
tooltipRoot.style.pointerEvents = resolved.mode === "pinned" ? "auto" : "none";
|
|
1090
1090
|
tooltipRoot.style.visibility = "hidden";
|
|
1091
1091
|
renderTooltipContent(tooltipRoot, tooltipDetails, resolved.mode);
|
|
1092
1092
|
positionTooltip(tooltipRoot, details.renderObject);
|
|
@@ -1691,6 +1691,33 @@ function fallbackSpatialSceneFromRenderScene(scene) {
|
|
|
1691
1691
|
hidden: orbit.hidden,
|
|
1692
1692
|
motion: null,
|
|
1693
1693
|
})),
|
|
1694
|
+
trajectories: scene.trajectories.map((trajectory) => ({
|
|
1695
|
+
trajectoryId: trajectory.trajectoryId,
|
|
1696
|
+
trajectory: trajectory.trajectory,
|
|
1697
|
+
craftObjectId: trajectory.craftObjectId,
|
|
1698
|
+
mode: trajectory.mode,
|
|
1699
|
+
stroke: trajectory.stroke,
|
|
1700
|
+
strokeWidth: trajectory.strokeWidth,
|
|
1701
|
+
marker: trajectory.marker,
|
|
1702
|
+
labelMode: trajectory.labelMode,
|
|
1703
|
+
showWaypoints: trajectory.showWaypoints,
|
|
1704
|
+
samples: [],
|
|
1705
|
+
waypoints: trajectory.waypoints.map((waypoint) => ({
|
|
1706
|
+
trajectoryId: waypoint.trajectoryId,
|
|
1707
|
+
segmentId: waypoint.segmentId,
|
|
1708
|
+
maneuverId: waypoint.maneuverId,
|
|
1709
|
+
objectId: waypoint.objectId,
|
|
1710
|
+
position: {
|
|
1711
|
+
x: waypoint.x - scene.contentBounds.centerX,
|
|
1712
|
+
y: 0,
|
|
1713
|
+
z: waypoint.y - scene.contentBounds.centerY,
|
|
1714
|
+
},
|
|
1715
|
+
label: waypoint.label,
|
|
1716
|
+
dateLabel: waypoint.dateLabel,
|
|
1717
|
+
hidden: waypoint.hidden,
|
|
1718
|
+
})),
|
|
1719
|
+
hidden: trajectory.hidden,
|
|
1720
|
+
})),
|
|
1694
1721
|
focusTargets: scene.objects.map((object) => ({
|
|
1695
1722
|
objectId: object.objectId,
|
|
1696
1723
|
center: {
|
|
@@ -1732,7 +1759,11 @@ function getClosestObjectId(target) {
|
|
|
1732
1759
|
if (!(target instanceof Element)) {
|
|
1733
1760
|
return null;
|
|
1734
1761
|
}
|
|
1735
|
-
|
|
1762
|
+
const selectionTarget = target.closest("[data-object-id], [data-orbit-object-id]");
|
|
1763
|
+
if (!selectionTarget) {
|
|
1764
|
+
return null;
|
|
1765
|
+
}
|
|
1766
|
+
return selectionTarget.dataset.objectId ?? selectionTarget.dataset.orbitObjectId ?? null;
|
|
1736
1767
|
}
|
|
1737
1768
|
function ensureBrowserEnvironment(container) {
|
|
1738
1769
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
@@ -1864,7 +1895,7 @@ function installViewerOverlayStyles() {
|
|
|
1864
1895
|
backdrop-filter: blur(12px);
|
|
1865
1896
|
font: 500 13px/1.5 "Segoe UI Variable", "Segoe UI", sans-serif;
|
|
1866
1897
|
}
|
|
1867
|
-
.wo-viewer-tooltip-root[data-mode="hover"] { pointer-events:
|
|
1898
|
+
.wo-viewer-tooltip-root[data-mode="hover"] { pointer-events: none; }
|
|
1868
1899
|
.wo-viewer-tooltip-root[data-mode="pinned"] { pointer-events: auto; }
|
|
1869
1900
|
.wo-tooltip-card { display: grid; gap: 10px; }
|
|
1870
1901
|
.wo-tooltip-head { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 12px; align-items: center; }
|