How to animate objects on scroll with Tailwind CSS and the JavaScript intersection observer API

Good Monday everyone! Finally my favourite day of the week, and I’m excited to share with you a new tutorial on how to animate objects with Tailwind CSS and JavaScript intersection observer API. This tutorial will show you how to create a simple animation when an element enters the viewport, using the Intersection Observer API with JavaScript and Tailwind CSS.
What is the Intersection Observer API?
The Intersection Observer API is a JavaScript API that allows you to observe the visibility of elements on a web page. It provides a way to detect when an element enters or exits the viewport, and triggers a callback function when the element is visible.
Traditionally, identifying whether an element is visible or comparing the visibility of two elements has been difficult, often leading to unreliable methods and sluggish browser performance. With the evolution of the web, the demand for such information has grown. Intersection data is essential for several reasons, such as:
- Lazy-loading images or other content as the user scrolls.
- Creating “infinite scrolling” websites, where content continuously loads as the user scrolls, eliminating the need for pagination.
- Tracking ad visibility to calculate advertising revenue.
- Deciding whether to execute tasks or animations based on whether the user will see the outcome.
and other use cases.
The markup
- The Id
id="rotateYImage"
is used to reference the image element in the JavaScript code. On this case, the image is rotated around the Y-axis. - The Id
id="rotateXImage"
is used to reference the image element in the JavaScript code. On this case, the image is rotated around the X-axis.
<section>
<div>
<img
id="rotateYImage"
src="https://i.pinimg.com/564x/78/d1/c0/78d1c06554aead1dc1d1490f08d39ffd.jpg" />
</div>
</section>
<section>
<div>
<img
id="rotateXImage"
src="https://i.pinimg.com/564x/78/d1/c0/78d1c06554aead1dc1d1490f08d39ffd.jpg" />
</div>
</section>
The script
The event listeners
const rotateYImage = document.getElementById("rotateYImage")
: This line of code selects the element with the idrotateYImage
and assigns it to the variablerotateYImage
.const rotateXImage = document.getElementById("rotateXImage")
: This line of code selects the element with the idrotateXImage
and assigns it to the variablerotateXImage
.
const rotateYImage = document.getElementById("rotateYImage");
const rotateXImage = document.getElementById("rotateXImage");
The observer
const createObserver = (element, rotateProperty, targetDegree, step) => {
: This line of code defines a function calledcreateObserver
that takes four parameters:element
,rotateProperty
,targetDegree
, andstep
.let degree = 0;
: This line of code initializes a variable calleddegree
to 0. It will be used to keep track of the current rotation angle of the element.const observer = new IntersectionObserver((entries) => {
: This line of code creates a new instance of the IntersectionObserver class and assigns it to the variableobserver
.entries.forEach((entry) => {
: This line of code iterates over each entry in the entries array and calls a function for each entry.if (entry.isIntersecting) {
: This line of code checks if the entry is intersecting with the viewport.const interval = setInterval(() => {
: This line of code creates a new interval and assigns it to the variableinterval
.if (degree < targetDegree) {
: This line of code checks if the current rotation angle is less than the target rotation angle.degree += step;
: This line of code increments the current rotation angle by the step value.element.style.transform =
perspective(1000px) ${rotateProperty}(${degree}deg): This line of code sets the transform property of the element to
perspective(1000px) rotateY(degree)deg`.} else {
: This line of code checks if the current rotation angle is greater than or equal to the target rotation angle.clearInterval(interval);
: This line of code clears the interval and stops the rotation animation.}, 50);
: This line of code sets the interval to run every 50 milliseconds.
const createObserver = (element, rotateProperty, targetDegree, step) => {
let degree = 0;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const interval = setInterval(() => {
if (degree < targetDegree) {
degree += step;
element.style.transform = `perspective(1000px) ${rotateProperty}(${degree}deg)`;
} else {
clearInterval(interval);
}
}, 50);
}
});
});
observer.observe(element);
};
Creating the observer
createObserver(rotateYImage, "rotateY", 360, 5);
: This line of code calls thecreateObserver
function with therotateYImage
element, therotateY
property, the target rotation angle of 360 degrees, and a step value of 5.createObserver(rotateXImage, "rotateX", 30, 1);
: This line of code calls thecreateObserver
function with therotateXImage
element, therotateX
property, the target rotation angle of 30 degrees, and a step value of 1.
createObserver(rotateYImage, "rotateY", 360, 5);
createObserver(rotateXImage, "rotateX", 30, 1);
The full script
document.addEventListener("DOMContentLoaded", function () {
const rotateYImage = document.getElementById("rotateYImage");
const rotateXImage = document.getElementById("rotateXImage");
const createObserver = (element, rotateProperty, targetDegree, step) => {
let degree = 0;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const interval = setInterval(() => {
if (degree < targetDegree) {
degree += step;
element.style.transform = `perspective(1000px) ${rotateProperty}(${degree}deg)`;
} else {
clearInterval(interval);
}
}, 50);
}
});
});
observer.observe(element);
};
createObserver(rotateYImage, "rotateY", 360, 5);
createObserver(rotateXImage, "rotateX", 30, 1);
});
Conclusion
In this tutorial, we learned how to use the Intersection Observer API to animate objects in a web page. We created a simple animation when an element enters the viewport, using the Intersection Observer API with JavaScript and Tailwind CSS.
Hope you enjoyed this tutorial and have a nice day!
/Michael Andreuzza
Unlock all themes for $149 and own them forever! Includes lifetime updates, new themes, unlimited projects, and support
