How to create a floating animation with GSAP

breakdance_illustration
😜
BREAK
DANCE

Why using GSAP instead of a basic CSS animation?
It's easier to manage, there are more options and the best of all : The animations will only run when they are visible in the viewport.

Creating a loop animation is pretty simple with GSAP, and I have already explained the method in this tutorial: How to create looping animations with GSAP.

Instead of creating a different animation (and having different code) for each element we want to animate, I have created a global code, that works with the data-attributes. Which means that we paste the code once, and we can animate any element in the page, with their own settings.

For example, the word "BREAK" that is animated at the top of this page, has a special attribute:

gsap-floating-attribute

With this method, we can easily animate any element, by adding the data attribute data-gsap-floating.
Then for the value, in JSON format, we can set an horizontal or/and a vertical distance, and a different speed for both, in that format:

{"x":"50","y":"50","speedx":"1.5","speedy":"2.5"}

For the emoji that is moving vertically only, I used this value :

gsap-floating-vertical-animation
{"y":"-20","speedy":".8"}

Here is the full Javascript code that you can paste in your page. Don't forget that you need GSAP, so check this tutorial to learn how to use GSAP with Breakdance.

const floatingobjs = document.querySelectorAll('[data-gsap-floating]');

floatingobjs.forEach((element) => {

const json = element.dataset.gsapFloating;
const data = JSON.parse(json ?? '{}');
const xpos = data.x ?? 0;
const ypos = data.y ?? 0;
const speedx = data.speedx ?? 1; // default horizontal duration
const speedy = data.speedy ?? 1; // default vertical duration

const floatingtm = gsap.timeline({
defaults: {
ease: 'sine.inOut',
repeat: -1,
yoyo: true,
},
scrollTrigger: {
trigger: element,
start: "top bottom",
toggleActions: "play pause resume reset"
}
});

floatingtm.fromTo(element,{ x: -xpos/2 }, {
x: xpos/2,
duration: speedx
}, 0)
.fromTo(element, { y: -ypos/2 }, {
y: ypos/2,
duration: speedy,
}, 0);

})

Here is how it looks like in the backend of my page, when using the GSAP Block element:

gsap-floating-code