In the previous post, we successfully rendered our first cube! (See it in action)
Now, let's add some movement and transform that static cube into a dynamic object.
For A quick refresher on how three js and three fiber you can follow this article
We'll be using the useFrame hook from react-three/fiber. This hook plays a crucial role in creating animations
UseFrame
The useFrame
hook takes a callback function as an argument and calls it just before each animation loop. The callback function receives two arguments state
and delta
.
-
State - This is the object that stores a lot of information about the current state, It contains information like:
- Clock - A three js clock object which tell us the current time and the delta time.
- Camera - A reference to the current active camera in the scene.
- Scene - A reference to the root scene object.
- gl - reference to the webGL rendering context.
- size - an object with height and width of the canvas.
- Viewport - an object containing the size of viewport in pixels.
- Delta - This number denotes the time elapsed after the last frame in seconds. It can be used to create the frame-independent animations, for eg: we can multiply the delta value with the desired change in position or rotation to ensure no matter what the frame rate of the device is, the objects are at the correct position.
While useFrame is powerful for animations, it's important to avoid performing heavy calculations within the callback function. This can negatively impact performance and cause stuttering in your animation.
Rotating the Cube
Enough theory, let's get into the action, we will store the reference of our Box geometry and in each animation loop, change the rotation by some factor.
import { useRef } from "react";
import { OrbitControls, Box } from "@react-three/drei";
import { Canvas, useFrame } from "@react-three/fiber";
//type
import type { Mesh } from "three";
const ROTATION_SPEED = 0.005;
function Cube() {
const boxRef = useRef<Mesh>(null);
useFrame(() => {
if (boxRef.current) {
boxRef.current.rotation.x += ROTATION_SPEED;
boxRef.current.rotation.y += ROTATION_SPEED;
}
});
return (
<Box ref={boxRef}>
<meshBasicMaterial color="orange" />
</Box>
);
}
export default function App() {
return (
<div style={{ height: "100vh", width: "100vw" }}>
<Canvas>
<OrbitControls />
<gridHelper />
<Cube />
</Canvas>
</div>
);
}
As a fun practice exercise, try creating a sphere that moves up and down repeatedly.
Top comments (0)