1
0
Files
tideshift-website/src/components/landing/HeroSection.astro
T

203 lines
4.1 KiB
Plaintext

---
import Picture from "astro/components/Picture.astro";
import HeroImage from "../../assets/img/hero.jpg";
import ArrowDown from "../icons/ArrowDown.astro";
---
<div class="hero" aria-label="Hero section">
<div class="image-wrapper">
<Picture
class="image"
src={HeroImage}
formats={["jpg", "jpeg", "webp"]}
alt="todo"
/>
</div>
<div class="content">
<h1 class="heading-gradient">
<span>Your Partner </span>
<span>For A Better Web</span>
</h1>
<p>
From concept to launch - websites, apps, and digital solutions that work
hard, so you can play hard. We create long-term success by focusing on
digital sovereignty and sustainability.
</p>
<button class="down">
<ArrowDown />
</button>
</div>
</div>
<style>
.hero {
display: grid;
grid-template-columns: var(--base-grid);
height: 100svh;
padding-inline: 5rem;
max-width: var(--max-content-width);
margin-inline: auto;
}
.image-wrapper {
grid-column: -1 / -6;
grid-row: 1;
/* width: 100%; */
max-height: clamp(400px, 70vh, 1000px);
}
.image {
display: inline-block;
max-width: 100%;
max-height: 100%;
object-fit: cover;
object-position: bottom;
}
.content {
display: grid;
grid-template-columns: subgrid;
grid-template-rows: 1fr 1fr;
row-gap: 2.25em;
z-index: 1;
grid-column: 1 / -1;
grid-row: 1;
}
h1 {
grid-column: 2 / -2;
grid-row: 1;
align-self: end;
font-size: var(--fs-page-title);
line-height: var(--leading-title);
letter-spacing: var(--tracking-narrow);
font-weight: 600;
& span {
display: block;
}
}
p {
grid-column: 3 / -5;
grid-row: 2;
max-width: 45ch;
font-size: var(--fs-md);
line-height: var(--leading-paragraph);
}
.down {
display: inline-flex;
grid-column: 1 / -1;
grid-row: 1 / 3;
justify-self: center;
align-self: end;
padding: 1rem;
margin-bottom: 2rem;
background-color: transparent;
border: none;
& svg {
display: inline-block;
width: 3rem;
height: 3rem;
}
}
</style>
<script>
import { gsap } from "gsap";
import { SplitText } from "gsap/SplitText";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(SplitText);
gsap.registerPlugin(ScrollTrigger);
const heroSection = document.querySelector(".hero");
if (heroSection) {
const mm = gsap.matchMedia();
mm.add("(prefers-reduced-motion: no-preference)", () => {
const tl = gsap.timeline().pause();
tl.addLabel("heading", 0);
tl.addLabel("image", 0.2);
tl.addLabel("text", 0.8);
tl.addLabel("arrow", 1.5);
tl.from(
heroSection.querySelector(".image"),
{
duration: 2,
opacity: 0,
xPercent: 10,
ease: "expo.out",
},
"image",
);
new SplitText(heroSection.querySelector("h1"), {
type: "words, chars",
autoSplit: true,
mask: "chars",
charsClass: "char",
onSplit: (self) => {
tl.from(
self.chars,
{
duration: 1,
yPercent: -120,
scale: 1.2,
stagger: 0.015,
ease: "expo.out",
onComplete: () => self.revert(),
},
"heading",
);
},
});
new SplitText(heroSection.querySelector("p"), {
type: "lines, words",
autoSplit: true,
mask: "lines",
linesClass: "line",
onSplit: (self) => {
tl.from(
self.lines,
{
duration: 0.9,
yPercent: 105,
stagger: 0.06,
ease: "expo.out",
onComplete: () => self.revert(),
},
"text",
).play();
},
});
tl.from(
heroSection.querySelector(".down"),
{
duration: 1,
opacity: 0,
translateY: "-100%",
ease: "bounce.out",
},
"arrow",
);
});
}
</script>