2026-05-21-00-58-25 增加WebGL降级并更新测试文档

This commit is contained in:
2026-05-21 01:36:15 +08:00
parent b07b04adeb
commit 464b1aab59
5 changed files with 227 additions and 2 deletions

View File

@@ -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 ...