@visualli/core 0.1.5 → 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/animations/index.cjs +146 -0
- package/dist/animations/index.cjs.map +1 -0
- package/dist/animations/index.d.cts +81 -0
- package/dist/animations/index.d.ts +81 -0
- package/dist/animations/index.js +35 -0
- package/dist/animations/index.js.map +1 -0
- package/dist/chunk-6NXADJK2.js +562 -0
- package/dist/chunk-6NXADJK2.js.map +1 -0
- package/dist/chunk-F36SMC3K.js +106 -0
- package/dist/chunk-F36SMC3K.js.map +1 -0
- package/dist/chunk-G5H3P4YZ.js +273 -0
- package/dist/chunk-G5H3P4YZ.js.map +1 -0
- package/dist/chunk-GQMFBYLK.js +81 -0
- package/dist/chunk-GQMFBYLK.js.map +1 -0
- package/dist/chunk-I75TMOE4.js +108 -0
- package/dist/chunk-I75TMOE4.js.map +1 -0
- package/dist/chunk-LDJRGT2Q.js +163 -0
- package/dist/chunk-LDJRGT2Q.js.map +1 -0
- package/dist/chunk-LI3BVD6H.js +98 -0
- package/dist/chunk-LI3BVD6H.js.map +1 -0
- package/dist/chunk-LJYSKSCE.js +95 -0
- package/dist/chunk-LJYSKSCE.js.map +1 -0
- package/dist/chunk-LNTJTDB2.js +349 -0
- package/dist/chunk-LNTJTDB2.js.map +1 -0
- package/dist/chunk-PDP5CVUL.js +139 -0
- package/dist/chunk-PDP5CVUL.js.map +1 -0
- package/dist/chunk-VLGR5PZX.js +1 -0
- package/dist/chunk-VLGR5PZX.js.map +1 -0
- package/dist/config/index.cjs +391 -0
- package/dist/config/index.cjs.map +1 -0
- package/dist/config/index.d.cts +77 -0
- package/dist/config/index.d.ts +77 -0
- package/dist/config/index.js +38 -0
- package/dist/config/index.js.map +1 -0
- package/dist/constants/index.cjs +642 -0
- package/dist/constants/index.cjs.map +1 -0
- package/dist/constants/index.d.cts +448 -0
- package/dist/constants/index.d.ts +448 -0
- package/dist/constants/index.js +183 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/document-B3hnNr-F.d.cts +73 -0
- package/dist/document-B3hnNr-F.d.ts +73 -0
- package/dist/index.cjs +32 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -1044
- package/dist/index.d.ts +15 -1044
- package/dist/index.js +179 -1747
- package/dist/index.js.map +1 -1
- package/dist/layout/index.cjs +210 -0
- package/dist/layout/index.cjs.map +1 -0
- package/dist/layout/index.d.cts +80 -0
- package/dist/layout/index.d.ts +80 -0
- package/dist/layout/index.js +25 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/mindmap-DWS0WZT_.d.cts +118 -0
- package/dist/mindmap-DWS0WZT_.d.ts +118 -0
- package/dist/parser/index.cjs +739 -0
- package/dist/parser/index.cjs.map +1 -0
- package/dist/parser/index.d.cts +87 -0
- package/dist/parser/index.d.ts +87 -0
- package/dist/parser/index.js +43 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/performance/index.cjs +167 -0
- package/dist/performance/index.cjs.map +1 -0
- package/dist/performance/index.d.cts +40 -0
- package/dist/performance/index.d.ts +40 -0
- package/dist/performance/index.js +12 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/types/index.cjs +19 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +8 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/viewport/index.cjs +131 -0
- package/dist/viewport/index.cjs.map +1 -0
- package/dist/viewport/index.d.cts +56 -0
- package/dist/viewport/index.d.ts +56 -0
- package/dist/viewport/index.js +26 -0
- package/dist/viewport/index.js.map +1 -0
- package/package.json +6 -1
- package/src/config/README.md +59 -0
- package/src/config/USAGE_EXAMPLES.md +285 -0
- package/src/config/index.ts +7 -0
- package/src/index.ts +1 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types/index.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
|
19
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["// ─── Types Barrel Export ───────────────────────────────────────────────────────\n\nexport * from './mindmap.js';\nexport * from './meta.js';\nexport * from './layer.js';\nexport * from './document.js';\n// Re-export schema types for external use\nexport {\n type Meta,\n type Node,\n type Container,\n type Layer,\n type Connection,\n type Extension,\n type VisualliFragment,\n} from './schema.js';\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { F as FlatNode, a as MindMapConfig, M as MindMapConnection, b as MindMapData, c as MindMapNode, d as NodeMap, N as NodeSelection, R as RenderConfig, S as SpatialBounds, T as TopLevelConnection, V as ViewportState } from '../mindmap-DWS0WZT_.cjs';
|
|
2
|
+
export { L as LayerConnection, b as LayerContainer, c as LayerNode, V as VisualliDocument, a as VisualliLayer, d as VisualliMeta, e as VisualliRenderConnection, f as VisualliRenderNode } from '../document-B3hnNr-F.cjs';
|
|
3
|
+
import { Meta, Layer } from '@visualli/bindings';
|
|
4
|
+
export { Connection, Container, Extension, Layer, Meta, Node } from '@visualli/bindings';
|
|
5
|
+
|
|
6
|
+
type VisualliFragment = Meta | Layer;
|
|
7
|
+
|
|
8
|
+
export type { VisualliFragment };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { F as FlatNode, a as MindMapConfig, M as MindMapConnection, b as MindMapData, c as MindMapNode, d as NodeMap, N as NodeSelection, R as RenderConfig, S as SpatialBounds, T as TopLevelConnection, V as ViewportState } from '../mindmap-DWS0WZT_.js';
|
|
2
|
+
export { L as LayerConnection, b as LayerContainer, c as LayerNode, V as VisualliDocument, a as VisualliLayer, d as VisualliMeta, e as VisualliRenderConnection, f as VisualliRenderNode } from '../document-B3hnNr-F.js';
|
|
3
|
+
import { Meta, Layer } from '@visualli/bindings';
|
|
4
|
+
export { Connection, Container, Extension, Layer, Meta, Node } from '@visualli/bindings';
|
|
5
|
+
|
|
6
|
+
type VisualliFragment = Meta | Layer;
|
|
7
|
+
|
|
8
|
+
export type { VisualliFragment };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/viewport/index.ts
|
|
21
|
+
var viewport_exports = {};
|
|
22
|
+
__export(viewport_exports, {
|
|
23
|
+
calculateViewportBounds: () => calculateViewportBounds,
|
|
24
|
+
clampZoom: () => clampZoom,
|
|
25
|
+
focusOnNode: () => focusOnNode,
|
|
26
|
+
isNodeInViewport: () => isNodeInViewport,
|
|
27
|
+
panViewport: () => panViewport,
|
|
28
|
+
recalculateViewportBounds: () => recalculateViewportBounds,
|
|
29
|
+
screenToWorld: () => screenToWorld,
|
|
30
|
+
setViewportCenter: () => setViewportCenter,
|
|
31
|
+
worldToScreen: () => worldToScreen,
|
|
32
|
+
zoomViewport: () => zoomViewport
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(viewport_exports);
|
|
35
|
+
|
|
36
|
+
// src/constants/performanceConstants.ts
|
|
37
|
+
var FPS_TARGET = 60;
|
|
38
|
+
var TARGET_FRAME_TIME = 1e3 / FPS_TARGET;
|
|
39
|
+
var VIEWPORT_MARGIN = 0.1;
|
|
40
|
+
var ZOOM_MIN = 0.05;
|
|
41
|
+
var ZOOM_MAX = 5;
|
|
42
|
+
var DEFAULT_CANVAS_WIDTH = 1920;
|
|
43
|
+
var DEFAULT_CANVAS_HEIGHT = 1080;
|
|
44
|
+
|
|
45
|
+
// src/viewport/viewportUtils.ts
|
|
46
|
+
function calculateViewportBounds(viewport, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
47
|
+
const worldW = canvasWidth / viewport.zoomLevel;
|
|
48
|
+
const worldH = canvasHeight / viewport.zoomLevel;
|
|
49
|
+
const mx = worldW * VIEWPORT_MARGIN;
|
|
50
|
+
const my = worldH * VIEWPORT_MARGIN;
|
|
51
|
+
return {
|
|
52
|
+
minX: viewport.centerX - worldW / 2 - mx,
|
|
53
|
+
minY: viewport.centerY - worldH / 2 - my,
|
|
54
|
+
maxX: viewport.centerX + worldW / 2 + mx,
|
|
55
|
+
maxY: viewport.centerY + worldH / 2 + my
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function recalculateViewportBounds(viewport, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
59
|
+
return {
|
|
60
|
+
...viewport,
|
|
61
|
+
visibleBounds: calculateViewportBounds(viewport, canvasWidth, canvasHeight)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function worldToScreen(worldX, worldY, viewport, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
65
|
+
return {
|
|
66
|
+
x: (worldX - viewport.centerX) * viewport.zoomLevel + canvasWidth / 2,
|
|
67
|
+
y: (worldY - viewport.centerY) * viewport.zoomLevel + canvasHeight / 2
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function screenToWorld(screenX, screenY, viewport, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
71
|
+
return {
|
|
72
|
+
x: (screenX - canvasWidth / 2) / viewport.zoomLevel + viewport.centerX,
|
|
73
|
+
y: (screenY - canvasHeight / 2) / viewport.zoomLevel + viewport.centerY
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function clampZoom(zoom) {
|
|
77
|
+
return Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, zoom));
|
|
78
|
+
}
|
|
79
|
+
function panViewport(deltaX, deltaY, viewport) {
|
|
80
|
+
return {
|
|
81
|
+
...viewport,
|
|
82
|
+
centerX: viewport.centerX - deltaX / viewport.zoomLevel,
|
|
83
|
+
centerY: viewport.centerY - deltaY / viewport.zoomLevel
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function setViewportCenter(x, y, viewport) {
|
|
87
|
+
return { ...viewport, centerX: x, centerY: y };
|
|
88
|
+
}
|
|
89
|
+
function zoomViewport(delta, viewport, pivotX, pivotY, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
90
|
+
const newZoom = clampZoom(viewport.zoomLevel * (1 + delta));
|
|
91
|
+
let cx = viewport.centerX;
|
|
92
|
+
let cy = viewport.centerY;
|
|
93
|
+
if (pivotX !== void 0 && pivotY !== void 0) {
|
|
94
|
+
const worldPivot = screenToWorld(pivotX, pivotY, viewport, canvasWidth, canvasHeight);
|
|
95
|
+
cx = worldPivot.x - (pivotX - canvasWidth / 2) / newZoom;
|
|
96
|
+
cy = worldPivot.y - (pivotY - canvasHeight / 2) / newZoom;
|
|
97
|
+
}
|
|
98
|
+
return { ...viewport, centerX: cx, centerY: cy, zoomLevel: newZoom };
|
|
99
|
+
}
|
|
100
|
+
function focusOnNode(nodeX, nodeY, zoom) {
|
|
101
|
+
const clamped = clampZoom(zoom);
|
|
102
|
+
return {
|
|
103
|
+
centerX: nodeX,
|
|
104
|
+
centerY: nodeY,
|
|
105
|
+
zoomLevel: clamped,
|
|
106
|
+
rotation: 0,
|
|
107
|
+
visibleBounds: calculateViewportBounds(
|
|
108
|
+
{ centerX: nodeX, centerY: nodeY, zoomLevel: clamped, rotation: 0, visibleBounds: { minX: 0, minY: 0, maxX: 0, maxY: 0 } }
|
|
109
|
+
)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function isNodeInViewport(nodeX, nodeY, nodeWidth, nodeHeight, viewport, canvasWidth = DEFAULT_CANVAS_WIDTH, canvasHeight = DEFAULT_CANVAS_HEIGHT) {
|
|
113
|
+
const bounds = calculateViewportBounds(viewport, canvasWidth, canvasHeight);
|
|
114
|
+
const hw = nodeWidth / 2;
|
|
115
|
+
const hh = nodeHeight / 2;
|
|
116
|
+
return !(nodeX + hw < bounds.minX || nodeX - hw > bounds.maxX || nodeY + hh < bounds.minY || nodeY - hh > bounds.maxY);
|
|
117
|
+
}
|
|
118
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
119
|
+
0 && (module.exports = {
|
|
120
|
+
calculateViewportBounds,
|
|
121
|
+
clampZoom,
|
|
122
|
+
focusOnNode,
|
|
123
|
+
isNodeInViewport,
|
|
124
|
+
panViewport,
|
|
125
|
+
recalculateViewportBounds,
|
|
126
|
+
screenToWorld,
|
|
127
|
+
setViewportCenter,
|
|
128
|
+
worldToScreen,
|
|
129
|
+
zoomViewport
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/viewport/index.ts","../../src/constants/performanceConstants.ts","../../src/viewport/viewportUtils.ts"],"sourcesContent":["export * from './viewportUtils.js';\n","// ─── Performance & Rendering Constants ───────────────────────────────────────\n\n// ── FPS ───────────────────────────────────────────────────────────────────────\n\nexport const FPS_TARGET = 60;\nexport const FPS_WARNING_THRESHOLD = 45;\nexport const FPS_CRITICAL_THRESHOLD = 30;\nexport const TARGET_FRAME_TIME = 1000 / FPS_TARGET; // ~16.67 ms\nexport const MAX_FRAME_TIME = 18; // p95 threshold\n\n/** Legacy frame-rate targets kept for backward compatibility. */\nexport const FPS_TARGETS = {\n PAN_MIN: 30,\n ZOOM_TARGET: 60,\n WARNING_THRESHOLD: 20,\n} as const;\n\n// ── Timing Thresholds (ms) ────────────────────────────────────────────────────\n\nexport const TIMING_THRESHOLDS = {\n VIEWPORT_QUERY_MAX: 5,\n SPATIAL_UPDATE_MAX: 10,\n DRAG_RESPONSE_MAX: 16,\n LOAD_5K_TARGET: 2000,\n LOAD_10K_TARGET: 3000,\n VIEWPORT_DEBOUNCE: 100,\n SPATIAL_INDEX_BUILD: 50,\n} as const;\n\n// ── Memory Limits (MB) ────────────────────────────────────────────────────────\n\nexport const MEMORY_TARGET_MB = 500;\nexport const MEMORY_WARNING_MB = 600;\nexport const MEMORY_CRITICAL_MB = 800;\n\nexport const MEMORY_LIMITS = {\n MAX_10K_NODES: 500,\n MAX_GROWTH_PERCENT: 20,\n WARNING_THRESHOLD: 400,\n} as const;\n\n// ── Viewport Culling ──────────────────────────────────────────────────────────\n\nexport const VIEWPORT_MARGIN = 0.1;\nexport const MAX_VISIBLE_NODES = 800;\nexport const CULLING_QUERY_TIME_BUDGET = 5;\n\n// ── Spatial Index ─────────────────────────────────────────────────────────────\n\nexport const RBUSH_MAX_ENTRIES = 16;\nexport const SPATIAL_INDEX_BUILD_BUDGET = 50;\n\n// ── Node Dimensions ───────────────────────────────────────────────────────────\n\nexport const NODE_MIN_WIDTH = 200;\nexport const NODE_HEIGHT = 80;\nexport const NODE_PADDING = 40;\nexport const CHAR_WIDTH = 8;\nexport const TITLE_MAX_LENGTH = 150;\n\n// ── Visual Styling ────────────────────────────────────────────────────────────\n\nexport const CORNER_RADIUS = 8;\nexport const BORDER_WIDTH_NORMAL = 2;\nexport const BORDER_WIDTH_SELECTED = 3;\n\nexport const COLOR_SELECTED = '#1B2D4F';\nexport const COLOR_BORDER_LIGHT = '#4A3728';\nexport const COLOR_BORDER_DARK = '#FAF6F1';\nexport const COLOR_DEFAULT_NODE = '#FAF6F1';\n\n// ── Zoom Constraints ──────────────────────────────────────────────────────────\n\nexport const ZOOM_MIN = 0.05;\nexport const ZOOM_MAX = 5.0;\nexport const ZOOM_DEFAULT = 1.0;\nexport const ZOOM_STEP = 0.1;\nexport const ZOOM_WHEEL_SENSITIVITY = 0.001;\n\nexport const ZOOM_NAV_IN_THRESHOLD = 2.7;\nexport const ZOOM_NAV_OUT_THRESHOLD = 0.4;\nexport const TEXT_LABEL_HIDE_BELOW_ZOOM = 0.3;\n\n// ── Quality Level Presets ─────────────────────────────────────────────────────\n\nexport const QUALITY_HIGH = {\n shadows: true,\n bezierCurves: true,\n animations: true,\n textQuality: 'high' as const,\n antialiasing: true,\n};\n\nexport const QUALITY_MEDIUM = {\n shadows: false,\n bezierCurves: true,\n animations: true,\n textQuality: 'medium' as const,\n antialiasing: true,\n};\n\nexport const QUALITY_LOW = {\n shadows: false,\n bezierCurves: false,\n animations: false,\n textQuality: 'low' as const,\n antialiasing: false,\n};\n\n// ── Performance Monitoring ────────────────────────────────────────────────────\n\nexport const FPS_SAMPLE_WINDOW = 60;\nexport const FPS_UPDATE_INTERVAL = 1000;\nexport const MEMORY_CHECK_INTERVAL = 5000;\nexport const PERFORMANCE_TOAST_COOLDOWN = 10000;\n\n// ── Auto-Adjustment ───────────────────────────────────────────────────────────\n\nexport const FPS_DOWNGRADE_THRESHOLD = 45;\nexport const FPS_UPGRADE_THRESHOLD = 58;\nexport const FPS_STABILIZATION_FRAMES = 180;\n\n// ── Canvas Dimensions ─────────────────────────────────────────────────────────\n\nexport const DEFAULT_CANVAS_WIDTH = 1920;\nexport const DEFAULT_CANVAS_HEIGHT = 1080;\n\n// ── Interaction ───────────────────────────────────────────────────────────────\n\nexport const CLICK_THRESHOLD = 5;\nexport const DOUBLE_CLICK_DELAY = 300;\nexport const DRAG_START_DISTANCE = 10;\n\n// ── Data Validation ───────────────────────────────────────────────────────────\n\nexport const MAX_NODES = 20000;\nexport const CIRCULAR_REFERENCE_MAX_DEPTH = 1000;\n\n// ── Debounce / Throttle ───────────────────────────────────────────────────────\n\nexport const RESIZE_DEBOUNCE = 300;\nexport const SCROLL_THROTTLE = 16;\nexport const SEARCH_DEBOUNCE = 500;\n\n/** Node count thresholds that gate optimisation strategies. */\nexport const NODE_COUNT_THRESHOLDS = {\n SPATIAL_INDEX_MIN: 100,\n VIEWPORT_CULLING_MIN: 500,\n CANVAS_RENDERING_MIN: 2000,\n DOM_RENDERING_MAX: 5000,\n} as const;\n\n/** Viewport buffer configuration. */\nexport const VIEWPORT_CONFIG = {\n BUFFER_PERCENT: 0.2,\n MIN_VISIBLE_NODES: 10,\n} as const;\n","// ─── Viewport Utilities ───────────────────────────────────────────────────────\n//\n// Pure functions for viewport bounds calculation, coordinate transforms,\n// pan/zoom operations, and node visibility queries.\n\nimport type { ViewportState } from '../types/mindmap.js';\nimport {\n VIEWPORT_MARGIN,\n DEFAULT_CANVAS_WIDTH,\n DEFAULT_CANVAS_HEIGHT,\n ZOOM_MIN,\n ZOOM_MAX,\n} from '../constants/performanceConstants.js';\n\n// ── Viewport Bounds ───────────────────────────────────────────────────────────\n\nexport interface WorldBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\n/**\n * Calculate the visible world-space bounding box including a margin buffer.\n */\nexport function calculateViewportBounds(\n viewport: ViewportState,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): WorldBounds {\n const worldW = canvasWidth / viewport.zoomLevel;\n const worldH = canvasHeight / viewport.zoomLevel;\n const mx = worldW * VIEWPORT_MARGIN;\n const my = worldH * VIEWPORT_MARGIN;\n return {\n minX: viewport.centerX - worldW / 2 - mx,\n minY: viewport.centerY - worldH / 2 - my,\n maxX: viewport.centerX + worldW / 2 + mx,\n maxY: viewport.centerY + worldH / 2 + my,\n };\n}\n\n/**\n * Return a new ViewportState with `visibleBounds` recalculated.\n */\nexport function recalculateViewportBounds(\n viewport: ViewportState,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): ViewportState {\n return {\n ...viewport,\n visibleBounds: calculateViewportBounds(viewport, canvasWidth, canvasHeight),\n };\n}\n\n// ── Coordinate Transforms ─────────────────────────────────────────────────────\n\n/**\n * Convert world-space coordinates to screen-space pixel coordinates.\n */\nexport function worldToScreen(\n worldX: number,\n worldY: number,\n viewport: ViewportState,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): { x: number; y: number } {\n return {\n x: (worldX - viewport.centerX) * viewport.zoomLevel + canvasWidth / 2,\n y: (worldY - viewport.centerY) * viewport.zoomLevel + canvasHeight / 2,\n };\n}\n\n/**\n * Convert screen-space pixel coordinates to world-space coordinates.\n */\nexport function screenToWorld(\n screenX: number,\n screenY: number,\n viewport: ViewportState,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): { x: number; y: number } {\n return {\n x: (screenX - canvasWidth / 2) / viewport.zoomLevel + viewport.centerX,\n y: (screenY - canvasHeight / 2) / viewport.zoomLevel + viewport.centerY,\n };\n}\n\n// ── Pan / Zoom ────────────────────────────────────────────────────────────────\n\n/** Clamp zoom to [ZOOM_MIN, ZOOM_MAX]. */\nexport function clampZoom(zoom: number): number {\n return Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, zoom));\n}\n\n/**\n * Pan the viewport by a screen-space delta (positive = right/down).\n */\nexport function panViewport(\n deltaX: number,\n deltaY: number,\n viewport: ViewportState,\n): ViewportState {\n return {\n ...viewport,\n centerX: viewport.centerX - deltaX / viewport.zoomLevel,\n centerY: viewport.centerY - deltaY / viewport.zoomLevel,\n };\n}\n\n/** Teleport the viewport centre to the given world coordinates. */\nexport function setViewportCenter(\n x: number,\n y: number,\n viewport: ViewportState,\n): ViewportState {\n return { ...viewport, centerX: x, centerY: y };\n}\n\n/**\n * Zoom the viewport by a multiplicative delta, optionally around a pivot point.\n *\n * @param delta - Multiplier delta, e.g. 0.1 for +10% zoom\n * @param pivotX - Optional screen-space X pivot\n * @param pivotY - Optional screen-space Y pivot\n */\nexport function zoomViewport(\n delta: number,\n viewport: ViewportState,\n pivotX?: number,\n pivotY?: number,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): ViewportState {\n const newZoom = clampZoom(viewport.zoomLevel * (1 + delta));\n\n let cx = viewport.centerX;\n let cy = viewport.centerY;\n\n if (pivotX !== undefined && pivotY !== undefined) {\n const worldPivot = screenToWorld(pivotX, pivotY, viewport, canvasWidth, canvasHeight);\n cx = worldPivot.x - (pivotX - canvasWidth / 2) / newZoom;\n cy = worldPivot.y - (pivotY - canvasHeight / 2) / newZoom;\n }\n\n return { ...viewport, centerX: cx, centerY: cy, zoomLevel: newZoom };\n}\n\n/**\n * Create a viewport centred on a node (world coordinates) at the given zoom level.\n */\nexport function focusOnNode(\n nodeX: number,\n nodeY: number,\n zoom: number,\n): ViewportState {\n const clamped = clampZoom(zoom);\n return {\n centerX: nodeX,\n centerY: nodeY,\n zoomLevel: clamped,\n rotation: 0,\n visibleBounds: calculateViewportBounds(\n { centerX: nodeX, centerY: nodeY, zoomLevel: clamped, rotation: 0, visibleBounds: { minX: 0, minY: 0, maxX: 0, maxY: 0 } },\n ),\n };\n}\n\n// ── Visibility ────────────────────────────────────────────────────────────────\n\n/**\n * Test whether a world-space AABB intersects the viewport's visible bounds.\n */\nexport function isNodeInViewport(\n nodeX: number,\n nodeY: number,\n nodeWidth: number,\n nodeHeight: number,\n viewport: ViewportState,\n canvasWidth = DEFAULT_CANVAS_WIDTH,\n canvasHeight = DEFAULT_CANVAS_HEIGHT,\n): boolean {\n const bounds = calculateViewportBounds(viewport, canvasWidth, canvasHeight);\n const hw = nodeWidth / 2;\n const hh = nodeHeight / 2;\n return !(\n nodeX + hw < bounds.minX ||\n nodeX - hw > bounds.maxX ||\n nodeY + hh < bounds.minY ||\n nodeY - hh > bounds.maxY\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { V as ViewportState } from '../mindmap-DWS0WZT_.cjs';
|
|
2
|
+
|
|
3
|
+
interface WorldBounds {
|
|
4
|
+
minX: number;
|
|
5
|
+
minY: number;
|
|
6
|
+
maxX: number;
|
|
7
|
+
maxY: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Calculate the visible world-space bounding box including a margin buffer.
|
|
11
|
+
*/
|
|
12
|
+
declare function calculateViewportBounds(viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): WorldBounds;
|
|
13
|
+
/**
|
|
14
|
+
* Return a new ViewportState with `visibleBounds` recalculated.
|
|
15
|
+
*/
|
|
16
|
+
declare function recalculateViewportBounds(viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): ViewportState;
|
|
17
|
+
/**
|
|
18
|
+
* Convert world-space coordinates to screen-space pixel coordinates.
|
|
19
|
+
*/
|
|
20
|
+
declare function worldToScreen(worldX: number, worldY: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Convert screen-space pixel coordinates to world-space coordinates.
|
|
26
|
+
*/
|
|
27
|
+
declare function screenToWorld(screenX: number, screenY: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
};
|
|
31
|
+
/** Clamp zoom to [ZOOM_MIN, ZOOM_MAX]. */
|
|
32
|
+
declare function clampZoom(zoom: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Pan the viewport by a screen-space delta (positive = right/down).
|
|
35
|
+
*/
|
|
36
|
+
declare function panViewport(deltaX: number, deltaY: number, viewport: ViewportState): ViewportState;
|
|
37
|
+
/** Teleport the viewport centre to the given world coordinates. */
|
|
38
|
+
declare function setViewportCenter(x: number, y: number, viewport: ViewportState): ViewportState;
|
|
39
|
+
/**
|
|
40
|
+
* Zoom the viewport by a multiplicative delta, optionally around a pivot point.
|
|
41
|
+
*
|
|
42
|
+
* @param delta - Multiplier delta, e.g. 0.1 for +10% zoom
|
|
43
|
+
* @param pivotX - Optional screen-space X pivot
|
|
44
|
+
* @param pivotY - Optional screen-space Y pivot
|
|
45
|
+
*/
|
|
46
|
+
declare function zoomViewport(delta: number, viewport: ViewportState, pivotX?: number, pivotY?: number, canvasWidth?: number, canvasHeight?: number): ViewportState;
|
|
47
|
+
/**
|
|
48
|
+
* Create a viewport centred on a node (world coordinates) at the given zoom level.
|
|
49
|
+
*/
|
|
50
|
+
declare function focusOnNode(nodeX: number, nodeY: number, zoom: number): ViewportState;
|
|
51
|
+
/**
|
|
52
|
+
* Test whether a world-space AABB intersects the viewport's visible bounds.
|
|
53
|
+
*/
|
|
54
|
+
declare function isNodeInViewport(nodeX: number, nodeY: number, nodeWidth: number, nodeHeight: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): boolean;
|
|
55
|
+
|
|
56
|
+
export { type WorldBounds, calculateViewportBounds, clampZoom, focusOnNode, isNodeInViewport, panViewport, recalculateViewportBounds, screenToWorld, setViewportCenter, worldToScreen, zoomViewport };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { V as ViewportState } from '../mindmap-DWS0WZT_.js';
|
|
2
|
+
|
|
3
|
+
interface WorldBounds {
|
|
4
|
+
minX: number;
|
|
5
|
+
minY: number;
|
|
6
|
+
maxX: number;
|
|
7
|
+
maxY: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Calculate the visible world-space bounding box including a margin buffer.
|
|
11
|
+
*/
|
|
12
|
+
declare function calculateViewportBounds(viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): WorldBounds;
|
|
13
|
+
/**
|
|
14
|
+
* Return a new ViewportState with `visibleBounds` recalculated.
|
|
15
|
+
*/
|
|
16
|
+
declare function recalculateViewportBounds(viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): ViewportState;
|
|
17
|
+
/**
|
|
18
|
+
* Convert world-space coordinates to screen-space pixel coordinates.
|
|
19
|
+
*/
|
|
20
|
+
declare function worldToScreen(worldX: number, worldY: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Convert screen-space pixel coordinates to world-space coordinates.
|
|
26
|
+
*/
|
|
27
|
+
declare function screenToWorld(screenX: number, screenY: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
};
|
|
31
|
+
/** Clamp zoom to [ZOOM_MIN, ZOOM_MAX]. */
|
|
32
|
+
declare function clampZoom(zoom: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Pan the viewport by a screen-space delta (positive = right/down).
|
|
35
|
+
*/
|
|
36
|
+
declare function panViewport(deltaX: number, deltaY: number, viewport: ViewportState): ViewportState;
|
|
37
|
+
/** Teleport the viewport centre to the given world coordinates. */
|
|
38
|
+
declare function setViewportCenter(x: number, y: number, viewport: ViewportState): ViewportState;
|
|
39
|
+
/**
|
|
40
|
+
* Zoom the viewport by a multiplicative delta, optionally around a pivot point.
|
|
41
|
+
*
|
|
42
|
+
* @param delta - Multiplier delta, e.g. 0.1 for +10% zoom
|
|
43
|
+
* @param pivotX - Optional screen-space X pivot
|
|
44
|
+
* @param pivotY - Optional screen-space Y pivot
|
|
45
|
+
*/
|
|
46
|
+
declare function zoomViewport(delta: number, viewport: ViewportState, pivotX?: number, pivotY?: number, canvasWidth?: number, canvasHeight?: number): ViewportState;
|
|
47
|
+
/**
|
|
48
|
+
* Create a viewport centred on a node (world coordinates) at the given zoom level.
|
|
49
|
+
*/
|
|
50
|
+
declare function focusOnNode(nodeX: number, nodeY: number, zoom: number): ViewportState;
|
|
51
|
+
/**
|
|
52
|
+
* Test whether a world-space AABB intersects the viewport's visible bounds.
|
|
53
|
+
*/
|
|
54
|
+
declare function isNodeInViewport(nodeX: number, nodeY: number, nodeWidth: number, nodeHeight: number, viewport: ViewportState, canvasWidth?: number, canvasHeight?: number): boolean;
|
|
55
|
+
|
|
56
|
+
export { type WorldBounds, calculateViewportBounds, clampZoom, focusOnNode, isNodeInViewport, panViewport, recalculateViewportBounds, screenToWorld, setViewportCenter, worldToScreen, zoomViewport };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
calculateViewportBounds,
|
|
3
|
+
clampZoom,
|
|
4
|
+
focusOnNode,
|
|
5
|
+
isNodeInViewport,
|
|
6
|
+
panViewport,
|
|
7
|
+
recalculateViewportBounds,
|
|
8
|
+
screenToWorld,
|
|
9
|
+
setViewportCenter,
|
|
10
|
+
worldToScreen,
|
|
11
|
+
zoomViewport
|
|
12
|
+
} from "../chunk-LJYSKSCE.js";
|
|
13
|
+
import "../chunk-LDJRGT2Q.js";
|
|
14
|
+
export {
|
|
15
|
+
calculateViewportBounds,
|
|
16
|
+
clampZoom,
|
|
17
|
+
focusOnNode,
|
|
18
|
+
isNodeInViewport,
|
|
19
|
+
panViewport,
|
|
20
|
+
recalculateViewportBounds,
|
|
21
|
+
screenToWorld,
|
|
22
|
+
setViewportCenter,
|
|
23
|
+
worldToScreen,
|
|
24
|
+
zoomViewport
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visualli/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Framework-agnostic core logic, types, and engines for Visualli",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -50,6 +50,11 @@
|
|
|
50
50
|
"types": "./dist/animations/index.d.ts",
|
|
51
51
|
"import": "./dist/animations/index.js",
|
|
52
52
|
"require": "./dist/animations/index.cjs"
|
|
53
|
+
},
|
|
54
|
+
"./config": {
|
|
55
|
+
"types": "./dist/config/index.d.ts",
|
|
56
|
+
"import": "./dist/config/index.js",
|
|
57
|
+
"require": "./dist/config/index.cjs"
|
|
53
58
|
}
|
|
54
59
|
},
|
|
55
60
|
"files": [
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Configuration Module
|
|
2
|
+
|
|
3
|
+
This module exports all configuration constants and utilities for Visualli.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### Import all config (from main package)
|
|
8
|
+
```typescript
|
|
9
|
+
import { ALL_BLOB_SHAPES, BlobShape, getBlobTypeForLayer, drawBlobPath } from '@visualli/core';
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
### Import from config sub-path (recommended for tree-shaking)
|
|
13
|
+
```typescript
|
|
14
|
+
import { ALL_BLOB_SHAPES, BlobShape, getBlobTypeForLayer, drawBlobPath } from '@visualli/core/config';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Import specific config file
|
|
18
|
+
```typescript
|
|
19
|
+
import {
|
|
20
|
+
ALL_BLOB_SHAPES,
|
|
21
|
+
BlobShape,
|
|
22
|
+
BlobPoint,
|
|
23
|
+
ACTIVE_BLOB_TYPES,
|
|
24
|
+
BLOB_LAYER_CONFIG,
|
|
25
|
+
NODE_LAYER_CONFIG,
|
|
26
|
+
BLOB_TEXT_OFFSETS,
|
|
27
|
+
getBlobTypeForLayer,
|
|
28
|
+
drawBlobPath
|
|
29
|
+
} from '@visualli/core/config';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Available Exports
|
|
33
|
+
|
|
34
|
+
### Blob Shapes (`blobShapes.ts`)
|
|
35
|
+
- **`ALL_BLOB_SHAPES`** - Array of 6 predefined blob shapes (Shape 0-5)
|
|
36
|
+
- **`ACTIVE_BLOB_TYPES`** - Array of active blob type indices
|
|
37
|
+
- **`BLOB_LAYER_CONFIG`** - Configuration for blob rendering layers
|
|
38
|
+
- **`NODE_LAYER_CONFIG`** - Configuration for node layer
|
|
39
|
+
- **`BLOB_TEXT_OFFSETS`** - Text positioning offsets per shape
|
|
40
|
+
- **`getBlobTypeForLayer(level: number)`** - Get blob type for a specific tree level
|
|
41
|
+
- **`drawBlobPath(ctx, radiusX, radiusY, blobType)`** - Draw blob path on canvas
|
|
42
|
+
|
|
43
|
+
### Text Scaling (`textScaling.ts`)
|
|
44
|
+
- Text scaling configuration utilities
|
|
45
|
+
|
|
46
|
+
## Adding New Configuration
|
|
47
|
+
|
|
48
|
+
To add new configuration modules:
|
|
49
|
+
|
|
50
|
+
1. Create your config file in `src/config/your-config.ts`
|
|
51
|
+
2. Add the export to `src/config/index.ts`:
|
|
52
|
+
```typescript
|
|
53
|
+
export * from './your-config.js';
|
|
54
|
+
```
|
|
55
|
+
3. The exports will automatically be available via both:
|
|
56
|
+
- `@visualli/core` (main barrel)
|
|
57
|
+
- `@visualli/core/config` (sub-path for better tree-shaking)
|
|
58
|
+
|
|
59
|
+
No need to update `package.json` or `tsup.config.ts` - they're already configured to handle all config files automatically!
|