JavaScript Window requestAnimationFrame()
Method: Requesting Animation Frame
The window.requestAnimationFrame()
method is a crucial part of creating smooth and efficient animations in web browsers. It tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint. This results in smoother animations and better performance compared to using setInterval()
or setTimeout()
.
What is requestAnimationFrame()
?
The requestAnimationFrame()
method is a browser API that optimizes animations by synchronizing them with the browser’s repaint cycle. Instead of setting a fixed interval with setInterval()
, requestAnimationFrame()
asks the browser to call your animation function right before it repaints the screen. This ensures animations are rendered at the optimal frame rate (typically 60 frames per second) and reduces unnecessary computations when the browser tab is inactive.
Purpose of requestAnimationFrame()
The primary purposes of requestAnimationFrame()
are to:
- Optimize Animation Performance: Ensure animations run smoothly and efficiently by synchronizing with the browser’s repaint cycle.
- Conserve System Resources: Reduce CPU usage and power consumption by only animating when the browser is ready to repaint.
- Improve User Experience: Deliver smoother, more visually appealing animations compared to traditional methods.
Syntax
The syntax for requestAnimationFrame()
is straightforward:
let animationID = window.requestAnimationFrame(callback);
Parameters
Parameter | Type | Description |
---|---|---|
`callback` | Function | The function to call before the next repaint. This function is passed a single argument, a `DOMHighResTimeStamp`, which indicates the current time when `requestAnimationFrame()` starts to execute callbacks. |
Return Value
animationID
: A long integer value that uniquely identifies the request. You can pass this value towindow.cancelAnimationFrame()
to cancel the animation frame request.
Basic Usage
Here’s a simple example demonstrating how to use requestAnimationFrame()
to create a basic animation:
<canvas
id="myCanvasRafa"
width="200"
height="100"
style="border: 1px solid black;"
></canvas>
<script>
const canvas_rafa = document.getElementById("myCanvasRafa");
const ctx_rafa = canvas_rafa.getContext("2d");
let x_rafa = 0;
function animate() {
ctx_rafa.clearRect(0, 0, canvas_rafa.width, canvas_rafa.height);
ctx_rafa.fillStyle = "red";
ctx_rafa.fillRect(x_rafa, 10, 50, 50);
x_rafa += 2;
if (x_rafa > canvas_rafa.width) {
x_rafa = -50;
}
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>
In this example, a red rectangle moves horizontally across the canvas. The animate()
function clears the canvas, draws the rectangle at an updated position, and then calls requestAnimationFrame()
to schedule the next frame.
Cancelling Animation Frames
To stop an animation created with requestAnimationFrame()
, you can use window.cancelAnimationFrame()
:
let animationID = requestAnimationFrame(animate);
// To cancel the animation:
cancelAnimationFrame(animationID);
Here’s an example that includes a button to start and stop the animation:
<canvas
id="myCanvasRafa2"
width="200"
height="100"
style="border: 1px solid black;"
></canvas>
<button id="startRafaButton">Start</button>
<button id="stopRafaButton">Stop</button>
<script>
const canvas_rafa2 = document.getElementById("myCanvasRafa2");
const ctx_rafa2 = canvas_rafa2.getContext("2d");
const startRafaButton = document.getElementById("startRafaButton");
const stopRafaButton = document.getElementById("stopRafaButton");
let x_rafa2 = 0;
let animationID_rafa;
let isAnimating = false;
function animate() {
ctx_rafa2.clearRect(0, 0, canvas_rafa2.width, canvas_rafa2.height);
ctx_rafa2.fillStyle = "blue";
ctx_rafa2.fillRect(x_rafa2, 10, 50, 50);
x_rafa2 += 2;
if (x_rafa2 > canvas_rafa2.width) {
x_rafa2 = -50;
}
animationID_rafa = requestAnimationFrame(animate);
}
startRafaButton.addEventListener("click", () => {
if (!isAnimating) {
isAnimating = true;
animate();
}
});
stopRafaButton.addEventListener("click", () => {
if (isAnimating) {
isAnimating = false;
cancelAnimationFrame(animationID_rafa);
}
});
</script>
This example adds “Start” and “Stop” buttons to control the animation. Clicking “Start” initiates the animation, and clicking “Stop” cancels it.
Advanced Usage: Timing and Synchronization
requestAnimationFrame()
provides a DOMHighResTimeStamp
to the callback function, indicating the time when the callback starts to execute. You can use this timestamp to create more accurate and synchronized animations.
<canvas
id="myCanvasRafa3"
width="200"
height="100"
style="border: 1px solid black;"
></canvas>
<script>
const canvas_rafa3 = document.getElementById("myCanvasRafa3");
const ctx_rafa3 = canvas_rafa3.getContext("2d");
let x_rafa3 = 0;
let lastTime = null;
function animate(time) {
if (lastTime != null) {
const timeDiff = time - lastTime;
const speed = timeDiff / 10; // pixels per millisecond
ctx_rafa3.clearRect(0, 0, canvas_rafa3.width, canvas_rafa3.height);
ctx_rafa3.fillStyle = "green";
ctx_rafa3.fillRect(x_rafa3, 10, 50, 50);
x_rafa3 += speed;
if (x_rafa3 > canvas_rafa3.width) {
x_rafa3 = -50;
}
}
lastTime = time;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
</script>
In this example, the animation speed is adjusted based on the time difference between frames, ensuring smoother motion regardless of frame rate variations.
Real-World Applications
requestAnimationFrame()
is used in a variety of real-world applications, including:
- Game Development: Creating smooth and responsive game animations.
- Interactive Graphics: Rendering dynamic and interactive graphics in web applications.
- UI Animations: Animating UI elements, such as transitions, effects, and progress indicators.
- Data Visualizations: Generating animated charts, graphs, and data visualizations.
Use Case Example: Animated Progress Bar
Let’s create a practical example that demonstrates how to use requestAnimationFrame()
to build a smooth animated progress bar.
<div style="width: 300px; border: 1px solid #ccc; margin-bottom: 20px;">
<div
id="progressBarRafa"
style="width: 0%; height: 20px; background-color: #4CAF50;"
></div>
</div>
<button id="startProgressBarRafaButton">Start Progress</button>
<script>
const progressBar_rafa = document.getElementById("progressBarRafa");
const startProgressBarButton = document.getElementById(
"startProgressBarRafaButton"
);
let width_rafa = 0;
let animationID_rafa_progress;
function animateProgress() {
width_rafa += 1;
progressBar_rafa.style.width = width_rafa + "%";
if (width_rafa >= 100) {
cancelAnimationFrame(animationID_rafa_progress);
} else {
animationID_rafa_progress = requestAnimationFrame(animateProgress);
}
}
startProgressBarButton.addEventListener("click", () => {
width_rafa = 0;
progressBar_rafa.style.width = "0%";
animationID_rafa_progress = requestAnimationFrame(animateProgress);
});
</script>
This example demonstrates:
- Smooth Animation: The progress bar smoothly fills from 0% to 100% using
requestAnimationFrame()
. - Dynamic Updates: The width of the progress bar is updated dynamically in the
animateProgress()
function. - Control: The animation stops when the progress bar reaches 100% using
cancelAnimationFrame()
.
Browser Support
The requestAnimationFrame()
method is widely supported across modern web browsers:
- Chrome
- Firefox
- Safari
- Edge
- Opera
Tips and Best Practices
- Always Use
requestAnimationFrame()
for Animations: Avoid usingsetInterval()
orsetTimeout()
for animations, as they are not synchronized with the browser’s repaint cycle and can lead to performance issues. - Cancel Animations When Not Needed: Use
cancelAnimationFrame()
to stop animations when they are no longer visible or active to conserve system resources. - Optimize Animation Logic: Keep the animation logic in the callback function as efficient as possible to ensure smooth performance.
- Use the Provided Timestamp: Utilize the
DOMHighResTimeStamp
provided to the callback function to create more accurate and synchronized animations.
Conclusion
The window.requestAnimationFrame()
method is an essential tool for creating smooth, efficient, and visually appealing animations in web applications. By synchronizing animations with the browser’s repaint cycle, it ensures optimal performance and conserves system resources. Understanding and utilizing requestAnimationFrame()
will significantly enhance the quality and performance of your web animations. 🚀