gsap-react animation

GSAP animation : Landing page animation in GSAP and Reactjs

GSAP animation in Reactjs : GSAP is an industry standard JavaScript animation library from GreenSock that lets you craft high-performance animations that work in every major browser.

Animation Preview Link

Please Like and subscribe for more animation – Youtube video

Lets, Create a ReactJS project and install gsap :
  • You can create a new ReactJS project using Create React App or any other preferred method. If you haven’t installed Create React App globally, you can do so with the following command: npm install -g create-react-app
  • Then create a new React project:  npx create-react-app my-gsap-project
  • go to project folder :  cd my-gsap-project
  • Next, you need to install GSAP package. You can do this via npm or yarn: npm install gsap or yarn add gsap
Here are some basic steps to follow when creating animation in GSAP, Reactjs:
  1. Register the scrollTrigger plugin to trigger elements on scroll.

  2. Create React Hooks and write GSAP code inside them.

  3. Utilize gsap.context() to collect all animations(GSAP) and ScrollTriggers created within the supplied function, allowing for easy reverting or killing of ALL of them at once.

  4. Develop timelines and scrollTriggers based on your specific requirements.

Logic of animation in GSAP with Reactjs
				
					useEffect(() => {
		gsap.registerPlugin(ScrollTrigger);

		const target = document.querySelectorAll("#target");
		Splitting({ target: target, by: 'chars' });
		const charForSplit = document.querySelectorAll(".char");
		gsap.timeline().from(charForSplit, { duration: 1, opacity: 0, stagger: 0.06, ease: "back.out" });
		var tl = gsap.timeline({
			scrollTrigger: {
				trigger: ".p-hero-desc",
				start: "0% 95%",
				end: "70% 50%",
				scrub: 1,
			}
		})

		tl.to("#p-hero-img", {
			top: "55%",
			left: "0%"
		})
		const targetCall = document.querySelector('.p-gallery-desc');
		const results = Splitting({ target: targetCall, by: 'lines' });

		results[0].lines.forEach((line, index) => {
			line.forEach((word) => {
				gsap.from(word, {
					scrollTrigger: {
						trigger: ".p-gallery-desc",
						toggleActions: "restart none none none",

					}, opacity: 0, delay: index / 4
				});
			})
		});
	}, [])
				
			
				
					<div>
			<div id="main">
				<div className="p-img-wrap">
					<img id="p-hero-img" src={require("../assets/h1.png")} alt="" />
				</div>
				<div className="p-hero">
					<h1 className="p-hero-title main-title" id="target" data-splitting><p className="p-hero-parallax">WE BELIEVE IN HAMMER</p>
						<span className="p-hero-stroke">SMOOTH EXPERIENCE
						</span></h1>
					<div className="p-hero-sub-title" id="target" data-splitting>BE CLASSIC,<span className="p-hero-stroke"> BE PROFESSIONAL</span></div>
				</div>
				<div className="p-hero-desc">
					<div className="p-hero-desc-left">

					</div>
					<div className="p-hero-desc-right">
						<h2 className="p-hero-title left">about<span className="p-hero-stroke">-us</span>
						</h2>
						<p className="p-gallery-desc">
							Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores cumque voluptas nihil! Consectetur, ea. Ratione nam odio mollitia. Mollitia impedit rerum autem quaerat ex fugiat assumenda quam nesciunt recusandae beatae.
						</p>
					</div>
				</div>
			</div>
</div>
				
			
CSS
				
					:root {
	--pr-color: #fff;
	--second-color: #0a0a0a;
	--cubicbz: cubic-bezier(.9, 0, .1, 1);
	--fz-big: 60px;
}

* {
	box-sizing: border-box;
	font-family: 'Syne', sans-serif;
	font-weight: 800;
	margin: 0;
	padding: 0;
	font-feature-settings: 'pnum' on, 'lnum' on;
}
#main{
	position: relative;
}
.p-hero{
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100vh;
	position: relative;
}

#p-hero-img{
    position: absolute;
    width: 800px;
    z-index: 0;
	height:800px;
	top:3%;
    transition: all cubic-bezier(0.19, 1, 0.22, 1)0.5s;
}

.p-hero-title {
	position: relative;
	margin: 0;
	margin-bottom: 60px;
	line-height: .8;
	font-size: 70px;
	z-index: 1;
	text-align: center;
	color: #fff;
	text-transform: uppercase;
}

.p-hero-title.left{
	text-align: left;
}

.p-hero-sub-title{
	position: relative;
	margin: 0;
	margin-bottom: 0px;
	line-height: .8;
	font-size: 40px;
	z-index: 1;
	color: #fff;
	text-transform: uppercase;
	position: absolute;
	bottom:20px;
	right:20px;
}

.p-hero-stroke {
	color: transparent;
	-webkit-text-stroke: 1px #fff;
	z-index: 1;
}

.p-gallery-desc {
	line-height: 1.4;
	letter-spacing: 1px;
	font-size: 20px;
	color: #ccc;
	z-index: 1;
}

.p-hero-parallax {
	display: inline-block;
	will-change: transform;
	z-index: 1;
}

.p-hero-desc{
	padding-right: 20px;
    width: 100%;
	display: flex;
	z-index: 1;
	align-items: center;
	height:100vh;
	justify-content: space-between;
}

.p-hero-desc-left, .p-hero-desc-right{
    display: flex;
	flex-direction: column;
	justify-content: center;
    width: 50%;
    height: 100%;
}
@media(max-width:1440px){
	.p-hero-desc-right{
		width: 40%;
	}
	.p-hero-title{
		font-size: 50px;
	}
	.main-title{
		font-size: 65px;
	}
}

.p-hero-items{
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5vw;
    width: 100%;
    height: 100vh;
}

.p-img-wrap{
	display: flex;
	justify-content: center;
}
				
			
Full Component file
				
					import { useEffect } from "react";
import "./Product.css";
import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";
import Splitting from "splitting";

const Product = () => {

	useEffect(() => {
		gsap.registerPlugin(ScrollTrigger);

		const target = document.querySelectorAll("#target");
		Splitting({ target: target, by: 'chars' });
		const charForSplit = document.querySelectorAll(".char");
		gsap.timeline().from(charForSplit, { duration: 1, opacity: 0, stagger: 0.06, ease: "back.out" });
		var tl = gsap.timeline({
			scrollTrigger: {
				trigger: ".p-hero-desc",
				start: "0% 95%",
				end: "70% 50%",
				scrub: 1,
			}
		})

		tl.to("#p-hero-img", {
			top: "55%",
			left: "0%"
		})
		const targetCall = document.querySelector('.p-gallery-desc');
		const results = Splitting({ target: targetCall, by: 'lines' });

		results[0].lines.forEach((line, index) => {
			line.forEach((word) => {
				gsap.from(word, {
					scrollTrigger: {
						trigger: ".p-gallery-desc",
						toggleActions: "restart none none none",

					}, opacity: 0, delay: index / 4
				});
			})
		});
	}, [])
	return (
		<div>
			<div id="main">
				<div className="p-img-wrap">
					<img id="p-hero-img" src={require("../assets/h1.png")} alt="" />
				</div>
				<div className="p-hero">
					<h1 className="p-hero-title main-title" id="target" data-splitting><p className="p-hero-parallax">WE BELIEVE IN HAMMER</p>
						<span className="p-hero-stroke">SMOOTH EXPERIENCE
						</span></h1>
					<div className="p-hero-sub-title" id="target" data-splitting>BE CLASSIC,<span className="p-hero-stroke"> BE PROFESSIONAL</span></div>
				</div>
				<div className="p-hero-desc">
					<div className="p-hero-desc-left">

					</div>
					<div className="p-hero-desc-right">
						<h2 className="p-hero-title left">about<span className="p-hero-stroke">-us</span>
						</h2>
						<p className="p-gallery-desc">
							Lorem ipsum dolor sit amet consectetur adipisicing elit. Asperiores cumque voluptas nihil! Consectetur, ea. Ratione nam odio mollitia. Mollitia impedit rerum autem quaerat ex fugiat assumenda quam nesciunt recusandae beatae.
						</p>
					</div>
				</div>
			</div>
        </div>
	)
}
export default Product;
				
			
Scroll to Top