Skip to content


 Zabbix
 Grafana
 Prometheus
 React Three Fiber
 Threejs and TypeScript
 SocketIO and TypeScript
 Blender Topological Earth
 Sweet Home 3D
 Design Patterns Python
 Design Patterns TypeScript
   
 Course Coupon Codes
Three.js and TypeScript
Kindle Edition
$6.99 $9.99 Paperback 
$22.99 $29.99




Design Patterns in TypeScript
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




Design Patterns in Python
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




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>
  )
}
Object3D.lookAt threejs.org

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