|
@@ -110,7 +110,7 @@ export function OverlayLoader({ fetchState, isModelReady, color, active }) {
|
|
|
left: 0,
|
|
left: 0,
|
|
|
width: "100%",
|
|
width: "100%",
|
|
|
height: "100%",
|
|
height: "100%",
|
|
|
- background: "#ffffff",
|
|
|
|
|
|
|
+ // background: "#ffffff", // 移除白色背景
|
|
|
display: "flex",
|
|
display: "flex",
|
|
|
alignItems: "center",
|
|
alignItems: "center",
|
|
|
justifyContent: "center",
|
|
justifyContent: "center",
|
|
@@ -138,8 +138,7 @@ export function OverlayLoader({ fetchState, isModelReady, color, active }) {
|
|
|
transform: `scaleX(${progress / 100})`,
|
|
transform: `scaleX(${progress / 100})`,
|
|
|
transformOrigin: "left",
|
|
transformOrigin: "left",
|
|
|
height: "100%",
|
|
height: "100%",
|
|
|
- background: color || "#4C7F7A",
|
|
|
|
|
- transition: "transform 0.2s linear",
|
|
|
|
|
|
|
+ background: color || "#4C7F7A"
|
|
|
}}
|
|
}}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -235,9 +234,9 @@ function FitWatcher({ controlsRef, onFitReady, zoomMin }) {
|
|
|
useFrame(() => {
|
|
useFrame(() => {
|
|
|
if (!controlsRef.current || isFitted.current) return;
|
|
if (!controlsRef.current || isFitted.current) return;
|
|
|
|
|
|
|
|
- // 强制等待至少 1000ms,确保 Bounds 有足够时间启动动画,且避免缓存加载时 Loader 闪现
|
|
|
|
|
|
|
+ // 强制等待至少 300ms,确保 Bounds 有足够时间启动动画,且避免缓存加载时 Loader 闪现
|
|
|
// 这段时间内,Loader 会一直遮挡屏幕
|
|
// 这段时间内,Loader 会一直遮挡屏幕
|
|
|
- if (Date.now() - startTime.current < 1000) return;
|
|
|
|
|
|
|
+ if (Date.now() - startTime.current < 300) return;
|
|
|
|
|
|
|
|
const controls = controlsRef.current;
|
|
const controls = controlsRef.current;
|
|
|
const currentPos = camera.position;
|
|
const currentPos = camera.position;
|
|
@@ -539,14 +538,6 @@ function SceneContent({ url, zoomMin, zoomMax, fileType, onReady }) {
|
|
|
const newPos = calculateZoomPos(f, true); // true = zoomIn
|
|
const newPos = calculateZoomPos(f, true); // true = zoomIn
|
|
|
if (newPos) {
|
|
if (newPos) {
|
|
|
animateCamera(newPos, () => {
|
|
animateCamera(newPos, () => {
|
|
|
- // 关键修改:缩放完成后,更新 initialState,这样后续复位就会回到这个新位置
|
|
|
|
|
- if (initialState.current) {
|
|
|
|
|
- initialState.current.position.copy(newPos);
|
|
|
|
|
- // target 通常不变,但为了保险也同步一下当前 target
|
|
|
|
|
- if (controlsRef.current) {
|
|
|
|
|
- initialState.current.target.copy(controlsRef.current.target);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
if (onDone) onDone();
|
|
if (onDone) onDone();
|
|
|
});
|
|
});
|
|
|
} else if (onDone) {
|
|
} else if (onDone) {
|
|
@@ -575,13 +566,6 @@ function SceneContent({ url, zoomMin, zoomMax, fileType, onReady }) {
|
|
|
const newPos = calculateZoomPos(f, false); // false = zoomOut
|
|
const newPos = calculateZoomPos(f, false); // false = zoomOut
|
|
|
if (newPos) {
|
|
if (newPos) {
|
|
|
animateCamera(newPos, () => {
|
|
animateCamera(newPos, () => {
|
|
|
- // 关键修改:更新 initialState
|
|
|
|
|
- if (initialState.current) {
|
|
|
|
|
- initialState.current.position.copy(newPos);
|
|
|
|
|
- if (controlsRef.current) {
|
|
|
|
|
- initialState.current.target.copy(controlsRef.current.target);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
if (onDone) onDone();
|
|
if (onDone) onDone();
|
|
|
});
|
|
});
|
|
|
} else if (onDone) {
|
|
} else if (onDone) {
|
|
@@ -643,12 +627,13 @@ function SceneContent({ url, zoomMin, zoomMax, fileType, onReady }) {
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export default function Scene({ blobUrl, zoomMin, zoomMax, onModelReady }) {
|
|
|
|
|
|
|
+export default function Scene({ blobUrl, zoomMin, zoomMax, onModelReady, fileType: externalFileType }) {
|
|
|
// 推断文件类型,传递给 ModelLoader
|
|
// 推断文件类型,传递给 ModelLoader
|
|
|
const fileType = useMemo(() => {
|
|
const fileType = useMemo(() => {
|
|
|
|
|
+ if (externalFileType) return externalFileType;
|
|
|
if (!blobUrl) return null;
|
|
if (!blobUrl) return null;
|
|
|
return "gltf"; // 默认
|
|
return "gltf"; // 默认
|
|
|
- }, [blobUrl]);
|
|
|
|
|
|
|
+ }, [blobUrl, externalFileType]);
|
|
|
|
|
|
|
|
// 为了保持兼容,我们还是需要真实的 URL 来推断类型,或者修改 App 传 fileType
|
|
// 为了保持兼容,我们还是需要真实的 URL 来推断类型,或者修改 App 传 fileType
|
|
|
// 这里暂时简化,假设都是 gltf,如果需要支持 fbx,App 需要传 fileType
|
|
// 这里暂时简化,假设都是 gltf,如果需要支持 fbx,App 需要传 fileType
|