将反应三纤维悬停在脸上

问题描述 投票:0回答:1

我仍然是整个 Three.js 生态系统的菜鸟,所以即使我找到非常接近解决方案的东西,我也会遇到困难。例如,我终于能够通过 seanwasere 在 Three.js Discoursethis CodeSandbox 上的评论找到如何在悬停时突出显示几何图形的面的解决方案。

如何将这段代码翻译为 React Three Fiber?

作为参考,让我在这里重现代码:

import * as THREE from "/build/three.module.js"; import { OrbitControls } from "/jsm/controls/OrbitControls.js"; import Stats from "/jsm/libs/stats.module.js"; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100 ); camera.position.z = 2; const light = new THREE.DirectionalLight(); light.position.set(2, 2, 10); scene.add(light); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement); const geometry = new THREE.BoxGeometry(); var materials = [ new THREE.MeshPhongMaterial({ color: 0x00ff00 }), new THREE.MeshPhongMaterial({ color: 0x00ff00 }), new THREE.MeshPhongMaterial({ color: 0x00ff00 }), new THREE.MeshPhongMaterial({ color: 0x00ff00 }), new THREE.MeshPhongMaterial({ color: 0x00ff00 }), new THREE.MeshPhongMaterial({ color: 0x00ff00 }) ]; const cube = new THREE.Mesh(geometry, materials); scene.add(cube); window.addEventListener( "resize", () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); render(); }, false ); renderer.domElement.addEventListener("mousemove", onMouseMove, false); const raycaster = new THREE.Raycaster(); let activeFaceIndex = 0; function onMouseMove(event) { raycaster.setFromCamera( { x: (event.clientX / renderer.domElement.clientWidth) * 2 - 1, y: -(event.clientY / renderer.domElement.clientHeight) * 2 + 1 }, camera ); const intersects = raycaster.intersectObject(cube, false); if (intersects.length > 0) { if ( intersects[0].face.materialIndex !== activeFaceIndex && activeFaceIndex !== -1 ) { materials[activeFaceIndex].color.setHex(0x00ff00); } activeFaceIndex = intersects[0].face.materialIndex; materials[activeFaceIndex].color.setHex(0xff0000); } else { if (activeFaceIndex !== -1) { materials[activeFaceIndex].color.setHex(0x00ff00); } activeFaceIndex = -1; } } const stats = Stats(); document.body.appendChild(stats.dom); var animate = function () { requestAnimationFrame(animate); cube.rotation.x += 0.01; cube.rotation.y += 0.01; controls.update(); render(); stats.update(); }; function render() { renderer.render(scene, camera); } animate();
关于如何突出显示脸上的三角形的另一个有用参考是

Mugen87,或在this JSFiddle

javascript three.js hover react-three-fiber
1个回答
2
投票
这里是基于CodeSandbox版本的

R3F版本

import React, { useRef, useState, Suspense } from 'react' import { createRoot } from 'react-dom/client' import { Canvas, useFrame } from '@react-three/fiber' import { Stats, OrbitControls, Environment } from '@react-three/drei' function Cube() { const ref = useRef() const [activeFaceIndex, setActiveFaceIndex] = useState(-1) useFrame((_, delta) => { ref.current.rotation.x += delta ref.current.rotation.y += 0.5 * delta }) return ( <mesh ref={ref} onPointerMove={({ face }) => { setActiveFaceIndex(face.materialIndex) }} onPointerOut={(e) => { setActiveFaceIndex(-1) }}> <boxGeometry /> <meshStandardMaterial attach={`material-0`} color={activeFaceIndex === 0 ? 'red' : 'green'} /> <meshStandardMaterial attach={`material-1`} color={activeFaceIndex === 1 ? 'red' : 'green'} /> <meshStandardMaterial attach={`material-2`} color={activeFaceIndex === 2 ? 'red' : 'green'} /> <meshStandardMaterial attach={`material-3`} color={activeFaceIndex === 3 ? 'red' : 'green'} /> <meshStandardMaterial attach={`material-4`} color={activeFaceIndex === 4 ? 'red' : 'green'} /> <meshStandardMaterial attach={`material-5`} color={activeFaceIndex === 5 ? 'red' : 'green'} /> </mesh> ) } function App() { return ( <Canvas camera={{ position: [0, 0, 2] }}> <directionalLight position={[1, 1, 1]} intensity={Math.PI} /> <ambientLight intensity={Math.PI / 8} /> <Cube /> <OrbitControls /> <Stats /> </Canvas> ) }
    
© www.soinside.com 2019 - 2024. All rights reserved.