1
0

feat: Header, Hero animations

This commit is contained in:
2026-02-25 17:16:02 +01:00
parent 839cf67fc7
commit f8065f06cd
6 changed files with 109 additions and 15 deletions
+26 -4
View File
@@ -1,9 +1,7 @@
---
import ArrowUpRight from "./icons/ArrowUpRight.astro";
import Logo from "../assets/ci/side-light.svg";
import Menu from "./Menu.astro";
import ArrowUpRight from "./icons/ArrowUpRight.astro";
import SkipNavLink from "./SkipNavLink.astro";
import NewMenu from "./NewMenu.astro";
---
<header>
@@ -15,7 +13,7 @@ import NewMenu from "./NewMenu.astro";
{/* Contact Link */}
<a class="contact" href="mailto:office@tideshiftdigital.com">
<span class="heading-gradient">Contact us</span>
<ArrowUpRight class="icon" />
<ArrowUpRight class="icon char" />
</a>
{/* Menu Button */}
@@ -34,6 +32,7 @@ import NewMenu from "./NewMenu.astro";
position: fixed;
top: 0;
inset-inline: 0;
z-index: 10;
}
.logo {
@@ -67,3 +66,26 @@ import NewMenu from "./NewMenu.astro";
grid-column: -1 / -2;
}*/
</style>
<script>
import { gsap } from "gsap";
import { SplitText } from "gsap/SplitText";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(SplitText);
gsap.registerPlugin(ScrollTrigger);
const header = document.querySelector("header");
if (header) {
const timeline = gsap.timeline();
timeline.from(header.children, {
duration: 1,
yPercent: -120,
opacity: 0,
stagger: 0.2,
ease: "expo.out",
});
}
</script>
-2
View File
@@ -6,9 +6,7 @@
width="51"
xmlns="http://www.w3.org/2000/svg"
height="51"
id="screenshot-8003f86b-8663-8006-8007-347270f3a7df"
viewBox="2440.5 1054.5 51 51"
style="-webkit-print-color-adjust::exact"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="none"
version="1.1"
-1
View File
@@ -7,7 +7,6 @@ const { class: classname, ...rest } = Astro.props;
width="116.333"
xmlns="http://www.w3.org/2000/svg"
height="116.333"
id="screenshot-6b8effdb-5f0e-80dd-8007-372a7199e59d"
viewBox="2743.833 5322.833 116.333 116.333"
style="-webkit-print-color-adjust::exact"
xmlns:xlink="http://www.w3.org/1999/xlink"
-2
View File
@@ -6,9 +6,7 @@ const { class: classname, ...rest } = Astro.props;
width="50"
xmlns="http://www.w3.org/2000/svg"
height="50"
id="screenshot-7dfb52c4-3c28-808c-8007-9f5d04f1d9f4"
viewBox="4464 381.207 50 50"
style="-webkit-print-color-adjust::exact"
xmlns:xlink="http://www.w3.org/1999/xlink"
fill="none"
version="1.1"
+80 -3
View File
@@ -26,9 +26,9 @@ import ArrowDown from "../icons/ArrowDown.astro";
digital sovereignty and sustainability.
</p>
<a>
<button class="down">
<ArrowDown />
</a>
</button>
</div>
</div>
@@ -62,6 +62,7 @@ import ArrowDown from "../icons/ArrowDown.astro";
grid-template-columns: subgrid;
grid-template-rows: 1fr 1fr;
row-gap: 2.25em;
z-index: 1;
grid-column: 1 / -1;
grid-row: 1;
@@ -91,7 +92,7 @@ import ArrowDown from "../icons/ArrowDown.astro";
line-height: var(--leading-paragraph);
}
a {
.down {
display: inline-flex;
grid-column: 1 / -1;
@@ -102,6 +103,9 @@ import ArrowDown from "../icons/ArrowDown.astro";
padding: 1rem;
margin-bottom: 2rem;
background-color: transparent;
border: none;
& svg {
display: inline-block;
width: 3rem;
@@ -109,3 +113,76 @@ import ArrowDown from "../icons/ArrowDown.astro";
}
}
</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 timeline = gsap.timeline().pause();
timeline.from(heroSection.querySelector(".image"), {
duration: 2,
opacity: 0,
// yPercent: 20,
ease: "expo.out",
});
timeline.from(
heroSection.querySelector(".down"),
{
duration: 1,
opacity: 0,
ease: "expo.out",
},
// ">-1",
);
new SplitText(heroSection.querySelector("h1"), {
type: "words, chars",
autoSplit: true,
mask: "chars",
charsClass: "char",
onSplit: (self) => {
timeline.from(
self.chars,
{
duration: 1,
yPercent: -120,
scale: 1.2,
stagger: 0.015,
ease: "expo.out",
},
">-2.8",
);
},
});
new SplitText(heroSection.querySelector("p"), {
type: "lines, words",
autoSplit: true,
mask: "lines",
linesClass: "line",
onSplit: (self) => {
timeline
.from(
self.lines,
{
duration: 0.9,
yPercent: 105,
stagger: 0.06,
ease: "expo.out",
},
">-1",
)
.play();
},
});
}
</script>