Anonymous
Холст Three.js отображается только тогда, когда я вручную изменяю область просмотра
Сообщение
Anonymous » 02 янв 2026, 20:54
У меня есть проект, который принимает GLB, разбивает его на два компонента и затем заполняет холст Three.js.
Он выглядит великолепно и полностью заполняется GLB, но только если я сначала захожу и вручную меняю область просмотра, иначе холст пуст и застревает в размере 300x150.
Код: Выделить всё
import { Canvas, extend } from '@react-three/fiber';
import {
OrbitControls,
useGLTF,
Environment,
PerformanceMonitor,
Preload
} from '@react-three/drei';
import {
EffectComposer,
Bloom,
Noise,
ToneMapping
} from '@react-three/postprocessing';
import React, { Suspense, useState } from 'react';
import { suspend } from 'suspend-react';
import { GLTFLoader } from 'three-stdlib';
import { Mesh } from 'three';
extend({ OrbitControls });
const environment = import('@pmndrs/assets/hdri/city.exr')
.then((module) => module.default);
useGLTF.preload('/animations/assembly.glb');
const Model = (
{ onAfterRender, onError }: {
onAfterRender?: () => void;
onError?: () => void
}
) => {
const [model, setModel] = useState();
React.useEffect(() => {
const loadModel = async () => {
try {
const gltf = await new GLTFLoader()
.loadAsync('/animations/assembly.glb');
setModel(gltf);
} catch (err) {
onError && onError();
}
};
loadModel();
}, [onError]);
if (!model) return null;
// Find meshes by name
const meshRFDD = model.scene.getObjectByName('RFDD_0');
const meshEdges = model.scene.getObjectByName('RFDD_edges_0');
if (!meshRFDD || !meshEdges) return null;
return (
);
};
const gradientBg = {
width: '100%',
height: '100%',
borderRadius: '1rem',
backgroundImage:
'radial-gradient(circle closest-corner at 25% 60%, rgba(238, 39, 39, 0.25), rgba(255, 255, 255, 0)), ' +
'radial-gradient(circle farthest-side at 71% 16%, rgba(154, 39, 238, 0.15), rgba(255, 255, 255, 0) 35%), ' +
'radial-gradient(circle closest-corner at 32% 38%, rgba(238, 164, 39, 0.1), rgba(255, 255, 255, 0) 76%), ' +
'radial-gradient(circle farthest-side at 69% 81%, rgba(255, 0, 48, 0.1), rgba(255, 255, 255, 0) 76%), ' +
'linear-gradient(#202124, #202124)',
};
const AssemblyViewer = () => {
const [dpr, setDpr] = useState(1.25);
const [fallback, setFallback] = useState(false);
// Hardware acceleration check (optional, simplified)
const hasHWA = typeof window !== 'undefined';
return (
{hasHWA && !fallback ? (
setDpr(Math.min(dpr + 0.25, 1.5))}
onDecline={() => setDpr(Math.max(dpr - 0.25, 0.75))}
/>
setFallback(true)} />
) : (
3D model could not be loaded or hardware acceleration is disabled.
)}
);
};
export default AssemblyViewer;
Я использую:
Next.js 16.0.10
React 19.2.3
Подробнее здесь:
https://stackoverflow.com/questions/798 ... e-viewport
1767376493
Anonymous
У меня есть проект, который принимает GLB, разбивает его на два компонента и затем заполняет холст Three.js. Он выглядит великолепно и полностью заполняется GLB, но только если я сначала захожу и вручную меняю область просмотра, иначе холст пуст и застревает в размере 300x150. [code]import { Canvas, extend } from '@react-three/fiber'; import { OrbitControls, useGLTF, Environment, PerformanceMonitor, Preload } from '@react-three/drei'; import { EffectComposer, Bloom, Noise, ToneMapping } from '@react-three/postprocessing'; import React, { Suspense, useState } from 'react'; import { suspend } from 'suspend-react'; import { GLTFLoader } from 'three-stdlib'; import { Mesh } from 'three'; extend({ OrbitControls }); const environment = import('@pmndrs/assets/hdri/city.exr') .then((module) => module.default); useGLTF.preload('/animations/assembly.glb'); const Model = ( { onAfterRender, onError }: { onAfterRender?: () => void; onError?: () => void } ) => { const [model, setModel] = useState(); React.useEffect(() => { const loadModel = async () => { try { const gltf = await new GLTFLoader() .loadAsync('/animations/assembly.glb'); setModel(gltf); } catch (err) { onError && onError(); } }; loadModel(); }, [onError]); if (!model) return null; // Find meshes by name const meshRFDD = model.scene.getObjectByName('RFDD_0'); const meshEdges = model.scene.getObjectByName('RFDD_edges_0'); if (!meshRFDD || !meshEdges) return null; return ( ); }; const gradientBg = { width: '100%', height: '100%', borderRadius: '1rem', backgroundImage: 'radial-gradient(circle closest-corner at 25% 60%, rgba(238, 39, 39, 0.25), rgba(255, 255, 255, 0)), ' + 'radial-gradient(circle farthest-side at 71% 16%, rgba(154, 39, 238, 0.15), rgba(255, 255, 255, 0) 35%), ' + 'radial-gradient(circle closest-corner at 32% 38%, rgba(238, 164, 39, 0.1), rgba(255, 255, 255, 0) 76%), ' + 'radial-gradient(circle farthest-side at 69% 81%, rgba(255, 0, 48, 0.1), rgba(255, 255, 255, 0) 76%), ' + 'linear-gradient(#202124, #202124)', }; const AssemblyViewer = () => { const [dpr, setDpr] = useState(1.25); const [fallback, setFallback] = useState(false); // Hardware acceleration check (optional, simplified) const hasHWA = typeof window !== 'undefined'; return ( {hasHWA && !fallback ? ( setDpr(Math.min(dpr + 0.25, 1.5))} onDecline={() => setDpr(Math.max(dpr - 0.25, 0.75))} /> setFallback(true)} /> ) : ( 3D model could not be loaded or hardware acceleration is disabled. )} ); }; export default AssemblyViewer; [/code] Я использую: [list] [*]Next.js 16.0.10 [*]React 19.2.3 [/list] Подробнее здесь: [url]https://stackoverflow.com/questions/79859280/three-js-canvas-only-displaying-when-i-manually-alter-the-viewport[/url]