Heim > Fragen und Antworten > Hauptteil
In React Three Fiber habe ich eine React-Komponente, die ein Sprite generiert, das ich über alle Kamerazooms hinweg beibehalten möchte. Der Algorithmus scheint zu funktionieren (die Größe scheint sich mit der Zeit nicht zu ändern), aber ich kann beim Vergrößern und Verkleinern deutlich erkennen, wie er skaliert.
Ich habe an anderer Stelle ähnliche Operationen an Sprites gesehen, und es scheint gut zu funktionieren, ohne dass es zu Störungen kommt. Ich glaube, es gibt eine Art Verzögerung, bin mir aber nicht sicher, wo sie liegt und wie ich sie beheben kann.
Ich habe auch ein Video des Problems angehängt: https://drive.google.com/file/d/121XPY1pB5bNJr5EYNESnyPfLDdtEeIhn/view?usp=sharing
Ich habe den Code für die React-Komponente angehängt. Wie beim regulären React Three Fiber-Code wird dieser einfach in die Canvas-Komponente eingegeben:
function TestFunction() { const [scale, setScale] = useState(new Vector3(1, 1, 1)); const map = new THREE.TextureLoader().load("src/assets/Joshy.png"); let state = useThree(); let zoom = state.camera.zoom / 100; let scaler: Vector3 = new Vector3(1 / zoom, 1 / zoom, 1 / zoom); const handleMouseScroll = (event: WheelEvent) => { // Perform actions when the mouse is scrolled scaler.set(1 / zoom, 1 / zoom, 1 / zoom); setScale(scaler); }; useFrame(() => { window.document.addEventListener("wheel", handleMouseScroll, { capture: true, passive: true, }); }); return ( <sprite scale={scale}> <spriteMaterial map={map} /> </sprite> ); }
Ich hoffe, es sieht nicht so verzögert aus, da ich jeden Frame aktualisiere und daher nicht sicher bin, wo das Problem liegt.
Was ich suche, ist Folgendes: https://drive.google.com/file/d/1KtEcrikFJFYboC6LX0mFVttx2eSTia0c/view?usp=sharing Keine spürbare Verzögerung. Der Code, der diese verzögerungsfreie Version generiert, ist reines JavaScript Three.js.
const cont = document.documentElement; const [w, h] = [cont.clientWidth - 20, cont.clientHeight - 20]; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(50, w / h, 0.1, 100); camera.position.set(10, 10, 10); const renderer = new THREE.WebGLRenderer(); renderer.setSize(w, h); document.body.appendChild(renderer.domElement); const hlp = new THREE.AxesHelper(3); scene.add(hlp); const map = new THREE.TextureLoader().load( 'https://source.unsplash.com/random/200x200' ); const material = new THREE.SpriteMaterial({ map: map }); const sprite_scale = 4; const sprite = new THREE.Sprite(material); /* sprite.scale.set(sprite_scale, sprite_scale); */ const virtual_d = sprite.position.distanceTo(camera.position) *1.4/ sprite_scale; scene.add(sprite); const controls = new THREE.OrbitControls(camera, renderer.domElement); const render = () => { renderer.render(scene, camera); }; const animate = () => { requestAnimationFrame(animate); render(); }; document.addEventListener('wheel', scaler); function scaler() { const scale = sprite.position.distanceTo(camera.position)/2; console.log(sprite.position.distanceTo(camera.position) ) console.log("CAMERA POSITION: ", camera.position) sprite.scale.set(scale, scale); } animate();
Die Logik von gewöhnlichem Three.js und React Three Fiber fühlt sich gleich an, aber die Ergebnisse sind völlig unterschiedlich.
P粉7558637502024-04-07 10:49:22
您正在使用 React。
因此,使用“window.document.addEventListener”时请小心。 每次重新渲染组件时,都会创建一个新的事件侦听器,从而导致页面上出现许多事件侦听器。
相反,请考虑使用钩子。你可以在react- Three-drei中找到很多hooks。 我强烈推荐使用react-two-drei。
useEffect(() => { function handleMouseScroll() { //do something } window.addEventListener('wheel', handleMouseScroll); return () => { window.removeEventListener('wheel', handleMouseScroll); }; }, []);
就您而言,您正在 useFrame 中使用事件侦听器。然后,useFrame 每秒运行 60 次。您每秒创建 60 个事件侦听器。