@tscircuit/3d-viewer 0.0.439 → 0.0.440
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 +391 -44
- 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
|
|
14231
|
+
import { useState as useState36, useCallback as useCallback22, useRef as useRef26, useEffect as useEffect42, useMemo as useMemo28 } from "react";
|
|
14232
14232
|
import * as THREE29 from "three";
|
|
14233
14233
|
|
|
14234
14234
|
// src/CadViewerJscad.tsx
|
|
@@ -28288,7 +28288,7 @@ import * as THREE15 from "three";
|
|
|
28288
28288
|
// package.json
|
|
28289
28289
|
var package_default = {
|
|
28290
28290
|
name: "@tscircuit/3d-viewer",
|
|
28291
|
-
version: "0.0.
|
|
28291
|
+
version: "0.0.439",
|
|
28292
28292
|
main: "./dist/index.js",
|
|
28293
28293
|
module: "./dist/index.js",
|
|
28294
28294
|
type: "module",
|
|
@@ -34503,8 +34503,110 @@ var useGlobalDownloadGltf = () => {
|
|
|
34503
34503
|
}, []);
|
|
34504
34504
|
};
|
|
34505
34505
|
|
|
34506
|
+
// src/hooks/useRegisteredHotkey.ts
|
|
34507
|
+
import { useEffect as useEffect25, useMemo as useMemo21, useRef as useRef11, useState as useState18 } from "react";
|
|
34508
|
+
var hotkeyRegistry = /* @__PURE__ */ new Map();
|
|
34509
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
34510
|
+
var isListenerAttached = false;
|
|
34511
|
+
var matchesKey = (eventKey, targetKey) => {
|
|
34512
|
+
if (!eventKey || !targetKey) return false;
|
|
34513
|
+
return eventKey.toLowerCase() === targetKey.toLowerCase();
|
|
34514
|
+
};
|
|
34515
|
+
var matchesModifiers = (event, modifiers) => {
|
|
34516
|
+
if (!modifiers || modifiers.length === 0) {
|
|
34517
|
+
return !event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey;
|
|
34518
|
+
}
|
|
34519
|
+
const hasCtrl = modifiers.includes("Ctrl");
|
|
34520
|
+
const hasCmd = modifiers.includes("Cmd");
|
|
34521
|
+
const hasShift = modifiers.includes("Shift");
|
|
34522
|
+
const hasAlt = modifiers.includes("Alt");
|
|
34523
|
+
if (hasCtrl && !event.ctrlKey) return false;
|
|
34524
|
+
if (hasCmd && !event.metaKey) return false;
|
|
34525
|
+
if (hasShift && !event.shiftKey) return false;
|
|
34526
|
+
if (hasAlt && !event.altKey) return false;
|
|
34527
|
+
return true;
|
|
34528
|
+
};
|
|
34529
|
+
var isEditableTarget = (target) => {
|
|
34530
|
+
if (!target || typeof target !== "object") return false;
|
|
34531
|
+
const element = target;
|
|
34532
|
+
const tagName = element.tagName;
|
|
34533
|
+
const editableTags = ["INPUT", "TEXTAREA", "SELECT"];
|
|
34534
|
+
if (editableTags.includes(tagName)) {
|
|
34535
|
+
return true;
|
|
34536
|
+
}
|
|
34537
|
+
return Boolean(element.getAttribute?.("contenteditable"));
|
|
34538
|
+
};
|
|
34539
|
+
var handleKeydown = (event) => {
|
|
34540
|
+
if (isEditableTarget(event.target)) {
|
|
34541
|
+
return;
|
|
34542
|
+
}
|
|
34543
|
+
hotkeyRegistry.forEach((entry) => {
|
|
34544
|
+
if (matchesKey(event.key, entry.key) && matchesModifiers(event, entry.modifiers)) {
|
|
34545
|
+
event.preventDefault();
|
|
34546
|
+
entry.invoke();
|
|
34547
|
+
}
|
|
34548
|
+
});
|
|
34549
|
+
};
|
|
34550
|
+
var notifySubscribers = () => {
|
|
34551
|
+
const entries = Array.from(hotkeyRegistry.values());
|
|
34552
|
+
subscribers.forEach((subscriber) => subscriber(entries));
|
|
34553
|
+
};
|
|
34554
|
+
var ensureListener = () => {
|
|
34555
|
+
if (isListenerAttached) return;
|
|
34556
|
+
if (typeof window === "undefined") return;
|
|
34557
|
+
window.addEventListener("keydown", handleKeydown);
|
|
34558
|
+
isListenerAttached = true;
|
|
34559
|
+
};
|
|
34560
|
+
var registerHotkey = (registration) => {
|
|
34561
|
+
hotkeyRegistry.set(registration.id, registration);
|
|
34562
|
+
notifySubscribers();
|
|
34563
|
+
ensureListener();
|
|
34564
|
+
};
|
|
34565
|
+
var unregisterHotkey = (id) => {
|
|
34566
|
+
if (hotkeyRegistry.delete(id)) {
|
|
34567
|
+
notifySubscribers();
|
|
34568
|
+
}
|
|
34569
|
+
};
|
|
34570
|
+
var subscribeToRegistry = (subscriber) => {
|
|
34571
|
+
subscribers.add(subscriber);
|
|
34572
|
+
subscriber(Array.from(hotkeyRegistry.values()));
|
|
34573
|
+
return () => {
|
|
34574
|
+
subscribers.delete(subscriber);
|
|
34575
|
+
};
|
|
34576
|
+
};
|
|
34577
|
+
var useRegisteredHotkey = (id, handler, metadata) => {
|
|
34578
|
+
const handlerRef = useRef11(handler);
|
|
34579
|
+
handlerRef.current = handler;
|
|
34580
|
+
const normalizedMetadata = useMemo21(
|
|
34581
|
+
() => ({
|
|
34582
|
+
key: metadata.key,
|
|
34583
|
+
description: metadata.description,
|
|
34584
|
+
modifiers: metadata.modifiers
|
|
34585
|
+
}),
|
|
34586
|
+
[metadata.key, metadata.description, metadata.modifiers]
|
|
34587
|
+
);
|
|
34588
|
+
useEffect25(() => {
|
|
34589
|
+
const registration = {
|
|
34590
|
+
id,
|
|
34591
|
+
...normalizedMetadata,
|
|
34592
|
+
invoke: () => handlerRef.current()
|
|
34593
|
+
};
|
|
34594
|
+
registerHotkey(registration);
|
|
34595
|
+
return () => {
|
|
34596
|
+
unregisterHotkey(id);
|
|
34597
|
+
};
|
|
34598
|
+
}, [id, normalizedMetadata]);
|
|
34599
|
+
};
|
|
34600
|
+
var useHotkeyRegistry = () => {
|
|
34601
|
+
const [entries, setEntries] = useState18(
|
|
34602
|
+
() => Array.from(hotkeyRegistry.values())
|
|
34603
|
+
);
|
|
34604
|
+
useEffect25(() => subscribeToRegistry(setEntries), []);
|
|
34605
|
+
return entries;
|
|
34606
|
+
};
|
|
34607
|
+
|
|
34506
34608
|
// src/components/ContextMenu.tsx
|
|
34507
|
-
import { useState as
|
|
34609
|
+
import { useState as useState34 } from "react";
|
|
34508
34610
|
|
|
34509
34611
|
// node_modules/@radix-ui/react-dropdown-menu/dist/index.mjs
|
|
34510
34612
|
import * as React43 from "react";
|
|
@@ -38132,9 +38234,9 @@ function assignRef(ref, value) {
|
|
|
38132
38234
|
}
|
|
38133
38235
|
|
|
38134
38236
|
// node_modules/use-callback-ref/dist/es2015/useRef.js
|
|
38135
|
-
import { useState as
|
|
38237
|
+
import { useState as useState29 } from "react";
|
|
38136
38238
|
function useCallbackRef2(initialValue, callback) {
|
|
38137
|
-
var ref =
|
|
38239
|
+
var ref = useState29(function() {
|
|
38138
38240
|
return {
|
|
38139
38241
|
// value
|
|
38140
38242
|
value: initialValue,
|
|
@@ -39858,7 +39960,7 @@ var SubTrigger2 = DropdownMenuSubTrigger;
|
|
|
39858
39960
|
var SubContent2 = DropdownMenuSubContent;
|
|
39859
39961
|
|
|
39860
39962
|
// src/components/AppearanceMenu.tsx
|
|
39861
|
-
import { useState as
|
|
39963
|
+
import { useState as useState33 } from "react";
|
|
39862
39964
|
|
|
39863
39965
|
// src/components/Icons.tsx
|
|
39864
39966
|
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
@@ -39964,8 +40066,8 @@ var iconContainerStyles = {
|
|
|
39964
40066
|
};
|
|
39965
40067
|
var AppearanceMenu = () => {
|
|
39966
40068
|
const { visibility, toggleLayer } = useLayerVisibility();
|
|
39967
|
-
const [appearanceSubOpen, setAppearanceSubOpen] =
|
|
39968
|
-
const [hoveredItem, setHoveredItem] =
|
|
40069
|
+
const [appearanceSubOpen, setAppearanceSubOpen] = useState33(false);
|
|
40070
|
+
const [hoveredItem, setHoveredItem] = useState33(null);
|
|
39969
40071
|
return /* @__PURE__ */ jsxs7(Fragment9, { children: [
|
|
39970
40072
|
/* @__PURE__ */ jsx33(Separator2, { style: separatorStyles }),
|
|
39971
40073
|
/* @__PURE__ */ jsxs7(Sub2, { onOpenChange: setAppearanceSubOpen, children: [
|
|
@@ -40216,11 +40318,12 @@ var ContextMenu = ({
|
|
|
40216
40318
|
onEngineSwitch,
|
|
40217
40319
|
onCameraPresetSelect,
|
|
40218
40320
|
onAutoRotateToggle,
|
|
40219
|
-
onDownloadGltf
|
|
40321
|
+
onDownloadGltf,
|
|
40322
|
+
onOpenKeyboardShortcuts
|
|
40220
40323
|
}) => {
|
|
40221
40324
|
const { cameraType, setCameraType } = useCameraController();
|
|
40222
|
-
const [cameraSubOpen, setCameraSubOpen] =
|
|
40223
|
-
const [hoveredItem, setHoveredItem] =
|
|
40325
|
+
const [cameraSubOpen, setCameraSubOpen] = useState34(false);
|
|
40326
|
+
const [hoveredItem, setHoveredItem] = useState34(null);
|
|
40224
40327
|
return /* @__PURE__ */ jsx34(
|
|
40225
40328
|
"div",
|
|
40226
40329
|
{
|
|
@@ -40413,6 +40516,35 @@ var ContextMenu = ({
|
|
|
40413
40516
|
}
|
|
40414
40517
|
),
|
|
40415
40518
|
/* @__PURE__ */ jsx34(Separator2, { style: separatorStyles2 }),
|
|
40519
|
+
/* @__PURE__ */ jsxs8(
|
|
40520
|
+
Item22,
|
|
40521
|
+
{
|
|
40522
|
+
style: {
|
|
40523
|
+
...itemStyles2,
|
|
40524
|
+
...itemPaddingStyles2,
|
|
40525
|
+
backgroundColor: hoveredItem === "shortcuts" ? "#404040" : "transparent"
|
|
40526
|
+
},
|
|
40527
|
+
onSelect: onOpenKeyboardShortcuts,
|
|
40528
|
+
onMouseEnter: () => setHoveredItem("shortcuts"),
|
|
40529
|
+
onMouseLeave: () => setHoveredItem(null),
|
|
40530
|
+
onTouchStart: () => setHoveredItem("shortcuts"),
|
|
40531
|
+
children: [
|
|
40532
|
+
/* @__PURE__ */ jsx34("span", { style: { flex: 1, display: "flex", alignItems: "center" }, children: "Keyboard Shortcuts" }),
|
|
40533
|
+
/* @__PURE__ */ jsx34(
|
|
40534
|
+
"div",
|
|
40535
|
+
{
|
|
40536
|
+
style: {
|
|
40537
|
+
...badgeStyles,
|
|
40538
|
+
display: "flex",
|
|
40539
|
+
alignItems: "center"
|
|
40540
|
+
},
|
|
40541
|
+
children: "Shift+?"
|
|
40542
|
+
}
|
|
40543
|
+
)
|
|
40544
|
+
]
|
|
40545
|
+
}
|
|
40546
|
+
),
|
|
40547
|
+
/* @__PURE__ */ jsx34(Separator2, { style: separatorStyles2 }),
|
|
40416
40548
|
/* @__PURE__ */ jsx34(
|
|
40417
40549
|
"div",
|
|
40418
40550
|
{
|
|
@@ -40450,23 +40582,216 @@ var ContextMenu = ({
|
|
|
40450
40582
|
);
|
|
40451
40583
|
};
|
|
40452
40584
|
|
|
40585
|
+
// src/components/KeyboardShortcutsDialog.tsx
|
|
40586
|
+
import { useEffect as useEffect41, useMemo as useMemo27, useRef as useRef25, useState as useState35 } from "react";
|
|
40587
|
+
import { Fragment as Fragment10, jsx as jsx35, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
40588
|
+
var KeyboardShortcutsDialog = ({
|
|
40589
|
+
open,
|
|
40590
|
+
onClose
|
|
40591
|
+
}) => {
|
|
40592
|
+
const [query, setQuery] = useState35("");
|
|
40593
|
+
const inputRef = useRef25(null);
|
|
40594
|
+
const hotkeys = useHotkeyRegistry();
|
|
40595
|
+
useEffect41(() => {
|
|
40596
|
+
if (!open) return void 0;
|
|
40597
|
+
const handleKeyDown = (event) => {
|
|
40598
|
+
if (event.key === "Escape") {
|
|
40599
|
+
event.preventDefault();
|
|
40600
|
+
onClose();
|
|
40601
|
+
}
|
|
40602
|
+
};
|
|
40603
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
40604
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
40605
|
+
}, [open, onClose]);
|
|
40606
|
+
useEffect41(() => {
|
|
40607
|
+
if (open) {
|
|
40608
|
+
setTimeout(() => {
|
|
40609
|
+
inputRef.current?.focus();
|
|
40610
|
+
}, 0);
|
|
40611
|
+
}
|
|
40612
|
+
}, [open]);
|
|
40613
|
+
const filteredHotkeys = useMemo27(() => {
|
|
40614
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
40615
|
+
if (!normalizedQuery) {
|
|
40616
|
+
return hotkeys;
|
|
40617
|
+
}
|
|
40618
|
+
return hotkeys.filter((hotkey) => {
|
|
40619
|
+
const haystack = `${hotkey.key} ${hotkey.description}`;
|
|
40620
|
+
return haystack.toLowerCase().includes(normalizedQuery);
|
|
40621
|
+
});
|
|
40622
|
+
}, [hotkeys, query]);
|
|
40623
|
+
if (!open) {
|
|
40624
|
+
return null;
|
|
40625
|
+
}
|
|
40626
|
+
return /* @__PURE__ */ jsx35(
|
|
40627
|
+
"div",
|
|
40628
|
+
{
|
|
40629
|
+
role: "dialog",
|
|
40630
|
+
"aria-modal": "true",
|
|
40631
|
+
style: {
|
|
40632
|
+
position: "fixed",
|
|
40633
|
+
inset: 0,
|
|
40634
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
40635
|
+
display: "flex",
|
|
40636
|
+
alignItems: "center",
|
|
40637
|
+
justifyContent: "center",
|
|
40638
|
+
zIndex: 9999
|
|
40639
|
+
},
|
|
40640
|
+
onClick: onClose,
|
|
40641
|
+
children: /* @__PURE__ */ jsxs9(
|
|
40642
|
+
"div",
|
|
40643
|
+
{
|
|
40644
|
+
style: {
|
|
40645
|
+
backgroundColor: "#1f1f23",
|
|
40646
|
+
color: "#f8f8ff",
|
|
40647
|
+
borderRadius: 12,
|
|
40648
|
+
width: "min(640px, 90vw)",
|
|
40649
|
+
maxHeight: "80vh",
|
|
40650
|
+
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.45), 0 8px 20px rgba(0, 0, 0, 0.35)",
|
|
40651
|
+
display: "flex",
|
|
40652
|
+
flexDirection: "column",
|
|
40653
|
+
overflow: "hidden"
|
|
40654
|
+
},
|
|
40655
|
+
onClick: (event) => event.stopPropagation(),
|
|
40656
|
+
children: [
|
|
40657
|
+
/* @__PURE__ */ jsxs9(
|
|
40658
|
+
"header",
|
|
40659
|
+
{
|
|
40660
|
+
style: {
|
|
40661
|
+
padding: "20px 24px 12px",
|
|
40662
|
+
borderBottom: "1px solid rgba(255, 255, 255, 0.08)"
|
|
40663
|
+
},
|
|
40664
|
+
children: [
|
|
40665
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
40666
|
+
/* @__PURE__ */ jsx35(
|
|
40667
|
+
"h2",
|
|
40668
|
+
{
|
|
40669
|
+
style: {
|
|
40670
|
+
margin: 0,
|
|
40671
|
+
fontSize: "1.1rem",
|
|
40672
|
+
fontWeight: 600,
|
|
40673
|
+
letterSpacing: "0.02em"
|
|
40674
|
+
},
|
|
40675
|
+
children: "Keyboard Shortcuts"
|
|
40676
|
+
}
|
|
40677
|
+
),
|
|
40678
|
+
/* @__PURE__ */ jsx35(
|
|
40679
|
+
"button",
|
|
40680
|
+
{
|
|
40681
|
+
type: "button",
|
|
40682
|
+
onClick: onClose,
|
|
40683
|
+
style: {
|
|
40684
|
+
background: "transparent",
|
|
40685
|
+
border: "none",
|
|
40686
|
+
color: "rgba(255, 255, 255, 0.8)",
|
|
40687
|
+
fontSize: "1rem",
|
|
40688
|
+
cursor: "pointer"
|
|
40689
|
+
},
|
|
40690
|
+
children: "\u2715"
|
|
40691
|
+
}
|
|
40692
|
+
)
|
|
40693
|
+
] }),
|
|
40694
|
+
/* @__PURE__ */ jsx35(
|
|
40695
|
+
"input",
|
|
40696
|
+
{
|
|
40697
|
+
ref: inputRef,
|
|
40698
|
+
type: "text",
|
|
40699
|
+
placeholder: "Search shortcuts...",
|
|
40700
|
+
value: query,
|
|
40701
|
+
onChange: (event) => setQuery(event.target.value),
|
|
40702
|
+
style: {
|
|
40703
|
+
marginTop: 12,
|
|
40704
|
+
width: "calc(100% - 24px)",
|
|
40705
|
+
padding: "10px 12px",
|
|
40706
|
+
borderRadius: 8,
|
|
40707
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
40708
|
+
backgroundColor: "rgba(255, 255, 255, 0.05)",
|
|
40709
|
+
color: "white",
|
|
40710
|
+
fontSize: "0.95rem"
|
|
40711
|
+
}
|
|
40712
|
+
}
|
|
40713
|
+
)
|
|
40714
|
+
]
|
|
40715
|
+
}
|
|
40716
|
+
),
|
|
40717
|
+
/* @__PURE__ */ jsx35("div", { style: { overflowY: "auto" }, children: /* @__PURE__ */ jsxs9(
|
|
40718
|
+
"table",
|
|
40719
|
+
{
|
|
40720
|
+
style: {
|
|
40721
|
+
width: "100%",
|
|
40722
|
+
borderCollapse: "collapse",
|
|
40723
|
+
fontSize: "0.95rem"
|
|
40724
|
+
},
|
|
40725
|
+
children: [
|
|
40726
|
+
/* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs9("tr", { style: { textAlign: "left", color: "#a1a1b5" }, children: [
|
|
40727
|
+
/* @__PURE__ */ jsx35("th", { style: { padding: "12px 24px", width: "25%" }, children: "Key" }),
|
|
40728
|
+
/* @__PURE__ */ jsx35("th", { style: { padding: "12px 24px" }, children: "Description" })
|
|
40729
|
+
] }) }),
|
|
40730
|
+
/* @__PURE__ */ jsx35("tbody", { children: filteredHotkeys.length === 0 ? /* @__PURE__ */ jsx35("tr", { children: /* @__PURE__ */ jsx35(
|
|
40731
|
+
"td",
|
|
40732
|
+
{
|
|
40733
|
+
colSpan: 2,
|
|
40734
|
+
style: { padding: "24px", textAlign: "center" },
|
|
40735
|
+
children: "No shortcuts found"
|
|
40736
|
+
}
|
|
40737
|
+
) }) : filteredHotkeys.map((hotkey) => /* @__PURE__ */ jsxs9(
|
|
40738
|
+
"tr",
|
|
40739
|
+
{
|
|
40740
|
+
style: { borderTop: "1px solid rgba(255, 255, 255, 0.05)" },
|
|
40741
|
+
children: [
|
|
40742
|
+
/* @__PURE__ */ jsx35("td", { style: { padding: "12px 24px" }, children: /* @__PURE__ */ jsx35(
|
|
40743
|
+
"span",
|
|
40744
|
+
{
|
|
40745
|
+
style: {
|
|
40746
|
+
display: "inline-flex",
|
|
40747
|
+
alignItems: "center",
|
|
40748
|
+
justifyContent: "center",
|
|
40749
|
+
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
40750
|
+
borderRadius: 6,
|
|
40751
|
+
minWidth: 36,
|
|
40752
|
+
padding: "4px 8px",
|
|
40753
|
+
fontFamily: "monospace",
|
|
40754
|
+
fontSize: "0.95rem"
|
|
40755
|
+
},
|
|
40756
|
+
children: hotkey.modifiers?.length ? /* @__PURE__ */ jsxs9(Fragment10, { children: [
|
|
40757
|
+
hotkey.modifiers.map((mod) => `${mod}+`).join(""),
|
|
40758
|
+
hotkey.key.toUpperCase()
|
|
40759
|
+
] }) : hotkey.key.toUpperCase()
|
|
40760
|
+
}
|
|
40761
|
+
) }),
|
|
40762
|
+
/* @__PURE__ */ jsx35("td", { style: { padding: "12px 24px" }, children: hotkey.description })
|
|
40763
|
+
]
|
|
40764
|
+
},
|
|
40765
|
+
hotkey.id
|
|
40766
|
+
)) })
|
|
40767
|
+
]
|
|
40768
|
+
}
|
|
40769
|
+
) })
|
|
40770
|
+
]
|
|
40771
|
+
}
|
|
40772
|
+
)
|
|
40773
|
+
}
|
|
40774
|
+
);
|
|
40775
|
+
};
|
|
40776
|
+
|
|
40453
40777
|
// src/CadViewer.tsx
|
|
40454
|
-
import { jsx as
|
|
40778
|
+
import { jsx as jsx36, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
40455
40779
|
var CadViewerInner = (props) => {
|
|
40456
|
-
const [engine, setEngine] =
|
|
40457
|
-
const containerRef =
|
|
40458
|
-
const [
|
|
40780
|
+
const [engine, setEngine] = useState36("manifold");
|
|
40781
|
+
const containerRef = useRef26(null);
|
|
40782
|
+
const [isKeyboardShortcutsDialogOpen, setIsKeyboardShortcutsDialogOpen] = useState36(false);
|
|
40783
|
+
const [autoRotate, setAutoRotate] = useState36(() => {
|
|
40459
40784
|
const stored = window.localStorage.getItem("cadViewerAutoRotate");
|
|
40460
40785
|
return stored === "false" ? false : true;
|
|
40461
40786
|
});
|
|
40462
|
-
const [autoRotateUserToggled, setAutoRotateUserToggled] =
|
|
40787
|
+
const [autoRotateUserToggled, setAutoRotateUserToggled] = useState36(() => {
|
|
40463
40788
|
const stored = window.localStorage.getItem("cadViewerAutoRotateUserToggled");
|
|
40464
40789
|
return stored === "true";
|
|
40465
40790
|
});
|
|
40466
|
-
const [cameraPreset, setCameraPreset] =
|
|
40791
|
+
const [cameraPreset, setCameraPreset] = useState36("Custom");
|
|
40467
40792
|
const { cameraType, setCameraType } = useCameraController();
|
|
40468
40793
|
const { visibility, toggleLayer } = useLayerVisibility();
|
|
40469
|
-
const cameraControllerRef =
|
|
40794
|
+
const cameraControllerRef = useRef26(null);
|
|
40470
40795
|
const externalCameraControllerReady = props.onCameraControllerReady;
|
|
40471
40796
|
const {
|
|
40472
40797
|
menuVisible,
|
|
@@ -40475,10 +40800,10 @@ var CadViewerInner = (props) => {
|
|
|
40475
40800
|
contextMenuEventHandlers,
|
|
40476
40801
|
setMenuVisible
|
|
40477
40802
|
} = useContextMenu({ containerRef });
|
|
40478
|
-
const autoRotateUserToggledRef =
|
|
40803
|
+
const autoRotateUserToggledRef = useRef26(autoRotateUserToggled);
|
|
40479
40804
|
autoRotateUserToggledRef.current = autoRotateUserToggled;
|
|
40480
|
-
const isAnimatingRef =
|
|
40481
|
-
const lastPresetSelectTime =
|
|
40805
|
+
const isAnimatingRef = useRef26(false);
|
|
40806
|
+
const lastPresetSelectTime = useRef26(0);
|
|
40482
40807
|
const PRESET_COOLDOWN = 1e3;
|
|
40483
40808
|
const handleUserInteraction = useCallback22(() => {
|
|
40484
40809
|
if (isAnimatingRef.current || Date.now() - lastPresetSelectTime.current < PRESET_COOLDOWN) {
|
|
@@ -40518,35 +40843,46 @@ var CadViewerInner = (props) => {
|
|
|
40518
40843
|
isAnimatingRef,
|
|
40519
40844
|
lastPresetSelectTime
|
|
40520
40845
|
});
|
|
40521
|
-
|
|
40846
|
+
useRegisteredHotkey(
|
|
40847
|
+
"open_keyboard_shortcuts_dialog",
|
|
40848
|
+
() => {
|
|
40849
|
+
setIsKeyboardShortcutsDialogOpen(true);
|
|
40850
|
+
},
|
|
40851
|
+
{
|
|
40852
|
+
key: "?",
|
|
40853
|
+
description: "Open keyboard shortcuts",
|
|
40854
|
+
modifiers: ["Shift"]
|
|
40855
|
+
}
|
|
40856
|
+
);
|
|
40857
|
+
useEffect42(() => {
|
|
40522
40858
|
const stored = window.localStorage.getItem("cadViewerEngine");
|
|
40523
40859
|
if (stored === "jscad" || stored === "manifold") {
|
|
40524
40860
|
setEngine(stored);
|
|
40525
40861
|
}
|
|
40526
40862
|
}, []);
|
|
40527
|
-
|
|
40863
|
+
useEffect42(() => {
|
|
40528
40864
|
window.localStorage.setItem("cadViewerEngine", engine);
|
|
40529
40865
|
}, [engine]);
|
|
40530
|
-
|
|
40866
|
+
useEffect42(() => {
|
|
40531
40867
|
window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
|
|
40532
40868
|
}, [autoRotate]);
|
|
40533
|
-
|
|
40869
|
+
useEffect42(() => {
|
|
40534
40870
|
window.localStorage.setItem(
|
|
40535
40871
|
"cadViewerAutoRotateUserToggled",
|
|
40536
40872
|
String(autoRotateUserToggled)
|
|
40537
40873
|
);
|
|
40538
40874
|
}, [autoRotateUserToggled]);
|
|
40539
|
-
|
|
40875
|
+
useEffect42(() => {
|
|
40540
40876
|
const stored = window.localStorage.getItem("cadViewerCameraType");
|
|
40541
40877
|
if (stored === "orthographic" || stored === "perspective") {
|
|
40542
40878
|
setCameraType(stored);
|
|
40543
40879
|
}
|
|
40544
40880
|
}, [setCameraType]);
|
|
40545
|
-
|
|
40881
|
+
useEffect42(() => {
|
|
40546
40882
|
window.localStorage.setItem("cadViewerCameraType", cameraType);
|
|
40547
40883
|
}, [cameraType]);
|
|
40548
40884
|
const viewerKey = props.circuitJson ? JSON.stringify(props.circuitJson) : void 0;
|
|
40549
|
-
return /* @__PURE__ */
|
|
40885
|
+
return /* @__PURE__ */ jsxs10(
|
|
40550
40886
|
"div",
|
|
40551
40887
|
{
|
|
40552
40888
|
ref: containerRef,
|
|
@@ -40562,7 +40898,7 @@ var CadViewerInner = (props) => {
|
|
|
40562
40898
|
},
|
|
40563
40899
|
...contextMenuEventHandlers,
|
|
40564
40900
|
children: [
|
|
40565
|
-
engine === "jscad" ? /* @__PURE__ */
|
|
40901
|
+
engine === "jscad" ? /* @__PURE__ */ jsx36(
|
|
40566
40902
|
CadViewerJscad,
|
|
40567
40903
|
{
|
|
40568
40904
|
...props,
|
|
@@ -40571,7 +40907,7 @@ var CadViewerInner = (props) => {
|
|
|
40571
40907
|
onUserInteraction: handleUserInteraction,
|
|
40572
40908
|
onCameraControllerReady: handleCameraControllerReady
|
|
40573
40909
|
}
|
|
40574
|
-
) : /* @__PURE__ */
|
|
40910
|
+
) : /* @__PURE__ */ jsx36(
|
|
40575
40911
|
CadViewerManifold_default,
|
|
40576
40912
|
{
|
|
40577
40913
|
...props,
|
|
@@ -40581,7 +40917,7 @@ var CadViewerInner = (props) => {
|
|
|
40581
40917
|
onCameraControllerReady: handleCameraControllerReady
|
|
40582
40918
|
}
|
|
40583
40919
|
),
|
|
40584
|
-
/* @__PURE__ */
|
|
40920
|
+
/* @__PURE__ */ jsxs10(
|
|
40585
40921
|
"div",
|
|
40586
40922
|
{
|
|
40587
40923
|
style: {
|
|
@@ -40598,11 +40934,11 @@ var CadViewerInner = (props) => {
|
|
|
40598
40934
|
},
|
|
40599
40935
|
children: [
|
|
40600
40936
|
"Engine: ",
|
|
40601
|
-
/* @__PURE__ */
|
|
40937
|
+
/* @__PURE__ */ jsx36("b", { children: engine === "jscad" ? "JSCAD" : "Manifold" })
|
|
40602
40938
|
]
|
|
40603
40939
|
}
|
|
40604
40940
|
),
|
|
40605
|
-
menuVisible && /* @__PURE__ */
|
|
40941
|
+
menuVisible && /* @__PURE__ */ jsx36(
|
|
40606
40942
|
ContextMenu,
|
|
40607
40943
|
{
|
|
40608
40944
|
menuRef,
|
|
@@ -40622,8 +40958,19 @@ var CadViewerInner = (props) => {
|
|
|
40622
40958
|
onDownloadGltf: () => {
|
|
40623
40959
|
downloadGltf();
|
|
40624
40960
|
closeMenu();
|
|
40961
|
+
},
|
|
40962
|
+
onOpenKeyboardShortcuts: () => {
|
|
40963
|
+
setIsKeyboardShortcutsDialogOpen(true);
|
|
40964
|
+
closeMenu();
|
|
40625
40965
|
}
|
|
40626
40966
|
}
|
|
40967
|
+
),
|
|
40968
|
+
/* @__PURE__ */ jsx36(
|
|
40969
|
+
KeyboardShortcutsDialog,
|
|
40970
|
+
{
|
|
40971
|
+
open: isKeyboardShortcutsDialogOpen,
|
|
40972
|
+
onClose: () => setIsKeyboardShortcutsDialogOpen(false)
|
|
40973
|
+
}
|
|
40627
40974
|
)
|
|
40628
40975
|
]
|
|
40629
40976
|
},
|
|
@@ -40631,17 +40978,17 @@ var CadViewerInner = (props) => {
|
|
|
40631
40978
|
);
|
|
40632
40979
|
};
|
|
40633
40980
|
var CadViewer = (props) => {
|
|
40634
|
-
const defaultTarget =
|
|
40635
|
-
const initialCameraPosition =
|
|
40981
|
+
const defaultTarget = useMemo28(() => new THREE29.Vector3(0, 0, 0), []);
|
|
40982
|
+
const initialCameraPosition = useMemo28(
|
|
40636
40983
|
() => [5, -5, 5],
|
|
40637
40984
|
[]
|
|
40638
40985
|
);
|
|
40639
|
-
return /* @__PURE__ */
|
|
40986
|
+
return /* @__PURE__ */ jsx36(
|
|
40640
40987
|
CameraControllerProvider,
|
|
40641
40988
|
{
|
|
40642
40989
|
defaultTarget,
|
|
40643
40990
|
initialCameraPosition,
|
|
40644
|
-
children: /* @__PURE__ */
|
|
40991
|
+
children: /* @__PURE__ */ jsx36(LayerVisibilityProvider, { children: /* @__PURE__ */ jsx36(CadViewerInner, { ...props }) })
|
|
40645
40992
|
}
|
|
40646
40993
|
);
|
|
40647
40994
|
};
|
|
@@ -40925,10 +41272,10 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
|
|
|
40925
41272
|
|
|
40926
41273
|
// src/hooks/exporter/gltf.ts
|
|
40927
41274
|
import { GLTFExporter as GLTFExporter2 } from "three-stdlib";
|
|
40928
|
-
import { useEffect as
|
|
41275
|
+
import { useEffect as useEffect43, useState as useState37, useMemo as useMemo29, useCallback as useCallback23 } from "react";
|
|
40929
41276
|
function useSaveGltfAs(options = {}) {
|
|
40930
41277
|
const parse2 = useParser(options);
|
|
40931
|
-
const link =
|
|
41278
|
+
const link = useMemo29(() => document.createElement("a"), []);
|
|
40932
41279
|
const saveAs = async (filename) => {
|
|
40933
41280
|
const name = filename ?? options.filename ?? "";
|
|
40934
41281
|
if (options.binary == null) options.binary = name.endsWith(".glb");
|
|
@@ -40938,7 +41285,7 @@ function useSaveGltfAs(options = {}) {
|
|
|
40938
41285
|
link.dispatchEvent(new MouseEvent("click"));
|
|
40939
41286
|
URL.revokeObjectURL(url);
|
|
40940
41287
|
};
|
|
40941
|
-
|
|
41288
|
+
useEffect43(
|
|
40942
41289
|
() => () => {
|
|
40943
41290
|
link.remove();
|
|
40944
41291
|
instance = null;
|
|
@@ -40953,17 +41300,17 @@ function useSaveGltfAs(options = {}) {
|
|
|
40953
41300
|
}
|
|
40954
41301
|
function useExportGltfUrl(options = {}) {
|
|
40955
41302
|
const parse2 = useParser(options);
|
|
40956
|
-
const [url, setUrl] =
|
|
40957
|
-
const [error, setError] =
|
|
41303
|
+
const [url, setUrl] = useState37();
|
|
41304
|
+
const [error, setError] = useState37();
|
|
40958
41305
|
const ref = useCallback23(
|
|
40959
41306
|
(instance) => parse2(instance).then(setUrl).catch(setError),
|
|
40960
41307
|
[]
|
|
40961
41308
|
);
|
|
40962
|
-
|
|
41309
|
+
useEffect43(() => () => URL.revokeObjectURL(url), [url]);
|
|
40963
41310
|
return [ref, url, error];
|
|
40964
41311
|
}
|
|
40965
41312
|
function useParser(options = {}) {
|
|
40966
|
-
const exporter =
|
|
41313
|
+
const exporter = useMemo29(() => new GLTFExporter2(), []);
|
|
40967
41314
|
return (instance) => {
|
|
40968
41315
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
40969
41316
|
exporter.parse(
|