React Three Fiber's Pointer Events Tutorial

React Three Fiber's Pointer Events Tutorial

In this React Three Fiber tutorial, we will learn how to create simple animations based on Pointer events. First, we will clone (or download) the initial code.

git clone https://github.com/rbarbosa51/r3f-events-tutorial.git
cd r3f-events-tutorial
npm install        

This repo already has the required dependencies in the package.json file. These dependencies are Three and react-three/fiber which are core to React Three Fiber. Open the repo in your favorite code editor.

In the src directory, you will notice that there are several files. The “Box.jsx” and “Sphere.jsx" files are empty. Go to the “App.jsx”, it is the project's entry code. It is just a React functional component returning a single Div. 

We will first create the React Three Fiber’s Canvas. The Canvas is responsible for setting the HTML5 Canvas with the WebGL context. It handles the resizing and placement. The Canvas gets a camera prop that positions the camera on screen. Go to “Canvas.jsx”, and type the following code:

import { Canvas } from "@react-three/fiber"
function App() {
  return (
    <div className='App'>
      {/* Create the Canvas with a Camera at 0,0,3 */}
      <Canvas camera={[0,0,3]}>

      </Canvas>
    </div>
  )
}
export default App        

If you were to run the dev server ("npm run dev"), you would only see a black screen.

Go to the "Box.jsx" file. In this file, we will create a 3D box. Based on Three.JS, a 3D object is a mesh that contains some geometry and a material. The mesh needs to define its shape (via its vertices) and its appearance. We will create a regular React Functional Component named Box. Inside you will define the mesh as a return value. Write the following code:

export default function Box() {
    return (
        <mesh>
            <boxGeometry args={[1,1,1]} />
            <meshBasicMaterial color={0xff0000} />
        </mesh>
    )
}        

This mesh will have a size of 1 unit across its 3-dimensional axis (X, Y, Z). The mesh has a Basic Material (the different types of materials will not be covered in this tutorial). This material has a hexadecimal color of 0xff0000 (red).

Go to "App.jsx", then include the Box Component. Add the Box component inside the Canvas. Your "App.jsx" should now look like this:

import { Canvas } from "@react-three/fiber"
import Box from "./Box"
function App() {
  return (
    <div className='App'>
      <Canvas camera={[0,0,3]}>
        {/* Added Box component here */}
        <Box />
      </Canvas>
    </div>
  )
}
export default App        

Now run the development server and open in a browser:

npm run dev        

You should now see the following:

Article content
You should see a red cube.

Now we are going to create a Sphere. Go to the "Sphere.jsx" file. Then add the following code.

export default function Sphere() {
    return (
        <mesh>
            <sphereGeometry args={[1,16,16]} />
            <meshBasicMaterial color={0x00ff00} />
        </mesh>
    )
}        

Then go back to the App.jsx file and import the Sphere and added beneath the Box:

import { Canvas } from "@react-three/fiber"
import Box from "./Box"
import Sphere from "./Sphere"
function App() {
  return (
    <div className='App'>
      <Canvas camera={[0,0,3]}>
        <Box />
        {/* Added Sphere here */}
        <Sphere />
      </Canvas>
    </div>
  )
}
export default App        

Now run the dev server and you should see a green sphere

Article content
Notice that you will not see the red cube

You might have noticed that the red cube has disappeared. It is still percent the problem is that is in the same place as the sphere. We need to move them. First, we are going to add props to both the Box and Sphere components. Then we are going to spread the props inside the mesh. See the code snippet:

...
export default function Sphere(props) {
    return (
        <mesh {...props}>
... //Rest of code

export default function Box(props) {
    return (
        <mesh {...props}>
... //Rest of code        

Now go to the "App.jsx" file. Then add position props to both the Box and Sphere. Your code should look like this:

import { Canvas } from "@react-three/fiber"
import Box from "./Box"
import Sphere from "./Sphere"
function App() {
  return (
    <div className='App'>
      <Canvas camera={[0,0,3]}>
        <Box position={[-2,0,0]} />
        <Sphere position={[2,0,0]}/>
      </Canvas>
    </div>
  )
}
export default App        

Now run the dev server and you should see both the box and Sphere

Article content

In react three fiber, you do not need to create raycasters. The mesh component can just handle mouse (pointer) hover and clicks. First go to the "Box.jsx" file. Then import useState and useRef from react. You will also import useFrame from react-three/fiber

import { useState, useRef} from "react"
import { useFrame } from "@react-three/fiber"        

We need a reference to the mesh. Create a constant ref that takes the useRef hook. We then need to create hovered and clicked states. We are also going to add a useFrame function. We are also going to modify the mesh to include a scale and events. Type the following code:

// Add these imports
import { useState, useRef } from "react";
import { useFrame } from "@react-three/fiber";

export default function Box(props) {
  // The ref will be used to get a reference to the mesh
  const ref = useRef();
  // The hovered and clicked states will be used
  // to modify the behaviour of the cube when either hovered
  // or clicked
  const [hovered, setHovered] = useState(false);
  const [clicked, setClicked] = useState(false);
  //useFrame is react-three-fiber's animation framework
  // it abstracts the HTML Canvas requestAnimationFrame
  useFrame((state, delta) => {
    //if clicked begin animation
    if (clicked) {
      ref.current.rotation.y += delta;
      ref.current.rotation.x += delta;
      //Move up and down --> slowed down by a factor of 2
      ref.current.position.y = Math.sin(state.clock.getElapsedTime()) / 2;
    }
  });
  return (
    <mesh
      //This is the reference
      ref={ref}
      {...props}
      // The scale of the cube will increase or decrease based on
      // Weather it is hovered or no
      scale={hovered ? [1.5, 1.5, 1.5] : [1.0, 1.0, 1.0]}
      // It toggles the hovered state
      onPointerOver={() => setHovered(!hovered)}
      onPointerOut={() => setHovered(!hovered)}
      //When the cube is clicked, the animation begins
      onClick={() => setClicked(!clicked)}
    >
      <boxGeometry args={[1, 1, 1]} />
      {/* Modified basic material to add a wireframe -
          Wireframe allows you to better visualize the animation
      */}
      <meshBasicMaterial color={0xff0000} wireframe />
    </mesh>
  );
}
        

Run the dev server. Hover over and out the cube. Watch how the cube scales up and down. Click the cube and watch cube go up and down while it

Article content

As an exercise, modify the Sphere on your own to create the same effect.

Feel free to clone the Finished branch of this repo.

git clone https://github.com/rbarbosa51/r3f-events-tutorial.git -b Finished        

I sincerely hope that you enjoyed this tutorial.

Are you looking for a badass developer to join your team? I am looking for a new team to belong feel free to contact me.

#opentowork #hireme

I think you should have a look at Instahyre [ https://bit.ly/3LN6kbU ]. There are great job opputunities listed & Instahyre puts out good career related content

Like
Reply

To view or add a comment, sign in

More articles by Rafael Barbosa

  • React 19 Compiler Tutorial

    In this quick tutorial, I will show you how you can upgrade a React-Vite program to use the new React 19 Compiler. For…

  • Learn how to use Zustand: the best Redux alternative.

    Zustand is a very simplistic alternative to the Redux state management library. It is fast intuitive and overall simple…

    1 Comment
  • Format.JS (React-Intl) Tutorial

    In this tutorial, we are going to learn how to localize your React app text. This can be very handy whenever we want to…

  • React QRCode Generator Tutorial

    In this tutorial, we will learn how to create a simple QR Code generator using the react-qr-code npm package. Before we…

  • React Sentiment Analysis Tutorial

    In this tutorial, We will use a Hugging Face (https://huggingface.co/) AI-pretrained model to create a React sentiment…

    1 Comment
  • React Error Boundaries Components with TypeScript

    In this quick tutorial, we are going to learn how to use Error Boundaries in React with TypeScript. By the end of this…

  • React Three Fiber Tutorial

    In this simple tutorial, we are going to learn how to manipulate a 3D model with the use of the React-Three-Fiber…

    1 Comment

Others also viewed

Explore content categories