@omiron33/omi-neuron-web 0.2.25 → 0.2.26
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/{NeuronWebExplorer-DymAHZ22.d.ts → NeuronWebExplorer-BBTb828y.d.ts} +14 -1
- package/dist/{NeuronWebExplorer-rAKqX6sf.d.cts → NeuronWebExplorer-C7WGF5kT.d.cts} +14 -1
- package/dist/{chunk-XQ7UTBAR.js → chunk-QKCKZYLH.js} +91 -4
- package/dist/chunk-QKCKZYLH.js.map +1 -0
- package/dist/{chunk-TS7Y522S.cjs → chunk-RCLZFQVX.cjs} +91 -4
- package/dist/chunk-RCLZFQVX.cjs.map +1 -0
- package/dist/index.cjs +17 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/visualization/index.cjs +16 -16
- package/dist/visualization/index.d.cts +2 -2
- package/dist/visualization/index.d.ts +2 -2
- package/dist/visualization/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-TS7Y522S.cjs.map +0 -1
- package/dist/chunk-XQ7UTBAR.js.map +0 -1
|
@@ -339,6 +339,19 @@ interface NeuronWebProps {
|
|
|
339
339
|
onNodeDrag?: (node: NeuronNode, position: [number, number, number]) => void;
|
|
340
340
|
/** Called when a node drag operation completes. */
|
|
341
341
|
onNodeDragEnd?: (node: NeuronNode, position: [number, number, number]) => void;
|
|
342
|
+
/**
|
|
343
|
+
* Enable keyboard controls for camera movement:
|
|
344
|
+
* - WASD: Pan camera
|
|
345
|
+
* - Q/E: Zoom in/out
|
|
346
|
+
* This frees the mouse for node interaction.
|
|
347
|
+
*/
|
|
348
|
+
keyboardControls?: boolean | {
|
|
349
|
+
enabled: boolean;
|
|
350
|
+
/** Pan speed multiplier (default: 1) */
|
|
351
|
+
panSpeed?: number;
|
|
352
|
+
/** Zoom speed multiplier (default: 1) */
|
|
353
|
+
zoomSpeed?: number;
|
|
354
|
+
};
|
|
342
355
|
/** When set, plays a story beat by id using the built-in study path player. */
|
|
343
356
|
activeStoryBeatId?: string | null;
|
|
344
357
|
/** Optional override for story beat step duration (ms). */
|
|
@@ -424,7 +437,7 @@ interface NeuronWebExplorerProps {
|
|
|
424
437
|
renderLoadingState?: () => React__default.ReactNode;
|
|
425
438
|
}
|
|
426
439
|
|
|
427
|
-
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, selectedNode, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, domainColors, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, hoverCardSlots, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onEdgeClick, onBackgroundClick, onCameraChange, draggable, onNodeDrag, onNodeDragEnd, performanceMode, density, rendering, activeStoryBeatId, storyBeatStepDurationMs, onStoryBeatComplete, }: NeuronWebProps): React__default.ReactElement;
|
|
440
|
+
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, selectedNode, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, domainColors, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, hoverCardSlots, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onEdgeClick, onBackgroundClick, onCameraChange, draggable, onNodeDrag, onNodeDragEnd, keyboardControls, performanceMode, density, rendering, activeStoryBeatId, storyBeatStepDurationMs, onStoryBeatComplete, }: NeuronWebProps): React__default.ReactElement;
|
|
428
441
|
|
|
429
442
|
declare function NeuronWebExplorer(props: NeuronWebExplorerProps): React__default.ReactElement;
|
|
430
443
|
|
|
@@ -339,6 +339,19 @@ interface NeuronWebProps {
|
|
|
339
339
|
onNodeDrag?: (node: NeuronNode, position: [number, number, number]) => void;
|
|
340
340
|
/** Called when a node drag operation completes. */
|
|
341
341
|
onNodeDragEnd?: (node: NeuronNode, position: [number, number, number]) => void;
|
|
342
|
+
/**
|
|
343
|
+
* Enable keyboard controls for camera movement:
|
|
344
|
+
* - WASD: Pan camera
|
|
345
|
+
* - Q/E: Zoom in/out
|
|
346
|
+
* This frees the mouse for node interaction.
|
|
347
|
+
*/
|
|
348
|
+
keyboardControls?: boolean | {
|
|
349
|
+
enabled: boolean;
|
|
350
|
+
/** Pan speed multiplier (default: 1) */
|
|
351
|
+
panSpeed?: number;
|
|
352
|
+
/** Zoom speed multiplier (default: 1) */
|
|
353
|
+
zoomSpeed?: number;
|
|
354
|
+
};
|
|
342
355
|
/** When set, plays a story beat by id using the built-in study path player. */
|
|
343
356
|
activeStoryBeatId?: string | null;
|
|
344
357
|
/** Optional override for story beat step duration (ms). */
|
|
@@ -424,7 +437,7 @@ interface NeuronWebExplorerProps {
|
|
|
424
437
|
renderLoadingState?: () => React__default.ReactNode;
|
|
425
438
|
}
|
|
426
439
|
|
|
427
|
-
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, selectedNode, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, domainColors, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, hoverCardSlots, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onEdgeClick, onBackgroundClick, onCameraChange, draggable, onNodeDrag, onNodeDragEnd, performanceMode, density, rendering, activeStoryBeatId, storyBeatStepDurationMs, onStoryBeatComplete, }: NeuronWebProps): React__default.ReactElement;
|
|
440
|
+
declare function NeuronWeb({ graphData, className, style, fullHeight, isFullScreen, isLoading, error, selectedNode, focusNodeSlug, onFocusConsumed, visibleNodeSlugs, renderEmptyState, renderLoadingState, ariaLabel, theme, domainColors, layout, cameraFit, cardsMode, clickCard, clickZoom, studyPathRequest, onStudyPathComplete, renderNodeHover, renderNodeDetail, hoverCard, hoverCardSlots, onNodeHover, onNodeClick, onNodeDoubleClick, onNodeFocused, onEdgeClick, onBackgroundClick, onCameraChange, draggable, onNodeDrag, onNodeDragEnd, keyboardControls, performanceMode, density, rendering, activeStoryBeatId, storyBeatStepDurationMs, onStoryBeatComplete, }: NeuronWebProps): React__default.ReactElement;
|
|
428
441
|
|
|
429
442
|
declare function NeuronWebExplorer(props: NeuronWebExplorerProps): React__default.ReactElement;
|
|
430
443
|
|
|
@@ -2585,6 +2585,12 @@ var InteractionManager = class {
|
|
|
2585
2585
|
};
|
|
2586
2586
|
onBackgroundClick = () => {
|
|
2587
2587
|
};
|
|
2588
|
+
/** Called when pointer-down occurs on a node (before drag threshold). Use to disable controls. */
|
|
2589
|
+
onNodePointerDown = () => {
|
|
2590
|
+
};
|
|
2591
|
+
/** Called when pointer-up occurs without a drag. Use to re-enable controls. */
|
|
2592
|
+
onNodePointerUp = () => {
|
|
2593
|
+
};
|
|
2588
2594
|
onNodeDragStart = () => {
|
|
2589
2595
|
};
|
|
2590
2596
|
onNodeDrag = () => {
|
|
@@ -2635,6 +2641,7 @@ var InteractionManager = class {
|
|
|
2635
2641
|
this.pointerDownPosition.copy(this.pointer);
|
|
2636
2642
|
const node = this.getIntersectedNode(this.pointer);
|
|
2637
2643
|
if (node) {
|
|
2644
|
+
this.onNodePointerDown(node);
|
|
2638
2645
|
const nodeObject = this.nodeObjects.find(
|
|
2639
2646
|
(obj) => obj.userData?.nodeId === node.id
|
|
2640
2647
|
);
|
|
@@ -2676,7 +2683,10 @@ var InteractionManager = class {
|
|
|
2676
2683
|
this.dragNode = null;
|
|
2677
2684
|
return;
|
|
2678
2685
|
}
|
|
2679
|
-
this.dragNode
|
|
2686
|
+
if (this.dragNode) {
|
|
2687
|
+
this.onNodePointerUp();
|
|
2688
|
+
this.dragNode = null;
|
|
2689
|
+
}
|
|
2680
2690
|
if (!this.config.enableClick) return;
|
|
2681
2691
|
const node = this.getIntersectedNode(this.pointer);
|
|
2682
2692
|
if (node) {
|
|
@@ -2939,6 +2949,7 @@ function NeuronWeb({
|
|
|
2939
2949
|
draggable,
|
|
2940
2950
|
onNodeDrag,
|
|
2941
2951
|
onNodeDragEnd,
|
|
2952
|
+
keyboardControls,
|
|
2942
2953
|
performanceMode,
|
|
2943
2954
|
density,
|
|
2944
2955
|
rendering,
|
|
@@ -3378,6 +3389,75 @@ function NeuronWeb({
|
|
|
3378
3389
|
constrainToPlane: draggable.constrainToPlane ?? "xy"
|
|
3379
3390
|
};
|
|
3380
3391
|
}, [draggable]);
|
|
3392
|
+
const keyboardControlsConfig = useMemo(() => {
|
|
3393
|
+
if (!keyboardControls) return { enabled: false, panSpeed: 1, zoomSpeed: 1 };
|
|
3394
|
+
if (keyboardControls === true) {
|
|
3395
|
+
return { enabled: true, panSpeed: 1, zoomSpeed: 1 };
|
|
3396
|
+
}
|
|
3397
|
+
return {
|
|
3398
|
+
enabled: keyboardControls.enabled,
|
|
3399
|
+
panSpeed: keyboardControls.panSpeed ?? 1,
|
|
3400
|
+
zoomSpeed: keyboardControls.zoomSpeed ?? 1
|
|
3401
|
+
};
|
|
3402
|
+
}, [keyboardControls]);
|
|
3403
|
+
const pressedKeysRef = useRef(/* @__PURE__ */ new Set());
|
|
3404
|
+
useEffect(() => {
|
|
3405
|
+
if (!keyboardControlsConfig.enabled || !sceneManager) return;
|
|
3406
|
+
const basePanSpeed = 0.15 * keyboardControlsConfig.panSpeed;
|
|
3407
|
+
const baseZoomSpeed = 0.5 * keyboardControlsConfig.zoomSpeed;
|
|
3408
|
+
const handleKeyDown2 = (e) => {
|
|
3409
|
+
const key = e.key.toLowerCase();
|
|
3410
|
+
if (["w", "a", "s", "d", "q", "e"].includes(key)) {
|
|
3411
|
+
pressedKeysRef.current.add(key);
|
|
3412
|
+
e.preventDefault();
|
|
3413
|
+
}
|
|
3414
|
+
};
|
|
3415
|
+
const handleKeyUp = (e) => {
|
|
3416
|
+
const key = e.key.toLowerCase();
|
|
3417
|
+
pressedKeysRef.current.delete(key);
|
|
3418
|
+
};
|
|
3419
|
+
let animationFrameId;
|
|
3420
|
+
const animate = () => {
|
|
3421
|
+
const keys = pressedKeysRef.current;
|
|
3422
|
+
if (keys.size > 0) {
|
|
3423
|
+
const camera = sceneManager.camera;
|
|
3424
|
+
const controls = sceneManager.controls;
|
|
3425
|
+
const right = new THREE.Vector3();
|
|
3426
|
+
const up = new THREE.Vector3();
|
|
3427
|
+
camera.getWorldDirection(up);
|
|
3428
|
+
right.crossVectors(camera.up, up).normalize();
|
|
3429
|
+
up.copy(camera.up);
|
|
3430
|
+
let dx = 0, dy = 0, dz = 0;
|
|
3431
|
+
if (keys.has("a")) dx -= basePanSpeed;
|
|
3432
|
+
if (keys.has("d")) dx += basePanSpeed;
|
|
3433
|
+
if (keys.has("w")) dy += basePanSpeed;
|
|
3434
|
+
if (keys.has("s")) dy -= basePanSpeed;
|
|
3435
|
+
if (keys.has("q")) dz += baseZoomSpeed;
|
|
3436
|
+
if (keys.has("e")) dz -= baseZoomSpeed;
|
|
3437
|
+
const panOffset = right.multiplyScalar(dx).add(up.multiplyScalar(dy));
|
|
3438
|
+
camera.position.add(panOffset);
|
|
3439
|
+
controls.target.add(panOffset);
|
|
3440
|
+
if (dz !== 0) {
|
|
3441
|
+
const direction = new THREE.Vector3();
|
|
3442
|
+
camera.getWorldDirection(direction);
|
|
3443
|
+
const distance = camera.position.distanceTo(controls.target);
|
|
3444
|
+
const newDistance = Math.max(controls.minDistance, Math.min(controls.maxDistance, distance - dz));
|
|
3445
|
+
camera.position.copy(controls.target).add(direction.multiplyScalar(-newDistance));
|
|
3446
|
+
}
|
|
3447
|
+
controls.update();
|
|
3448
|
+
}
|
|
3449
|
+
animationFrameId = requestAnimationFrame(animate);
|
|
3450
|
+
};
|
|
3451
|
+
window.addEventListener("keydown", handleKeyDown2);
|
|
3452
|
+
window.addEventListener("keyup", handleKeyUp);
|
|
3453
|
+
animationFrameId = requestAnimationFrame(animate);
|
|
3454
|
+
return () => {
|
|
3455
|
+
window.removeEventListener("keydown", handleKeyDown2);
|
|
3456
|
+
window.removeEventListener("keyup", handleKeyUp);
|
|
3457
|
+
cancelAnimationFrame(animationFrameId);
|
|
3458
|
+
pressedKeysRef.current.clear();
|
|
3459
|
+
};
|
|
3460
|
+
}, [keyboardControlsConfig, sceneManager]);
|
|
3381
3461
|
const interactionManager = useMemo(() => {
|
|
3382
3462
|
if (!sceneManager) return null;
|
|
3383
3463
|
return new InteractionManager(sceneManager.scene, sceneManager.camera, sceneManager.renderer, {
|
|
@@ -4178,11 +4258,18 @@ function NeuronWeb({
|
|
|
4178
4258
|
}
|
|
4179
4259
|
};
|
|
4180
4260
|
if (dragConfig.enabled) {
|
|
4181
|
-
interactionManager.
|
|
4261
|
+
interactionManager.onNodePointerDown = () => {
|
|
4182
4262
|
if (sceneManager) {
|
|
4183
4263
|
sceneManager.controls.enabled = false;
|
|
4184
4264
|
}
|
|
4185
4265
|
};
|
|
4266
|
+
interactionManager.onNodePointerUp = () => {
|
|
4267
|
+
if (sceneManager) {
|
|
4268
|
+
sceneManager.controls.enabled = true;
|
|
4269
|
+
}
|
|
4270
|
+
};
|
|
4271
|
+
interactionManager.onNodeDragStart = () => {
|
|
4272
|
+
};
|
|
4186
4273
|
interactionManager.onNodeDrag = (node, position) => {
|
|
4187
4274
|
nodeRenderer.updateNodePosition(node.id, position);
|
|
4188
4275
|
if (onNodeDrag) {
|
|
@@ -4772,5 +4859,5 @@ function dedupePreserveOrder(values) {
|
|
|
4772
4859
|
}
|
|
4773
4860
|
|
|
4774
4861
|
export { DEFAULT_RENDERING_OPTIONS, DEFAULT_STATUS_COLORS, DEFAULT_THEME, NeuronContext, NeuronWeb, NeuronWebExplorer, SceneManager, ThemeEngine, applyFuzzyLayout, applyTreeLayout, createStoryBeat, createStudyPathFromBeat, createStudyPathFromNodeIds, getAutoPerformanceMode, normalizeStoryBeat, useNeuronContext, useNeuronGraph, validateStoryBeat };
|
|
4775
|
-
//# sourceMappingURL=chunk-
|
|
4776
|
-
//# sourceMappingURL=chunk-
|
|
4862
|
+
//# sourceMappingURL=chunk-QKCKZYLH.js.map
|
|
4863
|
+
//# sourceMappingURL=chunk-QKCKZYLH.js.map
|