Skip to content

Commit 3670555

Browse files
Make footer and it's animation
1 parent 540156f commit 3670555

4 files changed

Lines changed: 186 additions & 1 deletion

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { FaBehance } from "react-icons/fa";
2+
import { FaInstagram } from "react-icons/fa";
3+
import { CiLinkedin } from "react-icons/ci";
4+
import { FaDribbble } from "react-icons/fa";
5+
6+
import MarqueeText from '../Marquee/MarqueeText';
7+
8+
const Footer = () => {
9+
return (
10+
<section className='w-screen h-dvh px-6 mt-10'>
11+
<p className='text-[.7rem] text-[#eae5dd] choose-subtitle mt-10'>Interested in an amazing adventure?<br />Reserve one of our Capsules<span>®</span></p>
12+
<div>
13+
<MarqueeText />
14+
</div>
15+
16+
<div className='flex justify-between items-center text-2xl mt-14'>
17+
<h3 className='text-[#b1a696]'>This website is just the concept<br />
18+
work done by—Moyra to showcase<br />
19+
our capabilities.<br /><br />
20+
If you would like to outsource a similar<br />
21+
website project—<a href="#" className='text-[#f4efe7] hover:text-[#c4c1b9] underline'> contact us.</a>
22+
</h3>
23+
24+
<div className='flex flex-col justify-center items-end'>
25+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Welcome</a>
26+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Introduction</a>
27+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Houses</a>
28+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Why Capsules®</a>
29+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Activites</a>
30+
<a href="#welcome" className='text-[#f2ede5] text-2xl'>Feedback</a>
31+
</div>
32+
</div>
33+
34+
<div className="w-full flex justify-between items-center mt-20">
35+
<div className="flex justify-center items-center gap-1">
36+
<div className='border-[1px] border-[#c4c1b9] rounded-full p-3 text-[#f2ede5]'><FaBehance className="text-xl" /></div>
37+
<div className='border-[1px] border-[#c4c1b9] rounded-full p-3 text-[#f2ede5]'><FaInstagram className="text-xl" /></div>
38+
<div className='border-[1px] border-[#c4c1b9] rounded-full p-3 text-[#f2ede5]'><CiLinkedin className="text-xl" /></div>
39+
<div className='border-[1px] border-[#c4c1b9] rounded-full p-3 text-[#f2ede5]'><FaDribbble className="text-xl" /></div>
40+
</div>
41+
42+
<div>
43+
<p className="text-[0.8rem] text-[#b1a696] text-right">
44+
Meet Capsules®—modern and cozy<br />
45+
houses, in the California desert.
46+
</p>
47+
</div>
48+
</div>
49+
</section>
50+
)
51+
}
52+
53+
export default Footer;
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { useGSAP } from '@gsap/react';
2+
import gsap from 'gsap';
3+
import { SplitText } from 'gsap/SplitText';
4+
import { ScrollTrigger } from 'gsap/ScrollTrigger';
5+
import React, { useRef } from 'react';
6+
7+
import "./footertitle.css";
8+
9+
gsap.registerPlugin(SplitText, ScrollTrigger);
10+
11+
const FooterTitle = () => {
12+
const ftConRef = useRef(null);
13+
14+
useGSAP(() => {
15+
if (!ftConRef.current) return;
16+
17+
// Get the original HTML before splitting
18+
const originalHTML = ftConRef.current.querySelector(".footer-title h1").innerHTML;
19+
20+
// Create split - exclude the sub element from being split
21+
const split = new SplitText(".footer-title h1", {
22+
type: "chars",
23+
charsClass: "ftChar",
24+
// Exclude the <sub> element from being split
25+
exclude: "sub"
26+
});
27+
28+
// Wrap each character in a span for animation
29+
split.chars.forEach(char => {
30+
char.innerHTML = `<span>${char.innerHTML}</span>`;
31+
});
32+
33+
const innerChars = split.chars.map(c => c.querySelector("span"));
34+
35+
// Handle the sub element separately
36+
const sub = ftConRef.current.querySelector(".footer-title sub");
37+
if (sub) {
38+
sub.innerHTML = `<span>${sub.innerHTML}</span>`;
39+
const subSpan = sub.querySelector("span");
40+
41+
// Add to innerChars array
42+
innerChars.push(subSpan);
43+
}
44+
45+
// Initial state - start from left (-120%)
46+
gsap.set(innerChars, { x: "-120%" });
47+
48+
// Animation - move to normal position
49+
gsap.to(innerChars, {
50+
x: "0%",
51+
stagger: 0.02, // Add stagger for character-by-character reveal
52+
ease: "power3.out",
53+
scrollTrigger: {
54+
trigger: ftConRef.current,
55+
start: "top 85%",
56+
end: "top 70%",
57+
scrub: true,
58+
// markers: true
59+
}
60+
});
61+
62+
// Cleanup - revert the split and restore original HTML
63+
return () => {
64+
split.revert();
65+
// Restore the original HTML with sub element
66+
ftConRef.current.querySelector(".footer-title h1").innerHTML = originalHTML;
67+
};
68+
69+
}, { scope: ftConRef });
70+
71+
return (
72+
<section ref={ftConRef} className='relative z-1 w-screen h-[50vh] border-1 border-t-[#c4c1b9]'>
73+
<div className='w-full flex justify-between items-center px-6 mt-8'>
74+
<p className='text-[#b1a696] text-[0.7rem]'>
75+
Website made by—<a href="#" className='text-[#f2ede5]'>Moyra.co</a>
76+
</p>
77+
<p className='text-[#b1a696] text-[0.7rem]'>
78+
This website is using <a href="#" className='text-[#f2ede5]'>cookies</a>
79+
</p>
80+
<p className='text-[#b1a696] text-[0.7rem]'>
81+
All rights reserved © <a href="#" className='text-[#f2ede5]'>2025</a>
82+
</p>
83+
</div>
84+
85+
<div className='footer-title w-full text-center'>
86+
<h1 className='text-[15vw] font-bold'>
87+
Capsules<sub>®</sub>
88+
</h1>
89+
</div>
90+
</section>
91+
);
92+
};
93+
94+
export default FooterTitle;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
.footer-title {
2+
position: absolute;
3+
top: 50%;
4+
left: 50%;
5+
transform: translate(-50%, -50%);
6+
width: 100%;
7+
text-align: center;
8+
z-index: 2;
9+
overflow: hidden;
10+
}
11+
12+
.footer-title h1 {
13+
position: relative;
14+
line-height: 1;
15+
color: #f4efe7;
16+
}
17+
18+
.ftChar {
19+
display: inline-block;
20+
overflow: hidden;
21+
position: relative;
22+
}
23+
24+
.ftChar>span {
25+
display: inline-block;
26+
will-change: transform;
27+
}
28+
29+
/* Specific styling for the ® symbol */
30+
.footer-title h1 sub.ftChar {
31+
font-size: 0.5em;
32+
/* Make ® smaller */
33+
vertical-align: super;
34+
bottom: 0;
35+
}

frontend/src/layouts/MainLayout.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import Preloader from "../components/Preloader/Preloader";
1010
import PreloaderII from "../components/Preloader/PreloaderII";
1111
import ReserveBtn from "../components/Buttons/ReserveBtn";
1212
import Logo from "../components/Buttons/Logo";
13+
import Footer from "../components/Footer/Footer";
14+
import FooterTitle from "../components/Footer/FooterTitle";
1315

1416
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
1517

@@ -34,7 +36,8 @@ const MainLayout = () => {
3436
<div id="smooth-content">
3537
<main>
3638
<Outlet /> {/* Hero, About, Contact, etc. */}
37-
<div className="h-dvh border-amber-600"></div>
39+
<Footer />
40+
<FooterTitle />
3841
</main>
3942
</div>
4043
</div>

0 commit comments

Comments
 (0)