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:
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:
Recommended by LinkedIn
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
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
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
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