#javascript #reactjs #three.js #react-three-fiber
#javascript #reactjs #three.js #реакция-трехволоконный
Вопрос:
Я пытаюсь прослушать события щелчка на моем реагирующем трехслойном холсте. Но я получаю другое событие при использовании addEventListener
.
onClick
свойство mesh возвращает следующее событие:
<mesh position={[0, 0, 0]} onClick={(e) => console.log('onClick mesh: ', e)}>
<boxGeometry attach="geometry" args={[10, 10, 10]} />
<meshStandardMaterial attach="material" color="hotpink" wireframe />
</mesh>
onClick mesh:
{dispatchConfig: Object, _targetInst: FiberNode, nativeEvent: MouseEvent, type: "click", target: Object…}
// This is the event I need!!
И добавление прослушивателя событий возвращает следующее событие:
const ThreeEventListener = () => {
const onClickDocument = (e) => {
console.log('onClick document listener: ', e)
}
useEffect(() => {
document.addEventListener('click', onClickDocument, false)
return () => document.removeEventListener('click', onClickDocument)
})
return null
}
onClick document listener:
MouseEvent {isTrusted: true, screenX: 1508, screenY: 427, clientX: 348, clientY: 178…}
// This is a normal DOM event from React that I dont need
Демонстрация (щелкните поле, чтобы запустить события)
Комментарии:
1. У Three нет событий, они поступают из R3F, который отслеживает события общего указателя, затем передает радиопередачи и формирует события уровня объекта. Добавив прослушиватели событий в холст, вы снова получите обычные события указателя. Но почему вы это делаете, в react вы не должны касаться dom.
Ответ №1:
Я предполагаю, что то, что вы получили в первый раз, — это экземпляр SyntheticEvent
, который React использует в качестве оболочки поверх собственных событий, в сочетании с некоторыми полезными для react-трехслойными полями — вот документ. В документе говорится, что есть собственное событие браузера и three.js полезные данные внутри их реализации события (это то, что вы получили).
Я предлагаю перенести то, что вам нужно, из собственного события в синтетическое:
event.nativeEvent
Ответ №2:
Вот близкое решение, использующее внешнюю библиотеку под названием three.interaction
:
import { Interaction } from 'three.interaction'
const ThreeEventListener = () => {
useEffect(() => {
// init three.interaction on mount
const interaction = new Interaction(gl, scene, camera);
}, [])
const onClickScene = (event) => {
console.log('onClick scene listener: ', e)
}
useEffect(() => {
// attach callbacks to clicks thanks to three.interaction
scene.on('click', onClickScene)
return () => scene.on('click', () => {})
})
return null
}
Событие, созданное three.interaction, выглядит следующим образом:
onClick scene listener: InteractionEvent {stopped: false, target: Scene, currentTarget: Scene, type: "click", data: InteractionData, …}
Комментарии:
1. Как бы вы это использовали? Я понимаю, как это работает, но не знаю, куда его поместить