Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,086 changes: 656 additions & 430 deletions features/twLandingPage/twComponents/TwJoinUsColumns.tsx

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion features/twLandingPage/twComponents/TwJoingUsEndCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { Button } from "./Button";

export const TwJoinUsEndCard: FC = () => {
return (
<div className="flex w-full flex-col items-center justify-center gap-4 rounded-sm border-2 border-neutral-700 bg-black p-8 text-white">
<div
className="flex w-full flex-col items-center justify-center gap-4 rounded-sm border-2 border-neutral-700 bg-black p-8 text-white md:opacity-0"
id="join-end-card"
>
<EELogo className="h-[100px] w-[100px]" />
<h1 className="text-center text-2xl font-bold">
We are here not only to build a working application{" "}
Expand Down
6 changes: 4 additions & 2 deletions features/twLandingPage/twComponents/TwLandingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import useLpAnimation from "../utils/useLpAnimation";
import { TwIntroduction } from "./TwIntroduction";
import { TwJoinUsTabs } from "./TwJoinUsTabs";
import TwJoinUsColumns from "./TwJoinUsColumns";
Expand All @@ -9,8 +10,9 @@ import { TwJoinUsEndCard } from "./TwJoingUsEndCard";
import { TwContact } from "./TwContact";

export const TwLandingPage = () => {
useLpAnimation();
return (
<div className="flex w-full flex-col justify-center bg-white">
<div className="flex w-full flex-col justify-center bg-white" id="gsapPin">
<style jsx>{`
.blackWhiteBgSplit {
@media (min-width: 769px) {
Expand All @@ -21,7 +23,7 @@ export const TwLandingPage = () => {
<TwIntroduction />
<TwJoinUsTabs />
<div className="blackWhiteBgSplit flex w-full justify-center">
<div className="flex max-w-[1440px] flex-grow">
<div id="gsapContainer" className="flex max-w-[1440px] flex-grow">
<TwJoinUsColumns />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion features/twLandingPage/twComponents/TwOurProducts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ProductNames } from "./referenceData";

export const TwOurProducts: FC = () => {
return (
<div className="mb-4 flex h-full w-full max-w-[1440px] flex-col items-center justify-center gap-12 self-center bg-white px-2 py-12 lg:gap-16 lg:px-2 lg:py-16">
<div className="mb-4 flex w-full max-w-[1440px] flex-col items-center justify-center gap-12 self-center bg-white px-2 py-12 lg:gap-16 lg:px-2 lg:py-16">
<div className="flex w-full items-center justify-center whitespace-nowrap text-4.5xl font-bold uppercase lg:justify-start lg:text-7.5xl">
Our Products
</div>
Expand Down
4 changes: 2 additions & 2 deletions features/twLandingPage/twComponents/TwOurServices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const TwOurServices: FC = () => {
return (
<div
id="our-services-section"
className="flex w-full max-w-[1440px] flex-col items-center justify-center gap-12 self-center px-2 py-12 font-bold text-black lg:gap-16 lg:px-2 lg:py-16"
className="flex w-full max-w-[1440px] flex-col items-center justify-center gap-12 self-center px-2 pb-12 pt-0 font-bold text-black lg:gap-16 lg:px-2 lg:pb-16"
>
<div className="flex min-h-full justify-center text-4.5xl lg:self-start lg:text-7.5xl">
<div className="flex justify-center text-4.5xl lg:self-start lg:text-7.5xl">
OUR SERVICES
</div>
<div className="grid w-full gap-4 sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
Expand Down
12 changes: 12 additions & 0 deletions features/twLandingPage/utils/calcScrollAnimationOffset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const calcScrollAnimationOffset = (
descHeight: number,
illustrationHeight: number,
) => {
if (descHeight + illustrationHeight <= window.innerHeight) {
return 0;
}

return (
window.innerHeight - descHeight - (descHeight + illustrationHeight) * 0.3
);
};
232 changes: 232 additions & 0 deletions features/twLandingPage/utils/useLpAnimation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import { useEffect } from "react";
import { gsap } from "gsap";
import { calcScrollAnimationOffset } from "./calcScrollAnimationOffset";

const COLUMN_SCROLL_SPEED = 6;

const useGsapAnimation = () => {
useEffect(() => {
import("gsap/ScrollTrigger").then((module) => {
const ScrollTrigger = module.ScrollTrigger;
gsap.registerPlugin(ScrollTrigger);

const mm = gsap.matchMedia();

mm.add(
{
isDesktop: "(min-width: 769px)",
},
(context) => {
const isDesktop = context?.conditions?.isDesktop;
if (!isDesktop) return;

const section1Timeline = gsap
.timeline({ defaults: { duration: 1 } })
.to("#sec-1-intro", { opacity: 1 })
.to("#sec-1-arrow", { opacity: 1, delay: 1.5 })
.to("#sec-1-illustration", { opacity: 1, delay: 1.5 })
.to("#sec-1-description", { opacity: 1, delay: 1.5 })
.to(["#sec-1-description", "#sec-1-illustration", "#sec-1-arrow"], {
y: () =>
calcScrollAnimationOffset(
document.querySelector("#sec-1-description")?.clientHeight ||
0,
document.querySelector("#sec-1-illustration")?.clientHeight ||
0,
),
duration: COLUMN_SCROLL_SPEED,
});

const section2Timeline = gsap
.timeline({ defaults: { duration: 1 } })
.to("#section-2", { opacity: 1, delay: 0.5 })
.to("#sec-2-intro", { opacity: 1, delay: 1.5 })
.to("#sec-2-arrow", { opacity: 1, delay: 1.5 })
.to("#sec-2-illustration", { opacity: 1, delay: 1.5 })
.to("#sec-2-description", { opacity: 1, delay: 1.5 })
.to(["#sec-2-description", "#sec-2-illustration", "#sec-2-arrow"], {
y: () =>
calcScrollAnimationOffset(
document.querySelector("#sec-2-description")?.clientHeight ||
0,
document.querySelector("#sec-2-illustration")?.clientHeight ||
0,
),
duration: COLUMN_SCROLL_SPEED,
});

const section3Timeline = gsap
.timeline({ defaults: { duration: 1 } })
.to("#section-3", { opacity: 1, delay: 0.5 })
.to("#sec-3-intro", { opacity: 1, delay: 1.5 })
.to("#sec-3-arrow", { opacity: 1, delay: 1.5 })
.to("#sec-3-illustration", { opacity: 1, delay: 1.5 })
.to("#sec-3-description", { opacity: 1, delay: 1.5 })
.to("#sec-3-desc-1", { opacity: 1, delay: 1.5 })
.to("#sec-3-desc-2", { opacity: 1, delay: 1.5 })
.to("#sec-3-desc-3", { opacity: 1, delay: 1.5 })

.to(["#sec-3-description", "#sec-3-illustration", "#sec-3-arrow"], {
y: () =>
calcScrollAnimationOffset(
document.querySelector("#sec-3-description")?.clientHeight ||
0,
document.querySelector("#sec-3-illustration")?.clientHeight ||
0,
),
duration: COLUMN_SCROLL_SPEED,
});

const section4Timeline = gsap
.timeline({ defaults: { duration: 1 } })
.to("#section-4", { opacity: 1, delay: 0.5 })
.to("#sec-4-intro", { opacity: 1, delay: 0.5 })
.to("#sec-4-arrow", { opacity: 1, delay: 1.5 })
.to("#sec-4-illustration", { opacity: 1, delay: 1.5 })
.to("#join_us_root", { height: "60vh" }, "<")
.to(["#sec-4-description", "#join-end-card"], {
opacity: 1,
duration: 1,
})
.to(["#sec-4-description", "#sec-4-illustration", "#sec-4-arrow"], {
y: () =>
calcScrollAnimationOffset(
document.querySelector("#sec-4-description")?.clientHeight ||
0,
document.querySelector("#sec-4-illustration")?.clientHeight ||
0,
),
duration: COLUMN_SCROLL_SPEED,
});

const desktopTimeline = gsap
.timeline({
scrollTrigger: {
trigger: "#gsapContainer",
start: "top center",
end: "+=2500",
scrub: 1,
markers: false,
},
defaults: { duration: 1 },
})
.to("#section-1", { opacity: 1, delay: 5 })
.add(section1Timeline)
.to(["#section-1", "#sec-1-arrow"], { opacity: 0, delay: 0.5 })
.add(section2Timeline)
.to(["#section-2", "#sec-2-arrow"], { opacity: 0, delay: 0.5 })
.add(section3Timeline)
.to(["#section-3", "#sec-3-arrow"], { opacity: 0, delay: 0.5 })
.add(section4Timeline);

ScrollTrigger.create({
trigger: "#gsapContainer",
start: "top top",
end: "+=2000",
pin: "#gsapPin",
pinSpacing: false,
scrub: 1,
markers: false,
});

return () => {
desktopTimeline.kill();
};
},
);

// Mobile animations
mm.add(
{
isMobile: "(max-width: 768px)",
},
() => {
const mobileTimeline = gsap.timeline({
scrollTrigger: {
trigger: "#gsapContainer",
start: "top top",
end: "+=2000",
scrub: 1,
markers: false,
},
});
ScrollTrigger.create({
trigger: "#section-2",
start: "top 20%",
onEnter: () => {
gsap.to("#m-label-1", { opacity: 0, duration: 0.5 });
gsap.to("#m-label-2", { opacity: 1, duration: 0.5 });
},
onLeaveBack: () => {
gsap.to("#m-label-1", { opacity: 1, duration: 0.5 });
gsap.to("#m-label-2", { opacity: 0, duration: 0.5 });
},
scrub: true,
markers: false,
invalidateOnRefresh: true, // Ensures recalculation on refresh
});

ScrollTrigger.create({
trigger: "#section-3",
start: "top 20%", // Start the trigger when #section-3 hits the center of the viewport
onEnter: () => {
gsap.to("#m-label-2", { opacity: 0, duration: 0.5 });
gsap.to("#m-label-3", { opacity: 1, duration: 0.5 });
},
onLeaveBack: () => {
gsap.to("#m-label-2", { opacity: 1, duration: 0.5 });
gsap.to("#m-label-3", { opacity: 0, duration: 0.5 });
},
scrub: true,
markers: false,
immediateRender: false,
invalidateOnRefresh: true, // Ensures recalculation on refresh
});

ScrollTrigger.create({
trigger: "#section-4",
start: "top center",
onEnter: () => {
gsap.to("#m-label-3", { opacity: 0, duration: 0.5 });
gsap.to("#m-label-4", { opacity: 1, duration: 0.5 });
},
onLeaveBack: () => {
gsap.to("#m-label-3", { opacity: 1, duration: 0.5 });
gsap.to("#m-label-4", { opacity: 0, duration: 0.5 });
},
scrub: true,
markers: false,
immediateRender: false,
invalidateOnRefresh: true, // Ensures recalculation on refresh
});

ScrollTrigger.create({
trigger: "#section-labels",
start: "top top",
end: () => {
const section4 = document.querySelector("#sec-4-illustration");

return section4
? section4.getBoundingClientRect().top - 120
: "top top";
},
pin: "#section-labels",
pinSpacing: false,
scrub: true,
markers: false,
invalidateOnRefresh: true, // Ensures recalculation on refresh
});
ScrollTrigger.refresh();
return () => {
mobileTimeline.kill();
};
},
);

return () => {
mm.kill();
};
});
}, []);
};
export default useGsapAnimation;
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"css-loader": "^7.1.2",
"form-data": "^4.0.0",
"framer-motion": "^11.3.31",
"gsap": "^3.12.5",
"lexical": "^0.11.3",
"link-preview-js": "^3.0.4",
"next": "^14.2.7",
Expand Down
2 changes: 1 addition & 1 deletion pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FunctionComponent } from "react";
import { TwLandingPage } from "../features/twLandingPage/twComponents/TwLandingPage";
import { TwLayout } from "../features/twLandingPage/twComponents/TwLayout";
import { LPSEO } from "../features/blog/components/LPSEO";
import { TwLayout } from "../features/twLandingPage/twComponents/TwLayout";

const Index: FunctionComponent = () => {
return (
Expand Down
Binary file added public/illustrations/Illustration_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/illustrations/Illustration_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/illustrations/Illustration_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/illustrations/Product_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ module.exports = {
"linear-gradient(270deg, #FE3301 0%, #FD7503 50%, #FF1B00 100%)",
"letter-background":
"linear-gradient(to right, rgba(255, 214, 68, 1), rgba(253, 117, 3, 1), rgba(255, 27, 0, 1))",
"gradient-under-labels":
"linear-gradient(180deg, #0E0C0C 0%, rgba(14, 12, 12, 0) 100%)",
},
colors: {
"letter-red": "rgba(255, 27, 0, 1)", // You can name this color anything you like
Expand Down Expand Up @@ -97,5 +99,19 @@ module.exports = {
};
addUtilities(newUtilities);
},
function ({ addUtilities }) {
addUtilities({
".gradient-under::after": {
content: '""',
position: "absolute",
left: "0",
bottom: "-72px",
width: "100%",
height: "72px",
backgroundImage:
"linear-gradient(180deg, #0E0C0C 0%, rgba(14, 12, 12, 0) 100%)",
},
});
},
],
};