Skip to content

Commit 4e2f46e

Browse files
rmarquisbchapuis
authored andcommitted
fix(web): resolve GLTF viewer visibility in workflow node outputs
- Remove CSS containment for compact mode to prevent ReactFlow interference - Add absolute positioning with high z-index for 180x180px Canvas visibility - Fix material transparency settings to preserve texture rendering - Enable GLTF rendering for "any" type parameters with model/gltf-binary mimeType - Add container overflow:visible to allow Canvas to escape bounds
1 parent 9ab6882 commit 4e2f46e

2 files changed

Lines changed: 56 additions & 33 deletions

File tree

apps/web/src/components/workflow/workflow-value-renderer.tsx

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,7 @@ function GltfModel({ url, onSceneLoad, wireframeMode }: GltfModelProps & { onSce
276276

277277
// Force material to be visible and properly configured
278278
mat.visible = true;
279-
mat.transparent = false;
280-
mat.opacity = 1.0;
279+
mat.transparent = true;
281280

282281
// Set wireframe mode (only for materials that support it)
283282
if ('wireframe' in mat) {
@@ -452,19 +451,43 @@ const GltfRenderer = React.memo(({
452451
);
453452
}
454453

455-
const viewerDimensions = compact
454+
const viewerDimensions = useMemo(() => compact
456455
? { width: 180, height: 180 }
457-
: { width: 320, height: 320 };
456+
: { width: 320, height: 320 }, [compact]);
458457

459458
// Calculate aspect ratio for camera positioning
460459
const aspectRatio = viewerDimensions.width / viewerDimensions.height;
461460

461+
// Memoized Canvas style to prevent re-renders and ensure consistent sizing
462+
const canvasStyle = useMemo(() => ({
463+
width: `${viewerDimensions.width}px`,
464+
height: `${viewerDimensions.height}px`,
465+
maxWidth: `${viewerDimensions.width}px`,
466+
maxHeight: `${viewerDimensions.height}px`,
467+
minWidth: `${viewerDimensions.width}px`,
468+
minHeight: `${viewerDimensions.height}px`,
469+
display: 'block', // Prevent any inline element spacing issues
470+
...(compact ? {
471+
position: 'absolute' as const,
472+
top: '0',
473+
left: '0',
474+
zIndex: 9999,
475+
} : {})
476+
}), [viewerDimensions.width, viewerDimensions.height, compact]);
477+
462478
return (
463479
<div className={compact ? "mt-1 space-y-2" : "mt-2 space-y-3"}>
464480
<GltfViewerErrorBoundary onError={handleError}>
465481
<div
466-
className="relative bg-slate-50 dark:bg-slate-900 rounded border gltf-canvas-container"
467-
style={{ width: viewerDimensions.width, height: viewerDimensions.height }}
482+
className={`${compact ? 'relative' : 'relative gltf-canvas-container'} bg-slate-50 dark:bg-slate-900 rounded border`}
483+
style={{
484+
width: viewerDimensions.width,
485+
height: viewerDimensions.height,
486+
...(compact ? {
487+
overflow: 'visible', // Allow absolute Canvas to escape container bounds
488+
zIndex: 1 // Ensure container doesn't interfere with Canvas z-index
489+
} : {})
490+
}}
468491
>
469492
<Canvas
470493
key={`gltf-canvas-${renderID.current}`} // Stable key per component instance
@@ -473,25 +496,28 @@ const GltfRenderer = React.memo(({
473496
fov: 50,
474497
// near and far will be set dynamically based on model size
475498
}}
476-
style={{
477-
width: `${viewerDimensions.width}px !important`,
478-
height: `${viewerDimensions.height}px !important`,
479-
maxWidth: `${viewerDimensions.width}px`,
480-
maxHeight: `${viewerDimensions.height}px`,
481-
minWidth: `${viewerDimensions.width}px`,
482-
minHeight: `${viewerDimensions.height}px`
483-
}}
484-
onCreated={({ gl }) => {
485-
// Force Three.js to respect our dimensions
499+
style={canvasStyle}
500+
dpr={1} // Force device pixel ratio to 1 to prevent scaling
501+
resize={{ scroll: false, debounce: 0 }} // Disable automatic resizing
502+
onCreated={({ gl, size }) => {
503+
// Log initial state for debugging
504+
console.log('Canvas onCreated - initial size:', size, 'intended:', viewerDimensions, 'compact:', compact);
505+
506+
// Force Three.js to respect our exact dimensions immediately
486507
gl.setSize(viewerDimensions.width, viewerDimensions.height, false);
487508

488-
// Ensure DOM element matches our intended size
509+
// Ensure DOM element matches our intended size (prevents any scaling animation)
489510
const canvas = gl.domElement;
490511
canvas.style.width = `${viewerDimensions.width}px`;
491512
canvas.style.height = `${viewerDimensions.height}px`;
492513
canvas.style.maxWidth = `${viewerDimensions.width}px`;
493514
canvas.style.maxHeight = `${viewerDimensions.height}px`;
494515

516+
// Set pixel ratio to 1 to prevent any scaling calculations
517+
gl.setPixelRatio(1);
518+
gl.setClearColor("#000000"); // Black background for better model visibility
519+
520+
495521
// Add minimal context loss monitoring
496522
gl.domElement.addEventListener('webglcontextlost', (e) => {
497523
console.error('WebGL Context Lost Event - preventing default');
@@ -541,9 +567,6 @@ const GltfRenderer = React.memo(({
541567
}, 150);
542568
}
543569

544-
545-
gl.setClearColor("#000000"); // Black background for better model visibility
546-
gl.setPixelRatio(Math.min(window.devicePixelRatio, 2));
547570
}}
548571
>
549572
{/* Enhanced lighting setup for better model visibility */}
@@ -1147,19 +1170,11 @@ export function WorkflowValueRenderer({
11471170
}
11481171
if (parameter.value.mimeType === "model/gltf-binary") {
11491172
return (
1150-
<div className={compact ? "mt-1 space-y-1" : "mt-2 space-y-2"}>
1151-
<div className="text-xs text-neutral-500">
1152-
glTF Model ({parameter.value.mimeType})
1153-
</div>
1154-
<a
1155-
href={objectUrl}
1156-
target="_blank"
1157-
rel="noopener noreferrer"
1158-
className="text-sm text-blue-500 hover:underline flex items-center"
1159-
>
1160-
Download GLB File
1161-
</a>
1162-
</div>
1173+
<GltfRenderer
1174+
parameter={parameter}
1175+
objectUrl={objectUrl}
1176+
compact={compact}
1177+
/>
11631178
);
11641179
}
11651180
if (

apps/web/src/index.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,12 @@ html.dark .shiki span {
251251
.gltf-canvas-container canvas {
252252
transform: none !important;
253253
image-rendering: auto;
254+
transition: none !important;
255+
animation: none !important;
256+
display: block !important;
257+
position: relative !important;
258+
z-index: 10 !important;
259+
background: #000 !important;
260+
opacity: 1 !important;
261+
visibility: visible !important;
254262
}

0 commit comments

Comments
 (0)