Making a Show-Stopping Website Animation

How we made the Inheaden Website Homepage Svg Animation that works with the scroller

Victor Umesiobi
Inheaden
4 min readNov 23, 2022

--

Inheaden Homepage (https://inheaden.io/)

The Inheaden Team recently released version 2 of its website and one of the features that attracts people the most is the homepage animation. They seem amused by the rocket and how it moves further as they scroll through. This article will discuss how it was done.

Prerequisite:

Now, let’s dive right into making it.

First, create a component with the SVG assets as demonstrated in the snippet code.

<body>
...
<h1>
<span>Your Preferred Title</span>
</h1>
...
<div>
<svg viewBox="0 0 1440 980" fill="none">
<rect width="1440" height="980" fill="#0093E5" />
<circle cx="1085" cy="695" r="207" fill="url(#paint0_linear_3790_188105)" />
<path d="M102.897 543.506L-0.502075 599.128V836L1440 838.557V613.513C1383.54 566.601 1401 646 1225.5 671.5C1186.55 648.198 1058 615.665 999.501 631C896.501 658 693.254 671.5 659.501 671.5C619.223 671.5 521.304 610.636 497.859 613.513C474.414 616.39 419.107 606.8 389.049 591.456C358.991 576.112 285.049 508.982 265.21 508.023C245.372 507.064 167.221 535.834 149.187 543.506C134.759 549.644 112.316 546.064 102.897 543.506Z"fill="url(#paint1_linear_3790_188105)"/>
...
</svg>
</div>
...
</body>

Next, make sure you look through your SVG and group each section. For instance, the rocket comprised different paths, but we had to add all its paths to a single group as seen below.



...
<g ref={rocket}>
<g filter="url(#filter0_f_3790_188105)">
<path d="M1173.59 629.521C1172.91 593.502 1170.01 372.829 1168.65 266.995L1160.53 267.038C1160.41 368.74 1160.29 584.011 1160.05 629.593C1159.81 675.398 1174.43 674.544 1173.59 629.521Z" fill="url(#paint4_linear_3790_188105)" />
</g>
<g filter="url(#filter1_f_3790_188105)">
<path d="M1170.52 508.686C1170.09 484.673 1168.2 337.558 1167.31 267.002L1162.09 267.029C1162.03 334.83 1161.98 478.344 1161.83 508.732C1161.69 539.269 1171.07 538.701 1170.52 508.686Z" fill="url(#paint5_linear_3790_188105)" />
</g>
</g>
...

After grouping these sections, create a ref for the section you would like to animate.

const cloud1 = useRef<HTMLDivElement>(null);
const rocket = useRef<HTMLDivElement>(null);


...
<g ref={rocket}>
...
</g>

<g ref={cloud1}>
...
</g>
...
Your result should be static and well placed as this image.

At this point, it's time to add the control for the website scroll bar. To do this, we used the tool locomotive-scroll and it was done as shown in the snippet below.

    useEffect(() => {
let locoScroll: any;

import('locomotive-scroll').then((locomotiveModule) => {
locoScroll = new locomotiveModule.default({
el: parentRef.current as any,
smooth: true,
multiplier: 1,
});
locoScroll.on('scroll', ScrollTrigger.update);
ScrollTrigger.normalizeScroll(true);
ScrollTrigger.scrollerProxy(parentRef.current as any, {
scrollTop(value) {
return arguments.length
? (locoScroll as any).scrollTo(value, 0, 0)
: (locoScroll as any).scroll.instance.scroll.y;
},
pinType: parentRef.current.style.transform ? 'transform' : 'fixed',
});

//TODO: Add Animation

ScrollTrigger.addEventListener('refresh', () => {
if (locoScroll) {
locoScroll?.update();
}
});
ScrollTrigger.refresh();
});

return () => {
if (locoScroll) {
ScrollTrigger.removeEventListener('refresh', locoScroll.update);
if (locoScroll.destroy) {
locoScroll.destroy();
}
}
};
}, []);

For the parentRef create a variable const parentRef = useRef<HTMLDivElement>(null); and include it in the parent div or element or body of the web page you expect the scroll animation to work on <body ref={parentRef}>....</body>

Now, you want to create your animations, and to do this, we used the tool gsap . You can put your animations in a function and try the expected result in a useEffect hook to get the best result before using it later.

 const loadAnimation = (tl, mountain1, mountain2, sun, cloud, rocket) => {
const option = {
translateY: 0,
ease: Power3.easeOut,
duration: 1,
opacity: 1,
}

tl.fromTo(mountain1, { translateY: 100, opacity: 0 }, option);
tl.fromTo(mountain2,{ translateY: 200, opacity: 0 },{ ...option, duration: 1.4 });
tl.fromTo(rocket, { translateY: 200, opacity: 0 }, { ...option, duration: 1.4 });
tl.fromTo(cloud, { translateX: 200, opacity: 0 }, option);
}


useEffect(() => {
loadAnimation(TweenMax, mountain1.current, mountain2.current, sun.current, cloud.current, rocket.current)
}, [])

You can adjust the animations depending on your SVG groups, and what you want to animate.

After you’re ok with your result, now call the loadAnimation function with the scroll update instead of using it in a useEffectdemonstrated below. Replace this line //TODO: Add Animation with the snippet below.

 var tl = gsap.timeline({
scrollTrigger: {
trigger: scrollElementRef.current,
scroller: parentRef.current,
scrub: true,
pin: true,
pinSpacing: false,
start: 'top top',
end: '+=100%',
},
});

loadAnimation(
tl,
mountain1.current,
mountain2.current,
sun.current,
cloud.current,
rocket.current
);

For the scrollElementRef, you want to create a variable as you’ve previously created for the parentRef and include it in the element that is a direct parent to the SVG assets.

Results

Finally, you should see your animation play as you scroll through your web. In scenarios where you want to disable the animation based on different screen sizes, you should add this line and modify it as you please.

 const conditions = {
isMobile: '(max-width: 500px)',
isDesktop: '(min-width: 501px)',
prefersReducedMotion: '(prefers-reduced-motion: reduce)',
};

const gm = gsap.matchMedia();
let locoScroll: any;
gm.add(conditions, (context) => {
if ((context.conditions as any).isDesktop) {
import('locomotive-scroll').then((locomotiveModule) => {
...
}
}
}

Please, do check out our own results by visiting here 👉🏻 Inheaden Team and leave a like if this article helped you!

Thank you for reading!

Found this post useful? Kindly hit the 👏 button below to show how much you liked this post!

We are a fast-growing tech startup headquartered in Darmstadt, Germany. Incepted in 2017 by 4 co-founders, we now have a team of 20+ experts in Information Technology (IT) and Digital Product creation. As Europe’s first Tech Angel, Inheaden supports startups or small businesses by providing them with the tech strategy, assets, and maintenance they need to thrive in today’s digital era.

--

--