Look At Mouse
Working Example
Description
The example takes the current mouse position on the screen and causes all Box
components to look at that position.
See the useFrame
function in ./src/Box.jsx
. The current mouse position is factored against the viewport height and width, then the ref
uses its Object3D.lookAt()
method to look at a position somewhere between the components current position and the cameras position.
Also see that the cameras own Object3D.lookAt()
method is also used in the useFrame
in ./src/App.jsx
to keep the center of the scene centered in the viewport.
./src/App.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | import { Canvas, useThree, useFrame } from '@react-three/fiber'
import Box from './Box'
import { Stats } from '@react-three/drei'
import { Vector3 } from 'three'
function Rig() {
const { camera, mouse } = useThree()
const vec = new Vector3()
return useFrame(() => {
camera.position.lerp(vec.set(mouse.x, mouse.y, camera.position.z), 0.05)
camera.lookAt(0, 0, 0)
})
}
export default function App() {
return (
<Canvas camera={{ position: [0, 0, 6] }}>
<directionalLight position={[0, 0, 1]} />
{[...Array(5).keys()].map((i) => (
<group key={i * 6}>
<Box position={[-5, -3 + i * 1.5, 0]} text={'S'} />
<Box position={[-3, -3 + i * 1.5, 0]} text={'B'} />
<Box position={[-1, -3 + i * 1.5, 0]} text={'C'} />
<Box position={[1, -3 + i * 1.5, 0]} text={'O'} />
<Box position={[3, -3 + i * 1.5, 0]} text={'D'} />
<Box position={[5, -3 + i * 1.5, 0]} text={'E'} />
</group>
))}
<Rig />
<Stats />
</Canvas>
)
}
|
./src/Box.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | import { useRef, useState, useMemo } from 'react'
import { useFrame } from '@react-three/fiber'
import { Color } from 'three'
import { Text } from '@react-three/drei'
export default function Box({ text, ...props }) {
const ref = useRef()
const black = useMemo(() => new Color('black'), [])
const lime = useMemo(() => new Color('lime'), [])
const [hovered, setHovered] = useState(false)
useFrame(({ mouse, viewport }) => {
const x = (mouse.x * viewport.width) / 2.5
const y = (mouse.y * viewport.height) / 2.5
ref.current.lookAt(x, y, 1)
ref.current.material.color.lerp(hovered ? lime : black, 0.05)
})
return (
<mesh
{...props}
ref={ref}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
>
<boxGeometry />
<meshStandardMaterial color={lime} />
<Text fontSize={0.5} position-z={0.501}>
{text}
</Text>
{props.children}
</mesh>
)
}
|
Useful Links
GitHub Branch
git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout lookAtMouse
npm install
npm start