@tscircuit/3d-viewer 0.0.431 → 0.0.432
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/index.js +111 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14228,7 +14228,7 @@ var require_browser = __commonJS({
|
|
|
14228
14228
|
});
|
|
14229
14229
|
|
|
14230
14230
|
// src/CadViewer.tsx
|
|
14231
|
-
import { useState as useState33, useCallback as useCallback20, useRef as
|
|
14231
|
+
import { useState as useState33, useCallback as useCallback20, useRef as useRef23, useEffect as useEffect39 } from "react";
|
|
14232
14232
|
|
|
14233
14233
|
// src/CadViewerJscad.tsx
|
|
14234
14234
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
@@ -28168,13 +28168,13 @@ var AnyCadComponent = ({
|
|
|
28168
28168
|
};
|
|
28169
28169
|
|
|
28170
28170
|
// src/CadViewerContainer.tsx
|
|
28171
|
-
import { forwardRef as forwardRef2, useMemo as useMemo15, useState as useState8 } from "react";
|
|
28171
|
+
import { forwardRef as forwardRef2, useMemo as useMemo15, useRef as useRef6, useState as useState8 } from "react";
|
|
28172
28172
|
import * as THREE14 from "three";
|
|
28173
28173
|
|
|
28174
28174
|
// package.json
|
|
28175
28175
|
var package_default = {
|
|
28176
28176
|
name: "@tscircuit/3d-viewer",
|
|
28177
|
-
version: "0.0.
|
|
28177
|
+
version: "0.0.431",
|
|
28178
28178
|
main: "./dist/index.js",
|
|
28179
28179
|
module: "./dist/index.js",
|
|
28180
28180
|
type: "module",
|
|
@@ -28460,7 +28460,7 @@ var configureRenderer = (renderer) => {
|
|
|
28460
28460
|
// src/react-three/Canvas.tsx
|
|
28461
28461
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
28462
28462
|
var Canvas = forwardRef(
|
|
28463
|
-
({ children, scene: sceneProps, camera: cameraProps, style }, ref) => {
|
|
28463
|
+
({ children, scene: sceneProps, camera: cameraProps, style, onCreated }, ref) => {
|
|
28464
28464
|
const mountRef = useRef4(null);
|
|
28465
28465
|
const [contextState, setContextState] = useState7(
|
|
28466
28466
|
null
|
|
@@ -28468,6 +28468,8 @@ var Canvas = forwardRef(
|
|
|
28468
28468
|
const frameListeners = useRef4(
|
|
28469
28469
|
[]
|
|
28470
28470
|
);
|
|
28471
|
+
const onCreatedRef = useRef4(void 0);
|
|
28472
|
+
onCreatedRef.current = onCreated;
|
|
28471
28473
|
const addFrameListener = useCallback4(
|
|
28472
28474
|
(listener) => {
|
|
28473
28475
|
frameListeners.current.push(listener);
|
|
@@ -28526,6 +28528,7 @@ var Canvas = forwardRef(
|
|
|
28526
28528
|
addFrameListener,
|
|
28527
28529
|
removeFrameListener
|
|
28528
28530
|
});
|
|
28531
|
+
onCreatedRef.current?.({ camera, renderer });
|
|
28529
28532
|
let animationFrameId;
|
|
28530
28533
|
const clock = new THREE10.Clock();
|
|
28531
28534
|
const animate = () => {
|
|
@@ -28585,10 +28588,17 @@ var OrbitControls = ({
|
|
|
28585
28588
|
return new ThreeOrbitControls(camera, renderer.domElement);
|
|
28586
28589
|
}, [camera, renderer]);
|
|
28587
28590
|
useEffect13(() => {
|
|
28588
|
-
|
|
28589
|
-
|
|
28591
|
+
onControlsChange?.(controls ?? null);
|
|
28592
|
+
return () => onControlsChange?.(null);
|
|
28593
|
+
}, [controls, onControlsChange]);
|
|
28594
|
+
useEffect13(() => {
|
|
28595
|
+
if (!controls) return;
|
|
28596
|
+
const handleChange = () => {
|
|
28597
|
+
onControlsChange?.(controls);
|
|
28598
|
+
};
|
|
28599
|
+
controls.addEventListener("change", handleChange);
|
|
28590
28600
|
return () => {
|
|
28591
|
-
|
|
28601
|
+
controls.removeEventListener("change", handleChange);
|
|
28592
28602
|
};
|
|
28593
28603
|
}, [controls, onControlsChange]);
|
|
28594
28604
|
useEffect13(() => {
|
|
@@ -28754,6 +28764,45 @@ var Lights = () => {
|
|
|
28754
28764
|
return null;
|
|
28755
28765
|
};
|
|
28756
28766
|
|
|
28767
|
+
// src/hooks/useSessionCamera.ts
|
|
28768
|
+
var CAMERA_KEY = "cadViewerCameraStateSession";
|
|
28769
|
+
var saveCameraToSession = (camera, controls) => {
|
|
28770
|
+
try {
|
|
28771
|
+
const savedCameraSession = {
|
|
28772
|
+
position: camera.position.toArray(),
|
|
28773
|
+
quaternion: camera.quaternion.toArray(),
|
|
28774
|
+
up: camera.up.toArray(),
|
|
28775
|
+
fov: camera.fov ?? 50,
|
|
28776
|
+
target: controls.target.toArray()
|
|
28777
|
+
};
|
|
28778
|
+
sessionStorage.setItem(CAMERA_KEY, JSON.stringify(savedCameraSession));
|
|
28779
|
+
} catch (err) {
|
|
28780
|
+
console.warn("Failed to save camera:", err);
|
|
28781
|
+
}
|
|
28782
|
+
};
|
|
28783
|
+
var loadCameraFromSession = (camera, controls) => {
|
|
28784
|
+
try {
|
|
28785
|
+
const raw = sessionStorage.getItem(CAMERA_KEY);
|
|
28786
|
+
if (!raw) return false;
|
|
28787
|
+
const state = JSON.parse(raw);
|
|
28788
|
+
camera.position.fromArray(state.position);
|
|
28789
|
+
camera.quaternion.fromArray(state.quaternion);
|
|
28790
|
+
camera.up.fromArray(state.up);
|
|
28791
|
+
if ("fov" in camera) {
|
|
28792
|
+
const persp = camera;
|
|
28793
|
+
persp.fov = state.fov;
|
|
28794
|
+
persp.updateProjectionMatrix?.();
|
|
28795
|
+
}
|
|
28796
|
+
controls.target.fromArray(state.target);
|
|
28797
|
+
controls.update();
|
|
28798
|
+
camera.updateMatrixWorld();
|
|
28799
|
+
return true;
|
|
28800
|
+
} catch (err) {
|
|
28801
|
+
console.warn("Failed to restore camera:", err);
|
|
28802
|
+
return false;
|
|
28803
|
+
}
|
|
28804
|
+
};
|
|
28805
|
+
|
|
28757
28806
|
// src/hooks/useCameraController.ts
|
|
28758
28807
|
import { useCallback as useCallback5, useEffect as useEffect16, useMemo as useMemo14, useRef as useRef5 } from "react";
|
|
28759
28808
|
import * as THREE13 from "three";
|
|
@@ -29045,6 +29094,10 @@ var CadViewerContainer = forwardRef2(
|
|
|
29045
29094
|
const [isInteractionEnabled, setIsInteractionEnabled] = useState8(
|
|
29046
29095
|
!clickToInteractEnabled
|
|
29047
29096
|
);
|
|
29097
|
+
const saveTimeoutRef = useRef6(null);
|
|
29098
|
+
const controlsRef = useRef6(null);
|
|
29099
|
+
const cameraRef = useRef6(null);
|
|
29100
|
+
const restoredOnceRef = useRef6(false);
|
|
29048
29101
|
const gridSectionSize = useMemo15(() => {
|
|
29049
29102
|
if (!boardDimensions) return 10;
|
|
29050
29103
|
const width10 = boardDimensions.width ?? 0;
|
|
@@ -29098,6 +29151,23 @@ var CadViewerContainer = forwardRef2(
|
|
|
29098
29151
|
ref,
|
|
29099
29152
|
scene: { up: new THREE14.Vector3(0, 0, 1) },
|
|
29100
29153
|
camera: { up: [0, 0, 1], position: initialCameraPosition },
|
|
29154
|
+
onCreated: ({ camera }) => {
|
|
29155
|
+
cameraRef.current = camera;
|
|
29156
|
+
if (!restoredOnceRef.current && controlsRef.current) {
|
|
29157
|
+
const restored = loadCameraFromSession(
|
|
29158
|
+
cameraRef.current,
|
|
29159
|
+
controlsRef.current
|
|
29160
|
+
);
|
|
29161
|
+
if (restored) restoredOnceRef.current = true;
|
|
29162
|
+
}
|
|
29163
|
+
if (controlsRef.current && !restoredOnceRef.current) {
|
|
29164
|
+
setTimeout(() => {
|
|
29165
|
+
if (cameraRef.current && controlsRef.current) {
|
|
29166
|
+
saveCameraToSession(cameraRef.current, controlsRef.current);
|
|
29167
|
+
}
|
|
29168
|
+
}, 0);
|
|
29169
|
+
}
|
|
29170
|
+
},
|
|
29101
29171
|
children: [
|
|
29102
29172
|
/* @__PURE__ */ jsx12(CameraAnimator, { ...cameraAnimatorProps }),
|
|
29103
29173
|
/* @__PURE__ */ jsx12(RotationTracker, {}),
|
|
@@ -29113,7 +29183,26 @@ var CadViewerContainer = forwardRef2(
|
|
|
29113
29183
|
enableDamping: true,
|
|
29114
29184
|
dampingFactor: 0.1,
|
|
29115
29185
|
target: orbitTarget,
|
|
29116
|
-
onControlsChange:
|
|
29186
|
+
onControlsChange: (controls) => {
|
|
29187
|
+
handleControlsChange(controls);
|
|
29188
|
+
controlsRef.current = controls;
|
|
29189
|
+
if (cameraRef.current && controlsRef.current && !restoredOnceRef.current) {
|
|
29190
|
+
const restored = loadCameraFromSession(
|
|
29191
|
+
cameraRef.current,
|
|
29192
|
+
controlsRef.current
|
|
29193
|
+
);
|
|
29194
|
+
if (restored) {
|
|
29195
|
+
restoredOnceRef.current = true;
|
|
29196
|
+
return;
|
|
29197
|
+
}
|
|
29198
|
+
}
|
|
29199
|
+
clearTimeout(saveTimeoutRef.current);
|
|
29200
|
+
saveTimeoutRef.current = setTimeout(() => {
|
|
29201
|
+
if (cameraRef.current && controlsRef.current) {
|
|
29202
|
+
saveCameraToSession(cameraRef.current, controlsRef.current);
|
|
29203
|
+
}
|
|
29204
|
+
}, 150);
|
|
29205
|
+
}
|
|
29117
29206
|
}
|
|
29118
29207
|
),
|
|
29119
29208
|
/* @__PURE__ */ jsx12(Lights, {}),
|
|
@@ -29237,7 +29326,7 @@ var useStlsFromGeom = (geom) => {
|
|
|
29237
29326
|
};
|
|
29238
29327
|
|
|
29239
29328
|
// src/hooks/useBoardGeomBuilder.ts
|
|
29240
|
-
import { useState as useState10, useEffect as useEffect18, useRef as
|
|
29329
|
+
import { useState as useState10, useEffect as useEffect18, useRef as useRef7 } from "react";
|
|
29241
29330
|
|
|
29242
29331
|
// src/soup-to-3d/index.ts
|
|
29243
29332
|
var import_primitives2 = __toESM(require_primitives(), 1);
|
|
@@ -31098,7 +31187,7 @@ var BoardGeomBuilder = class {
|
|
|
31098
31187
|
// src/hooks/useBoardGeomBuilder.ts
|
|
31099
31188
|
var useBoardGeomBuilder = (circuitJson) => {
|
|
31100
31189
|
const [boardGeom, setBoardGeom] = useState10(null);
|
|
31101
|
-
const isProcessingRef =
|
|
31190
|
+
const isProcessingRef = useRef7(false);
|
|
31102
31191
|
useEffect18(() => {
|
|
31103
31192
|
let isCancelled = false;
|
|
31104
31193
|
if (!circuitJson) {
|
|
@@ -31476,7 +31565,7 @@ import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
|
31476
31565
|
import { useEffect as useEffect22, useMemo as useMemo21, useState as useState15 } from "react";
|
|
31477
31566
|
|
|
31478
31567
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
31479
|
-
import { useState as useState14, useEffect as useEffect21, useMemo as useMemo20, useRef as
|
|
31568
|
+
import { useState as useState14, useEffect as useEffect21, useMemo as useMemo20, useRef as useRef8 } from "react";
|
|
31480
31569
|
import { su as su12 } from "@tscircuit/circuit-json-util";
|
|
31481
31570
|
import * as THREE24 from "three";
|
|
31482
31571
|
|
|
@@ -32821,7 +32910,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
32821
32910
|
const [pcbThickness, setPcbThickness] = useState14(null);
|
|
32822
32911
|
const [error, setError] = useState14(null);
|
|
32823
32912
|
const [isLoading, setIsLoading] = useState14(true);
|
|
32824
|
-
const manifoldInstancesForCleanup =
|
|
32913
|
+
const manifoldInstancesForCleanup = useRef8([]);
|
|
32825
32914
|
const boardData = useMemo20(() => {
|
|
32826
32915
|
const boards = su12(circuitJson).pcb_board.list();
|
|
32827
32916
|
if (boards.length === 0) {
|
|
@@ -33470,17 +33559,17 @@ try {
|
|
|
33470
33559
|
var CadViewerManifold_default = CadViewerManifold;
|
|
33471
33560
|
|
|
33472
33561
|
// src/hooks/useContextMenu.ts
|
|
33473
|
-
import { useState as useState16, useCallback as useCallback8, useRef as
|
|
33562
|
+
import { useState as useState16, useCallback as useCallback8, useRef as useRef9, useEffect as useEffect23 } from "react";
|
|
33474
33563
|
var useContextMenu = ({ containerRef }) => {
|
|
33475
33564
|
const [menuVisible, setMenuVisible] = useState16(false);
|
|
33476
33565
|
const [menuPos, setMenuPos] = useState16({
|
|
33477
33566
|
x: 0,
|
|
33478
33567
|
y: 0
|
|
33479
33568
|
});
|
|
33480
|
-
const menuRef =
|
|
33481
|
-
const interactionOriginPosRef =
|
|
33482
|
-
const longPressTimeoutRef =
|
|
33483
|
-
const ignoreNextContextMenuRef =
|
|
33569
|
+
const menuRef = useRef9(null);
|
|
33570
|
+
const interactionOriginPosRef = useRef9(null);
|
|
33571
|
+
const longPressTimeoutRef = useRef9(null);
|
|
33572
|
+
const ignoreNextContextMenuRef = useRef9(false);
|
|
33484
33573
|
const clearLongPressTimeout = () => {
|
|
33485
33574
|
if (longPressTimeoutRef.current !== null) {
|
|
33486
33575
|
clearTimeout(longPressTimeoutRef.current);
|
|
@@ -39594,7 +39683,7 @@ var ContextMenu = ({
|
|
|
39594
39683
|
import { jsx as jsx34, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
39595
39684
|
var CadViewerInner = (props) => {
|
|
39596
39685
|
const [engine, setEngine] = useState33("manifold");
|
|
39597
|
-
const containerRef =
|
|
39686
|
+
const containerRef = useRef23(null);
|
|
39598
39687
|
const [autoRotate, setAutoRotate] = useState33(() => {
|
|
39599
39688
|
const stored = window.localStorage.getItem("cadViewerAutoRotate");
|
|
39600
39689
|
return stored === "false" ? false : true;
|
|
@@ -39605,7 +39694,7 @@ var CadViewerInner = (props) => {
|
|
|
39605
39694
|
});
|
|
39606
39695
|
const [cameraPreset, setCameraPreset] = useState33("Custom");
|
|
39607
39696
|
const { visibility, toggleLayer } = useLayerVisibility();
|
|
39608
|
-
const cameraControllerRef =
|
|
39697
|
+
const cameraControllerRef = useRef23(null);
|
|
39609
39698
|
const externalCameraControllerReady = props.onCameraControllerReady;
|
|
39610
39699
|
const {
|
|
39611
39700
|
menuVisible,
|
|
@@ -39614,10 +39703,10 @@ var CadViewerInner = (props) => {
|
|
|
39614
39703
|
contextMenuEventHandlers,
|
|
39615
39704
|
setMenuVisible
|
|
39616
39705
|
} = useContextMenu({ containerRef });
|
|
39617
|
-
const autoRotateUserToggledRef =
|
|
39706
|
+
const autoRotateUserToggledRef = useRef23(autoRotateUserToggled);
|
|
39618
39707
|
autoRotateUserToggledRef.current = autoRotateUserToggled;
|
|
39619
|
-
const isAnimatingRef =
|
|
39620
|
-
const lastPresetSelectTime =
|
|
39708
|
+
const isAnimatingRef = useRef23(false);
|
|
39709
|
+
const lastPresetSelectTime = useRef23(0);
|
|
39621
39710
|
const PRESET_COOLDOWN = 1e3;
|
|
39622
39711
|
const handleUserInteraction = useCallback20(() => {
|
|
39623
39712
|
if (isAnimatingRef.current || Date.now() - lastPresetSelectTime.current < PRESET_COOLDOWN) {
|