worldorbit 3.2.1 → 3.2.2

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.
Files changed (81) hide show
  1. package/dist/browser/obsidian-plugin/dist/diagnostics.d.ts +3 -0
  2. package/dist/browser/obsidian-plugin/dist/diagnostics.js +23 -0
  3. package/dist/browser/obsidian-plugin/dist/examples.d.ts +3 -0
  4. package/dist/browser/obsidian-plugin/dist/examples.js +77 -0
  5. package/dist/browser/obsidian-plugin/dist/index.d.ts +9 -0
  6. package/dist/browser/obsidian-plugin/dist/index.js +8 -0
  7. package/dist/browser/obsidian-plugin/dist/main.d.ts +2 -0
  8. package/dist/browser/obsidian-plugin/dist/main.js +2 -0
  9. package/dist/browser/obsidian-plugin/dist/navigation.d.ts +6 -0
  10. package/dist/browser/obsidian-plugin/dist/navigation.js +44 -0
  11. package/dist/browser/obsidian-plugin/dist/plugin.d.ts +8 -0
  12. package/dist/browser/obsidian-plugin/dist/plugin.js +508 -0
  13. package/dist/browser/obsidian-plugin/dist/positions.d.ts +7 -0
  14. package/dist/browser/obsidian-plugin/dist/positions.js +14 -0
  15. package/dist/browser/obsidian-plugin/dist/settings.d.ts +2 -0
  16. package/dist/browser/obsidian-plugin/dist/settings.js +5 -0
  17. package/dist/browser/obsidian-plugin/dist/theme.d.ts +2 -0
  18. package/dist/browser/obsidian-plugin/dist/theme.js +31 -0
  19. package/dist/browser/obsidian-plugin/dist/types.d.ts +42 -0
  20. package/dist/browser/obsidian-plugin/dist/types.js +1 -0
  21. package/dist/browser/obsidian-plugin/dist/viewer-host.d.ts +14 -0
  22. package/dist/browser/obsidian-plugin/dist/viewer-host.js +110 -0
  23. package/dist/browser/viewer/dist/index.d.ts +1 -0
  24. package/dist/browser/viewer/dist/index.js +1 -0
  25. package/dist/browser/viewer/dist/interactive-2d.d.ts +21 -0
  26. package/dist/browser/viewer/dist/interactive-2d.js +201 -0
  27. package/dist/browser/viewer/dist/render.d.ts +1 -1
  28. package/dist/browser/viewer/dist/render.js +2 -1
  29. package/dist/browser/viewer/dist/viewer-state.d.ts +1 -1
  30. package/dist/browser/viewer/dist/viewer-state.js +1 -1
  31. package/dist/obsidian-plugin/LICENSE +21 -0
  32. package/dist/obsidian-plugin/README.md +124 -0
  33. package/dist/obsidian-plugin/main.js +108 -0
  34. package/dist/obsidian-plugin/manifest.json +9 -0
  35. package/dist/obsidian-plugin/obsidian_scsh_1.png +0 -0
  36. package/dist/obsidian-plugin/obsidian_scsh_2.png +0 -0
  37. package/dist/obsidian-plugin/styles.css +164 -0
  38. package/dist/unpkg/obsidian-plugin/dist/diagnostics.d.ts +3 -0
  39. package/dist/unpkg/obsidian-plugin/dist/diagnostics.js +23 -0
  40. package/dist/unpkg/obsidian-plugin/dist/examples.d.ts +3 -0
  41. package/dist/unpkg/obsidian-plugin/dist/examples.js +77 -0
  42. package/dist/unpkg/obsidian-plugin/dist/index.d.ts +9 -0
  43. package/dist/unpkg/obsidian-plugin/dist/index.js +8 -0
  44. package/dist/unpkg/obsidian-plugin/dist/main.d.ts +2 -0
  45. package/dist/unpkg/obsidian-plugin/dist/main.js +2 -0
  46. package/dist/unpkg/obsidian-plugin/dist/navigation.d.ts +6 -0
  47. package/dist/unpkg/obsidian-plugin/dist/navigation.js +44 -0
  48. package/dist/unpkg/obsidian-plugin/dist/plugin.d.ts +8 -0
  49. package/dist/unpkg/obsidian-plugin/dist/plugin.js +508 -0
  50. package/dist/unpkg/obsidian-plugin/dist/positions.d.ts +7 -0
  51. package/dist/unpkg/obsidian-plugin/dist/positions.js +14 -0
  52. package/dist/unpkg/obsidian-plugin/dist/settings.d.ts +2 -0
  53. package/dist/unpkg/obsidian-plugin/dist/settings.js +5 -0
  54. package/dist/unpkg/obsidian-plugin/dist/theme.d.ts +2 -0
  55. package/dist/unpkg/obsidian-plugin/dist/theme.js +31 -0
  56. package/dist/unpkg/obsidian-plugin/dist/types.d.ts +42 -0
  57. package/dist/unpkg/obsidian-plugin/dist/types.js +1 -0
  58. package/dist/unpkg/obsidian-plugin/dist/viewer-host.d.ts +14 -0
  59. package/dist/unpkg/obsidian-plugin/dist/viewer-host.js +110 -0
  60. package/dist/unpkg/viewer/dist/index.d.ts +1 -0
  61. package/dist/unpkg/viewer/dist/index.js +1 -0
  62. package/dist/unpkg/viewer/dist/interactive-2d.d.ts +21 -0
  63. package/dist/unpkg/viewer/dist/interactive-2d.js +201 -0
  64. package/dist/unpkg/viewer/dist/render.d.ts +1 -1
  65. package/dist/unpkg/viewer/dist/render.js +2 -1
  66. package/dist/unpkg/viewer/dist/viewer-state.d.ts +1 -1
  67. package/dist/unpkg/viewer/dist/viewer-state.js +1 -1
  68. package/dist/unpkg/worldorbit-editor.min.js +56 -56
  69. package/dist/unpkg/worldorbit-markdown.min.js +15 -15
  70. package/dist/unpkg/worldorbit-viewer.min.js +207 -207
  71. package/dist/unpkg/worldorbit.js +200 -0
  72. package/dist/unpkg/worldorbit.min.js +210 -210
  73. package/package.json +18 -1
  74. package/packages/viewer/dist/index.d.ts +1 -0
  75. package/packages/viewer/dist/index.js +1 -0
  76. package/packages/viewer/dist/interactive-2d.d.ts +21 -0
  77. package/packages/viewer/dist/interactive-2d.js +201 -0
  78. package/packages/viewer/dist/render.d.ts +1 -1
  79. package/packages/viewer/dist/render.js +2 -1
  80. package/packages/viewer/dist/viewer-state.d.ts +1 -1
  81. package/packages/viewer/dist/viewer-state.js +1 -1
@@ -0,0 +1,110 @@
1
+ import { createInteractiveViewer2D, renderSceneToSvg, } from "@worldorbit/viewer/interactive-2d";
2
+ export class WorldOrbitEmbeddedView {
3
+ options;
4
+ viewer = null;
5
+ state;
6
+ constructor(options) {
7
+ this.options = {
8
+ ...options,
9
+ createViewer: options.createViewer ?? defaultCreateViewer,
10
+ renderStatic: options.renderStatic ?? defaultRenderStatic,
11
+ };
12
+ this.state = {
13
+ interactive: options.interactive,
14
+ destroyed: false,
15
+ };
16
+ }
17
+ getState() {
18
+ return { ...this.state };
19
+ }
20
+ mount() {
21
+ if (this.state.destroyed) {
22
+ return;
23
+ }
24
+ this.renderCurrent();
25
+ }
26
+ setInteractive(interactive) {
27
+ if (this.state.destroyed || this.state.interactive === interactive) {
28
+ return;
29
+ }
30
+ this.state.interactive = interactive;
31
+ this.renderCurrent();
32
+ }
33
+ resize() {
34
+ if (this.state.destroyed) {
35
+ return;
36
+ }
37
+ if (this.viewer) {
38
+ const viewport = measureViewport(this.options.container, this.options.scene);
39
+ this.viewer.setRenderOptions(viewport);
40
+ return;
41
+ }
42
+ this.renderCurrent();
43
+ }
44
+ destroy() {
45
+ if (this.state.destroyed) {
46
+ return;
47
+ }
48
+ this.state.destroyed = true;
49
+ this.destroyViewer();
50
+ clearElement(this.options.container);
51
+ }
52
+ renderCurrent() {
53
+ this.destroyViewer();
54
+ clearElement(this.options.container);
55
+ if (this.state.interactive) {
56
+ const viewport = measureViewport(this.options.container, this.options.scene);
57
+ this.viewer = this.options.createViewer(this.options.container, {
58
+ scene: this.options.scene,
59
+ theme: this.options.theme,
60
+ pointer: this.options.enablePointer,
61
+ touch: this.options.enableTouch,
62
+ ...viewport,
63
+ });
64
+ return;
65
+ }
66
+ const viewport = measureViewport(this.options.container, this.options.scene);
67
+ this.options.container.innerHTML = this.options.renderStatic(this.options.scene, {
68
+ theme: this.options.theme,
69
+ ...viewport,
70
+ });
71
+ }
72
+ destroyViewer() {
73
+ this.viewer?.destroy();
74
+ this.viewer = null;
75
+ }
76
+ }
77
+ function defaultCreateViewer(container, options) {
78
+ return createInteractiveViewer2D(container, options.scene, {
79
+ theme: options.theme,
80
+ pointer: options.pointer,
81
+ touch: options.touch,
82
+ selection: true,
83
+ width: options.width,
84
+ height: options.height,
85
+ });
86
+ }
87
+ function defaultRenderStatic(scene, options) {
88
+ return renderSceneToSvg(scene, {
89
+ theme: options.theme,
90
+ width: options.width,
91
+ height: options.height,
92
+ });
93
+ }
94
+ function measureViewport(container, scene) {
95
+ const rect = container.getBoundingClientRect();
96
+ const width = sanitizeDimension(container.clientWidth || rect.width) ?? scene.width;
97
+ const height = sanitizeDimension(container.clientHeight || rect.height) ??
98
+ Math.max(Math.round(width * (scene.height / Math.max(scene.width, 1))), 280);
99
+ return { width, height };
100
+ }
101
+ function sanitizeDimension(value) {
102
+ return Number.isFinite(value) && value > 0 ? Math.round(value) : undefined;
103
+ }
104
+ function clearElement(element) {
105
+ if (typeof element.empty === "function") {
106
+ element.empty();
107
+ return;
108
+ }
109
+ element.replaceChildren();
110
+ }
@@ -8,3 +8,4 @@ export { createEmbedPayload, createWorldOrbitEmbedMarkup, deserializeWorldOrbitE
8
8
  export { defineWorldOrbitViewerElement } from "./custom-element.js";
9
9
  export { createAtlasViewer } from "./atlas-viewer.js";
10
10
  export { createInteractiveViewer } from "./viewer.js";
11
+ export { createInteractiveViewer2D } from "./interactive-2d.js";
@@ -7,3 +7,4 @@ export { createEmbedPayload, createWorldOrbitEmbedMarkup, deserializeWorldOrbitE
7
7
  export { defineWorldOrbitViewerElement } from "./custom-element.js";
8
8
  export { createAtlasViewer } from "./atlas-viewer.js";
9
9
  export { createInteractiveViewer } from "./viewer.js";
10
+ export { createInteractiveViewer2D } from "./interactive-2d.js";
@@ -0,0 +1,21 @@
1
+ import type { RenderScene } from "@worldorbit/core/types";
2
+ import type { SvgRenderOptions, ViewerState } from "./types.js";
3
+ export interface InteractiveViewer2DOptions extends Pick<SvgRenderOptions, "width" | "height" | "padding" | "preset" | "theme" | "layers" | "subtitle"> {
4
+ pointer?: boolean;
5
+ touch?: boolean;
6
+ selection?: boolean;
7
+ minScale?: number;
8
+ maxScale?: number;
9
+ fitPadding?: number;
10
+ }
11
+ export interface WorldOrbitViewer2D {
12
+ getState(): ViewerState;
13
+ setState(state: Partial<ViewerState>): void;
14
+ setRenderOptions(options: Partial<InteractiveViewer2DOptions>): void;
15
+ fitToSystem(): void;
16
+ destroy(): void;
17
+ }
18
+ export { renderSceneToSvg } from "./render.js";
19
+ export { resolveTheme } from "./theme.js";
20
+ export type { WorldOrbitTheme } from "./types.js";
21
+ export declare function createInteractiveViewer2D(container: HTMLElement, scene: RenderScene, options?: InteractiveViewer2DOptions): WorldOrbitViewer2D;
@@ -0,0 +1,201 @@
1
+ import { renderSceneToSvg, WORLD_LAYER_ID } from "./render.js";
2
+ import { DEFAULT_VIEWER_STATE, composeViewerTransform, fitViewerState, panViewerState, zoomViewerStateAt, } from "./viewer-state.js";
3
+ export { renderSceneToSvg } from "./render.js";
4
+ export { resolveTheme } from "./theme.js";
5
+ const DEFAULT_VIEWER_LIMITS = {
6
+ minScale: 0.2,
7
+ maxScale: 8,
8
+ fitPadding: 48,
9
+ };
10
+ export function createInteractiveViewer2D(container, scene, options = {}) {
11
+ const constraints = {
12
+ minScale: options.minScale ?? DEFAULT_VIEWER_LIMITS.minScale,
13
+ maxScale: options.maxScale ?? DEFAULT_VIEWER_LIMITS.maxScale,
14
+ fitPadding: options.fitPadding ?? DEFAULT_VIEWER_LIMITS.fitPadding,
15
+ };
16
+ const behavior = {
17
+ pointer: options.pointer ?? true,
18
+ touch: options.touch ?? true,
19
+ selection: options.selection ?? true,
20
+ };
21
+ let renderOptions = {
22
+ width: options.width,
23
+ height: options.height,
24
+ padding: options.padding,
25
+ preset: options.preset,
26
+ theme: options.theme,
27
+ layers: options.layers,
28
+ subtitle: options.subtitle,
29
+ pointer: behavior.pointer,
30
+ touch: behavior.touch,
31
+ selection: behavior.selection,
32
+ minScale: constraints.minScale,
33
+ maxScale: constraints.maxScale,
34
+ fitPadding: constraints.fitPadding,
35
+ };
36
+ let state = fitViewerState(scene, DEFAULT_VIEWER_STATE, constraints);
37
+ let svgElement = null;
38
+ let cameraRoot = null;
39
+ let destroyed = false;
40
+ let activePointerId = null;
41
+ let lastPointerClientPoint = null;
42
+ let dragDistance = 0;
43
+ const previousTabIndex = container.getAttribute("tabindex");
44
+ const previousTouchAction = container.style.touchAction;
45
+ if (previousTabIndex === null) {
46
+ container.tabIndex = 0;
47
+ }
48
+ container.classList.add("wo-viewer-container");
49
+ container.style.touchAction = behavior.touch ? "none" : previousTouchAction;
50
+ const handleWheel = (event) => {
51
+ if (!behavior.pointer || destroyed || !svgElement) {
52
+ return;
53
+ }
54
+ event.preventDefault();
55
+ container.focus();
56
+ const anchor = getScenePointFromClient(event.clientX, event.clientY);
57
+ const factor = clamp(Math.exp(-event.deltaY * 0.002), 0.6, 1.6);
58
+ updateState(zoomViewerStateAt(scene, state, factor, anchor, constraints));
59
+ };
60
+ const handlePointerDown = (event) => {
61
+ if (destroyed) {
62
+ return;
63
+ }
64
+ const isTouch = event.pointerType === "touch";
65
+ if ((isTouch && !behavior.touch) || (!isTouch && !behavior.pointer)) {
66
+ return;
67
+ }
68
+ if (!isTouch && event.button !== 0) {
69
+ return;
70
+ }
71
+ activePointerId = event.pointerId;
72
+ lastPointerClientPoint = { x: event.clientX, y: event.clientY };
73
+ dragDistance = 0;
74
+ container.setPointerCapture?.(event.pointerId);
75
+ container.focus();
76
+ };
77
+ const handlePointerMove = (event) => {
78
+ if (destroyed || activePointerId !== event.pointerId || !lastPointerClientPoint) {
79
+ return;
80
+ }
81
+ const rect = svgElement?.getBoundingClientRect();
82
+ if (!rect || rect.width <= 0 || rect.height <= 0) {
83
+ return;
84
+ }
85
+ const dx = event.clientX - lastPointerClientPoint.x;
86
+ const dy = event.clientY - lastPointerClientPoint.y;
87
+ lastPointerClientPoint = { x: event.clientX, y: event.clientY };
88
+ dragDistance += Math.hypot(dx, dy);
89
+ updateState(panViewerState(state, dx * (scene.width / rect.width), dy * (scene.height / rect.height)));
90
+ };
91
+ const stopPointer = (event) => {
92
+ if (activePointerId !== event.pointerId) {
93
+ return;
94
+ }
95
+ activePointerId = null;
96
+ lastPointerClientPoint = null;
97
+ container.releasePointerCapture?.(event.pointerId);
98
+ };
99
+ const handleClick = (event) => {
100
+ if (destroyed || !behavior.selection || dragDistance > 6) {
101
+ return;
102
+ }
103
+ const objectEl = event.target?.closest(".wo-object[data-object-id]");
104
+ if (!objectEl) {
105
+ return;
106
+ }
107
+ updateState({
108
+ ...state,
109
+ selectedObjectId: objectEl.dataset.objectId ?? null,
110
+ });
111
+ renderSvg();
112
+ };
113
+ container.addEventListener("wheel", handleWheel, { passive: false });
114
+ container.addEventListener("pointerdown", handlePointerDown);
115
+ container.addEventListener("pointermove", handlePointerMove);
116
+ container.addEventListener("pointerup", stopPointer);
117
+ container.addEventListener("pointercancel", stopPointer);
118
+ container.addEventListener("click", handleClick);
119
+ renderSvg();
120
+ return {
121
+ getState() {
122
+ return { ...state };
123
+ },
124
+ setState(nextState) {
125
+ updateState({
126
+ ...state,
127
+ ...nextState,
128
+ });
129
+ if ("selectedObjectId" in nextState) {
130
+ renderSvg();
131
+ }
132
+ },
133
+ setRenderOptions(nextOptions) {
134
+ renderOptions = {
135
+ ...renderOptions,
136
+ ...nextOptions,
137
+ };
138
+ renderSvg();
139
+ },
140
+ fitToSystem() {
141
+ updateState(fitViewerState(scene, state, constraints));
142
+ },
143
+ destroy() {
144
+ if (destroyed) {
145
+ return;
146
+ }
147
+ destroyed = true;
148
+ container.removeEventListener("wheel", handleWheel);
149
+ container.removeEventListener("pointerdown", handlePointerDown);
150
+ container.removeEventListener("pointermove", handlePointerMove);
151
+ container.removeEventListener("pointerup", stopPointer);
152
+ container.removeEventListener("pointercancel", stopPointer);
153
+ container.removeEventListener("click", handleClick);
154
+ if (previousTabIndex === null) {
155
+ container.removeAttribute("tabindex");
156
+ }
157
+ container.style.touchAction = previousTouchAction;
158
+ container.replaceChildren();
159
+ svgElement = null;
160
+ cameraRoot = null;
161
+ },
162
+ };
163
+ function renderSvg() {
164
+ if (destroyed) {
165
+ return;
166
+ }
167
+ container.innerHTML = renderSceneToSvg(scene, {
168
+ width: renderOptions.width,
169
+ height: renderOptions.height,
170
+ padding: renderOptions.padding,
171
+ preset: renderOptions.preset,
172
+ theme: renderOptions.theme,
173
+ layers: renderOptions.layers,
174
+ subtitle: renderOptions.subtitle,
175
+ selectedObjectId: state.selectedObjectId,
176
+ });
177
+ svgElement = container.querySelector("svg");
178
+ cameraRoot = container.querySelector(`[data-worldorbit-camera-root="${WORLD_LAYER_ID}"]`);
179
+ applyTransform();
180
+ }
181
+ function applyTransform() {
182
+ cameraRoot?.setAttribute("transform", composeViewerTransform(scene, state));
183
+ }
184
+ function updateState(nextState) {
185
+ state = nextState;
186
+ applyTransform();
187
+ }
188
+ function getScenePointFromClient(clientX, clientY) {
189
+ const rect = svgElement?.getBoundingClientRect();
190
+ if (!rect || rect.width <= 0 || rect.height <= 0) {
191
+ return { x: scene.width / 2, y: scene.height / 2 };
192
+ }
193
+ return {
194
+ x: ((clientX - rect.left) / rect.width) * scene.width,
195
+ y: ((clientY - rect.top) / rect.height) * scene.height,
196
+ };
197
+ }
198
+ }
199
+ function clamp(value, min, max) {
200
+ return Math.min(Math.max(value, min), max);
201
+ }
@@ -1,4 +1,4 @@
1
- import { type RenderScene, type WorldOrbitDocument } from "@worldorbit/core";
1
+ import { type RenderScene, type WorldOrbitDocument } from "@worldorbit/core/types";
2
2
  import type { SvgRenderOptions } from "./types.js";
3
3
  export declare const WORLD_LAYER_ID = "worldorbit-camera-root";
4
4
  export declare function renderSceneToSvg(scene: RenderScene, options?: SvgRenderOptions): string;
@@ -1,4 +1,5 @@
1
- import { loadWorldOrbitSource, renderDocumentToScene, } from "@worldorbit/core";
1
+ import { loadWorldOrbitSource } from "@worldorbit/core/load";
2
+ import { renderDocumentToScene } from "@worldorbit/core/scene";
2
3
  import { computeVisibleObjectIds } from "./atlas-state.js";
3
4
  import { resolveLayers, resolveTheme } from "./theme.js";
4
5
  export const WORLD_LAYER_ID = "worldorbit-camera-root";
@@ -1,4 +1,4 @@
1
- import { type CoordinatePoint, type RenderBounds, type RenderScene } from "@worldorbit/core";
1
+ import { type CoordinatePoint, type RenderBounds, type RenderScene } from "@worldorbit/core/types";
2
2
  import type { ViewerState } from "./types.js";
3
3
  export interface ViewerConstraints {
4
4
  minScale: number;
@@ -1,4 +1,4 @@
1
- import { rotatePoint, } from "@worldorbit/core";
1
+ import { rotatePoint } from "@worldorbit/core/scene";
2
2
  export const DEFAULT_VIEWER_STATE = {
3
3
  scale: 1,
4
4
  rotationDeg: 0,