2026-05-21-00-58-25 增加WebGL降级并更新测试文档
This commit is contained in:
@@ -538,6 +538,7 @@ export function FusionThreeView({
|
||||
const modelPoseRef = useRef(modelPose);
|
||||
const [status, setStatus] = useState('准备融合 DICOM 与 STL');
|
||||
const [loadProgress, setLoadProgress] = useState(0);
|
||||
const [webglError, setWebglError] = useState<string | null>(null);
|
||||
const [axisProjection, setAxisProjection] = useState<AxisProjection>(defaultAxisProjection);
|
||||
const axisProjectionSignatureRef = useRef(axisProjectionSignature(defaultAxisProjection));
|
||||
const resetFusionViewRef = useRef<() => void>(() => undefined);
|
||||
@@ -551,6 +552,7 @@ export function FusionThreeView({
|
||||
if (!container || !volume) return;
|
||||
|
||||
container.innerHTML = '';
|
||||
setWebglError(null);
|
||||
setStatus('正在构建三维融合场景...');
|
||||
setLoadProgress(8);
|
||||
setAxisProjection(defaultAxisProjection);
|
||||
@@ -568,7 +570,19 @@ export function FusionThreeView({
|
||||
camera.up.set(0, 0, 1);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
let renderer: THREE.WebGLRenderer;
|
||||
try {
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
} catch {
|
||||
const message = '当前浏览器无法创建 WebGL 三维上下文';
|
||||
setStatus(message);
|
||||
setLoadProgress(100);
|
||||
setWebglError('三维融合视图暂不可用,请检查浏览器硬件加速、显卡驱动或远程桌面图形支持。二维 DICOM 与逆向分割映射功能仍可继续使用。');
|
||||
resetFusionViewRef.current = () => undefined;
|
||||
return () => {
|
||||
container.innerHTML = '';
|
||||
};
|
||||
}
|
||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
renderer.setSize(width, height);
|
||||
renderer.localClippingEnabled = true;
|
||||
@@ -897,6 +911,15 @@ export function FusionThreeView({
|
||||
return (
|
||||
<div className="relative h-full min-h-[520px] overflow-hidden rounded-3xl border border-slate-800 bg-black shadow-xl">
|
||||
<div ref={containerRef} className="absolute inset-0 cursor-grab active:cursor-grabbing" />
|
||||
{webglError && (
|
||||
<div className="absolute inset-0 z-20 flex items-center justify-center bg-slate-950/92 px-8 text-center">
|
||||
<div className="max-w-md rounded-2xl border border-amber-300/20 bg-slate-900/90 p-6 text-amber-50 shadow-2xl">
|
||||
<AlertCircle className="mx-auto mb-3 text-amber-300" size={30} />
|
||||
<p className="text-sm font-bold">三维融合视图无法启动</p>
|
||||
<p className="mt-3 text-xs leading-6 text-amber-100/75">{webglError}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="pointer-events-none absolute left-4 top-4 rounded-xl border border-white/10 bg-black/60 px-3 py-2 text-[10px] font-mono text-white/60">
|
||||
{status}
|
||||
</div>
|
||||
@@ -953,6 +976,7 @@ function CutSectionPreview({
|
||||
}) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const modelPoseRef = useRef(modelPose);
|
||||
const [webglError, setWebglError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
modelPoseRef.current = modelPose;
|
||||
@@ -963,6 +987,7 @@ function CutSectionPreview({
|
||||
if (!container || !project || !volume) return;
|
||||
|
||||
container.innerHTML = '';
|
||||
setWebglError(null);
|
||||
let disposed = false;
|
||||
let animationId = 0;
|
||||
const scene = new THREE.Scene();
|
||||
@@ -975,7 +1000,15 @@ function CutSectionPreview({
|
||||
camera.up.set(0, 0, 1);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
let renderer: THREE.WebGLRenderer;
|
||||
try {
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
} catch {
|
||||
setWebglError('当前浏览器无法创建 WebGL 三维上下文,STL 切面三维预览暂不可用。');
|
||||
return () => {
|
||||
container.innerHTML = '';
|
||||
};
|
||||
}
|
||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
renderer.setSize(width, height);
|
||||
renderer.localClippingEnabled = true;
|
||||
@@ -1218,6 +1251,13 @@ function CutSectionPreview({
|
||||
return (
|
||||
<div className="relative h-full min-h-[420px] overflow-hidden rounded-3xl border border-slate-800 bg-slate-950 shadow-2xl">
|
||||
<div ref={containerRef} className="absolute inset-0 cursor-grab active:cursor-grabbing" />
|
||||
{webglError && (
|
||||
<div className="absolute inset-0 flex items-center justify-center px-6 text-center">
|
||||
<div className="rounded-2xl border border-amber-300/20 bg-slate-900/90 p-5 text-xs font-bold leading-6 text-amber-100">
|
||||
{webglError}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{(!project || !volume) && (
|
||||
<div className="absolute inset-0 flex items-center justify-center text-xs font-bold text-white/40">
|
||||
正在载入 STL 切面...
|
||||
|
||||
Reference in New Issue
Block a user