feat: implement prefers reduced motion for anims
This commit is contained in:
+15
-10
@@ -148,15 +148,20 @@ function getCurrentYear() {
|
|||||||
const footer = document.querySelector("footer");
|
const footer = document.querySelector("footer");
|
||||||
|
|
||||||
if (footer) {
|
if (footer) {
|
||||||
gsap.from(footer, {
|
const mm = gsap.matchMedia();
|
||||||
scrollTrigger: {
|
|
||||||
trigger: footer,
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
start: "top bottom",
|
gsap.from(footer, {
|
||||||
},
|
scrollTrigger: {
|
||||||
duration: 2,
|
trigger: footer,
|
||||||
opacity: 0,
|
start: "top bottom",
|
||||||
yPercent: 10,
|
},
|
||||||
ease: "expo.out",
|
duration: 2,
|
||||||
|
opacity: 0,
|
||||||
|
yPercent: 10,
|
||||||
|
// yPercent: 10,
|
||||||
|
ease: "expo.out",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -82,14 +82,18 @@ import SkipNavLink from "./SkipNavLink.astro";
|
|||||||
const header = document.querySelector("header");
|
const header = document.querySelector("header");
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
const tl = gsap.timeline();
|
const mm = gsap.matchMedia();
|
||||||
|
|
||||||
tl.from(header.children, {
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
duration: 1,
|
const tl = gsap.timeline();
|
||||||
yPercent: -120,
|
|
||||||
opacity: 0,
|
tl.from(header.children, {
|
||||||
stagger: 0.2,
|
duration: 1,
|
||||||
ease: "expo.out",
|
yPercent: -120,
|
||||||
|
opacity: 0,
|
||||||
|
stagger: 0.2,
|
||||||
|
ease: "expo.out",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -122,87 +122,91 @@ import { Picture } from "astro:assets";
|
|||||||
const aboutSection = document.querySelector(".about");
|
const aboutSection = document.querySelector(".about");
|
||||||
|
|
||||||
if (aboutSection) {
|
if (aboutSection) {
|
||||||
const tl = gsap.timeline({
|
const mm = gsap.matchMedia();
|
||||||
scrollTrigger: {
|
|
||||||
trigger: aboutSection,
|
|
||||||
start: "top 70%",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
tl.addLabel("heading", 0);
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
tl.addLabel("heading-text", 0.6);
|
const tl = gsap.timeline({
|
||||||
tl.addLabel("image", 0.8);
|
scrollTrigger: {
|
||||||
tl.addLabel("image-text", 1.1);
|
trigger: aboutSection,
|
||||||
|
start: "top 70%",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
new SplitText(aboutSection.querySelector("h2"), {
|
tl.addLabel("heading", 0);
|
||||||
type: "words, chars",
|
tl.addLabel("heading-text", 0.6);
|
||||||
autoSplit: true,
|
tl.addLabel("image", 0.8);
|
||||||
mask: "chars",
|
tl.addLabel("image-text", 1.1);
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
|
||||||
tl.from(
|
|
||||||
self.chars,
|
|
||||||
{
|
|
||||||
duration: 0.9,
|
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
},
|
|
||||||
"heading",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
new SplitText(aboutSection.querySelectorAll(".heading p"), {
|
new SplitText(aboutSection.querySelector("h2"), {
|
||||||
type: "lines, words",
|
type: "words, chars",
|
||||||
autoSplit: true,
|
autoSplit: true,
|
||||||
mask: "lines",
|
mask: "chars",
|
||||||
linesClass: "line",
|
charsClass: "char",
|
||||||
onSplit: (self) => {
|
onSplit: (self) => {
|
||||||
tl.from(
|
tl.from(
|
||||||
self.lines,
|
self.chars,
|
||||||
{
|
{
|
||||||
duration: 0.9,
|
duration: 0.9,
|
||||||
yPercent: 105,
|
yPercent: -120,
|
||||||
stagger: 0.06,
|
scale: 1.2,
|
||||||
ease: "expo.out",
|
stagger: 0.015,
|
||||||
onComplete: () => self.revert(),
|
ease: "expo.out",
|
||||||
},
|
onComplete: () => self.revert(),
|
||||||
"heading-text",
|
},
|
||||||
);
|
"heading",
|
||||||
},
|
);
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
tl.from(
|
new SplitText(aboutSection.querySelectorAll(".heading p"), {
|
||||||
aboutSection.querySelector(".background"),
|
type: "lines, words",
|
||||||
{
|
autoSplit: true,
|
||||||
duration: 2,
|
mask: "lines",
|
||||||
opacity: 0,
|
linesClass: "line",
|
||||||
ease: "expo.out",
|
onSplit: (self) => {
|
||||||
},
|
tl.from(
|
||||||
"image",
|
self.lines,
|
||||||
);
|
{
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: 105,
|
||||||
|
stagger: 0.06,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"heading-text",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
new SplitText(aboutSection.querySelectorAll(".image > p"), {
|
tl.from(
|
||||||
type: "lines, words",
|
aboutSection.querySelector(".background"),
|
||||||
autoSplit: true,
|
{
|
||||||
mask: "lines",
|
duration: 2,
|
||||||
linesClass: "line",
|
opacity: 0,
|
||||||
onSplit: (self) => {
|
ease: "expo.out",
|
||||||
tl.from(
|
},
|
||||||
self.lines,
|
"image",
|
||||||
{
|
);
|
||||||
duration: 0.9,
|
|
||||||
yPercent: 105,
|
new SplitText(aboutSection.querySelectorAll(".image > p"), {
|
||||||
stagger: 0.06,
|
type: "lines, words",
|
||||||
ease: "expo.out",
|
autoSplit: true,
|
||||||
onComplete: () => self.revert(),
|
mask: "lines",
|
||||||
},
|
linesClass: "line",
|
||||||
"image-text",
|
onSplit: (self) => {
|
||||||
);
|
tl.from(
|
||||||
},
|
self.lines,
|
||||||
|
{
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: 105,
|
||||||
|
stagger: 0.06,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"image-text",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -104,100 +104,104 @@ import ArrowUpRight from "../icons/ArrowUpRight.astro";
|
|||||||
const contactSection = document.querySelector(".contact");
|
const contactSection = document.querySelector(".contact");
|
||||||
|
|
||||||
if (contactSection) {
|
if (contactSection) {
|
||||||
const tl = gsap.timeline({
|
const mm = gsap.matchMedia();
|
||||||
scrollTrigger: {
|
|
||||||
trigger: contactSection,
|
|
||||||
start: "top 60%",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
tl.addLabel("image", 0.2);
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
tl.addLabel("heading", 0.5);
|
const tl = gsap.timeline({
|
||||||
tl.addLabel("text", 0.6);
|
scrollTrigger: {
|
||||||
tl.addLabel("arrow", 0.6);
|
trigger: contactSection,
|
||||||
|
start: "top 60%",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
new SplitText(contactSection.querySelector("h2"), {
|
tl.addLabel("image", 0.2);
|
||||||
type: "words, chars",
|
tl.addLabel("heading", 0.5);
|
||||||
autoSplit: true,
|
tl.addLabel("text", 0.6);
|
||||||
mask: "chars",
|
tl.addLabel("arrow", 0.6);
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
new SplitText(contactSection.querySelector("h2"), {
|
||||||
tl.from(
|
type: "words, chars",
|
||||||
self.chars,
|
autoSplit: true,
|
||||||
{
|
mask: "chars",
|
||||||
|
charsClass: "char",
|
||||||
|
onSplit: (self) => {
|
||||||
|
tl.from(
|
||||||
|
self.chars,
|
||||||
|
{
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: -120,
|
||||||
|
scale: 1.2,
|
||||||
|
stagger: 0.015,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"heading",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new SplitText(contactSection.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",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
tl.from(
|
||||||
|
contactSection.querySelector(".image"),
|
||||||
|
{
|
||||||
|
duration: 2,
|
||||||
|
opacity: 0,
|
||||||
|
xPercent: -10,
|
||||||
|
ease: "expo.out",
|
||||||
|
},
|
||||||
|
"image",
|
||||||
|
);
|
||||||
|
|
||||||
|
new SplitText(contactSection.querySelector("a"), {
|
||||||
|
type: "words, chars",
|
||||||
|
autoSplit: true,
|
||||||
|
mask: "chars",
|
||||||
|
charsClass: "char",
|
||||||
|
onSplit: (self) => {
|
||||||
|
gsap.from(self.chars, {
|
||||||
|
scrollTrigger: {
|
||||||
|
trigger: contactSection,
|
||||||
|
start: "top 50%",
|
||||||
|
},
|
||||||
duration: 0.9,
|
duration: 0.9,
|
||||||
yPercent: -120,
|
yPercent: -120,
|
||||||
scale: 1.2,
|
scale: 1.2,
|
||||||
stagger: 0.015,
|
stagger: 0.015,
|
||||||
ease: "expo.out",
|
ease: "expo.out",
|
||||||
onComplete: () => self.revert(),
|
onComplete: () => self.revert(),
|
||||||
},
|
});
|
||||||
"heading",
|
},
|
||||||
);
|
});
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
new SplitText(contactSection.querySelector("p"), {
|
tl.from(
|
||||||
type: "lines, words",
|
contactSection.querySelector("a > svg"),
|
||||||
autoSplit: true,
|
{
|
||||||
mask: "lines",
|
duration: 1,
|
||||||
linesClass: "line",
|
opacity: 0,
|
||||||
onSplit: (self) => {
|
yPercent: -10,
|
||||||
tl.from(
|
|
||||||
self.lines,
|
|
||||||
{
|
|
||||||
duration: 0.9,
|
|
||||||
yPercent: 105,
|
|
||||||
stagger: 0.06,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
},
|
|
||||||
"text",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
tl.from(
|
|
||||||
contactSection.querySelector(".image"),
|
|
||||||
{
|
|
||||||
duration: 2,
|
|
||||||
opacity: 0,
|
|
||||||
xPercent: -10,
|
|
||||||
ease: "expo.out",
|
|
||||||
},
|
|
||||||
"image",
|
|
||||||
);
|
|
||||||
|
|
||||||
new SplitText(contactSection.querySelector("a"), {
|
|
||||||
type: "words, chars",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "chars",
|
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
|
||||||
gsap.from(self.chars, {
|
|
||||||
scrollTrigger: {
|
|
||||||
trigger: contactSection,
|
|
||||||
start: "top 50%",
|
|
||||||
},
|
|
||||||
duration: 0.9,
|
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
ease: "expo.out",
|
||||||
onComplete: () => self.revert(),
|
},
|
||||||
});
|
"arrow",
|
||||||
},
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tl.from(
|
|
||||||
contactSection.querySelector("a > svg"),
|
|
||||||
{
|
|
||||||
duration: 1,
|
|
||||||
opacity: 0,
|
|
||||||
yPercent: -10,
|
|
||||||
ease: "expo.out",
|
|
||||||
},
|
|
||||||
"arrow",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -125,74 +125,78 @@ import ArrowDown from "../icons/ArrowDown.astro";
|
|||||||
const heroSection = document.querySelector(".hero");
|
const heroSection = document.querySelector(".hero");
|
||||||
|
|
||||||
if (heroSection) {
|
if (heroSection) {
|
||||||
const tl = gsap.timeline().pause();
|
const mm = gsap.matchMedia();
|
||||||
|
|
||||||
tl.addLabel("heading", 0);
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
tl.addLabel("image", 0.2);
|
const tl = gsap.timeline().pause();
|
||||||
tl.addLabel("text", 0.8);
|
|
||||||
tl.addLabel("arrow", 1.5);
|
|
||||||
|
|
||||||
tl.from(
|
tl.addLabel("heading", 0);
|
||||||
heroSection.querySelector(".image"),
|
tl.addLabel("image", 0.2);
|
||||||
{
|
tl.addLabel("text", 0.8);
|
||||||
duration: 2,
|
tl.addLabel("arrow", 1.5);
|
||||||
opacity: 0,
|
|
||||||
xPercent: 10,
|
|
||||||
ease: "expo.out",
|
|
||||||
},
|
|
||||||
"image",
|
|
||||||
);
|
|
||||||
|
|
||||||
new SplitText(heroSection.querySelector("h1"), {
|
tl.from(
|
||||||
type: "words, chars",
|
heroSection.querySelector(".image"),
|
||||||
autoSplit: true,
|
{
|
||||||
mask: "chars",
|
duration: 2,
|
||||||
charsClass: "char",
|
opacity: 0,
|
||||||
onSplit: (self) => {
|
xPercent: 10,
|
||||||
tl.from(
|
ease: "expo.out",
|
||||||
self.chars,
|
},
|
||||||
{
|
"image",
|
||||||
duration: 1,
|
);
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
new SplitText(heroSection.querySelector("h1"), {
|
||||||
stagger: 0.015,
|
type: "words, chars",
|
||||||
ease: "expo.out",
|
autoSplit: true,
|
||||||
onComplete: () => self.revert(),
|
mask: "chars",
|
||||||
},
|
charsClass: "char",
|
||||||
"heading",
|
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",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
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>
|
</script>
|
||||||
|
|||||||
@@ -110,68 +110,72 @@ const services: Array<ComponentProps<typeof ServicesCard>> = [
|
|||||||
const servicesSection = document.querySelector(".services");
|
const servicesSection = document.querySelector(".services");
|
||||||
|
|
||||||
if (servicesSection) {
|
if (servicesSection) {
|
||||||
const tl = gsap.timeline({
|
const mm = gsap.matchMedia();
|
||||||
scrollTrigger: {
|
|
||||||
trigger: servicesSection,
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
start: "top 60%",
|
const tl = gsap.timeline({
|
||||||
},
|
scrollTrigger: {
|
||||||
|
trigger: servicesSection,
|
||||||
|
start: "top 60%",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
tl.addLabel("heading", 0);
|
||||||
|
tl.addLabel("text", 0.3);
|
||||||
|
tl.addLabel("cards", 0.5);
|
||||||
|
|
||||||
|
new SplitText(servicesSection.querySelector("h2"), {
|
||||||
|
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(servicesSection.querySelector("p"), {
|
||||||
|
type: "lines, words",
|
||||||
|
autoSplit: true,
|
||||||
|
mask: "lines",
|
||||||
|
linesClass: "line",
|
||||||
|
onSplit: (self) => {
|
||||||
|
tl.from(
|
||||||
|
self.lines,
|
||||||
|
{
|
||||||
|
duration: 1.5,
|
||||||
|
yPercent: 105,
|
||||||
|
stagger: 0.06,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"text",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
tl.from(
|
||||||
|
servicesSection.querySelectorAll(".cards > *"),
|
||||||
|
{
|
||||||
|
duration: 1,
|
||||||
|
opacity: 0,
|
||||||
|
yPercent: 5,
|
||||||
|
stagger: 0.15,
|
||||||
|
ease: "expo.out",
|
||||||
|
},
|
||||||
|
"cards",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
tl.addLabel("heading", 0);
|
|
||||||
tl.addLabel("text", 0.3);
|
|
||||||
tl.addLabel("cards", 0.5);
|
|
||||||
|
|
||||||
new SplitText(servicesSection.querySelector("h2"), {
|
|
||||||
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(servicesSection.querySelector("p"), {
|
|
||||||
type: "lines, words",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "lines",
|
|
||||||
linesClass: "line",
|
|
||||||
onSplit: (self) => {
|
|
||||||
tl.from(
|
|
||||||
self.lines,
|
|
||||||
{
|
|
||||||
duration: 1.5,
|
|
||||||
yPercent: 105,
|
|
||||||
stagger: 0.06,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
},
|
|
||||||
"text",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
tl.from(
|
|
||||||
servicesSection.querySelectorAll(".cards > *"),
|
|
||||||
{
|
|
||||||
duration: 1,
|
|
||||||
opacity: 0,
|
|
||||||
yPercent: 5,
|
|
||||||
stagger: 0.15,
|
|
||||||
ease: "expo.out",
|
|
||||||
},
|
|
||||||
"cards",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -113,101 +113,105 @@ function formatIndex(index: number) {
|
|||||||
const valuesSection = document.querySelector(".values");
|
const valuesSection = document.querySelector(".values");
|
||||||
|
|
||||||
if (valuesSection) {
|
if (valuesSection) {
|
||||||
const heading = valuesSection.querySelector("h2");
|
const mm = gsap.matchMedia();
|
||||||
|
|
||||||
new SplitText(heading, {
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
type: "words, chars",
|
const heading = valuesSection.querySelector("h2");
|
||||||
autoSplit: true,
|
|
||||||
mask: "chars",
|
new SplitText(heading, {
|
||||||
charsClass: "char",
|
type: "words, chars",
|
||||||
onSplit: (self) => {
|
autoSplit: true,
|
||||||
gsap.from(self.chars, {
|
mask: "chars",
|
||||||
|
charsClass: "char",
|
||||||
|
onSplit: (self) => {
|
||||||
|
gsap.from(self.chars, {
|
||||||
|
scrollTrigger: {
|
||||||
|
trigger: heading,
|
||||||
|
start: "top 70%",
|
||||||
|
},
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: -120,
|
||||||
|
scale: 1.2,
|
||||||
|
stagger: 0.015,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const items = valuesSection.querySelectorAll("li");
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
const itemTl = gsap.timeline({
|
||||||
scrollTrigger: {
|
scrollTrigger: {
|
||||||
trigger: heading,
|
trigger: item,
|
||||||
start: "top 70%",
|
start: "top 70%",
|
||||||
},
|
},
|
||||||
duration: 0.9,
|
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const items = valuesSection.querySelectorAll("li");
|
itemTl.addLabel("number", 0);
|
||||||
|
itemTl.addLabel("heading", 0.2);
|
||||||
|
itemTl.addLabel("text", 0.5);
|
||||||
|
|
||||||
items.forEach((item) => {
|
new SplitText(item.querySelector("span"), {
|
||||||
const itemTl = gsap.timeline({
|
type: "words, chars",
|
||||||
scrollTrigger: {
|
autoSplit: true,
|
||||||
trigger: item,
|
mask: "chars",
|
||||||
start: "top 70%",
|
charsClass: "char",
|
||||||
},
|
onSplit: (self) => {
|
||||||
});
|
itemTl.from(
|
||||||
|
self.chars,
|
||||||
|
{
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: -120,
|
||||||
|
stagger: 0.25,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"number",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
itemTl.addLabel("number", 0);
|
new SplitText(item.querySelector("h3"), {
|
||||||
itemTl.addLabel("heading", 0.2);
|
type: "words, chars",
|
||||||
itemTl.addLabel("text", 0.5);
|
autoSplit: true,
|
||||||
|
mask: "chars",
|
||||||
|
charsClass: "char",
|
||||||
|
onSplit: (self) => {
|
||||||
|
itemTl.from(
|
||||||
|
self.chars,
|
||||||
|
{
|
||||||
|
duration: 0.9,
|
||||||
|
yPercent: -120,
|
||||||
|
stagger: 0.015,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
},
|
||||||
|
"heading",
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
new SplitText(item.querySelector("span"), {
|
new SplitText(item.querySelector("p"), {
|
||||||
type: "words, chars",
|
type: "lines, words",
|
||||||
autoSplit: true,
|
autoSplit: true,
|
||||||
mask: "chars",
|
mask: "lines",
|
||||||
charsClass: "char",
|
linesClass: "line",
|
||||||
onSplit: (self) => {
|
onSplit: (self) => {
|
||||||
itemTl.from(
|
itemTl.from(
|
||||||
self.chars,
|
self.lines,
|
||||||
{
|
{
|
||||||
duration: 0.9,
|
duration: 0.9,
|
||||||
yPercent: -120,
|
yPercent: 105,
|
||||||
stagger: 0.25,
|
stagger: 0.06,
|
||||||
ease: "expo.out",
|
ease: "expo.out",
|
||||||
onComplete: () => self.revert(),
|
onComplete: () => self.revert(),
|
||||||
},
|
},
|
||||||
"number",
|
"text",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new SplitText(item.querySelector("h3"), {
|
|
||||||
type: "words, chars",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "chars",
|
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
|
||||||
itemTl.from(
|
|
||||||
self.chars,
|
|
||||||
{
|
|
||||||
duration: 0.9,
|
|
||||||
yPercent: -120,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
},
|
|
||||||
"heading",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
new SplitText(item.querySelector("p"), {
|
|
||||||
type: "lines, words",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "lines",
|
|
||||||
linesClass: "line",
|
|
||||||
onSplit: (self) => {
|
|
||||||
itemTl.from(
|
|
||||||
self.lines,
|
|
||||||
{
|
|
||||||
duration: 0.9,
|
|
||||||
yPercent: 105,
|
|
||||||
stagger: 0.06,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
},
|
|
||||||
"text",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-23
@@ -63,30 +63,34 @@ import BaseLayout from "../layouts/BaseLayout.astro";
|
|||||||
const page = document.querySelector(".imprint");
|
const page = document.querySelector(".imprint");
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
new SplitText(page.querySelector("h1"), {
|
const mm = gsap.matchMedia();
|
||||||
type: "words, chars",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "chars",
|
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
|
||||||
gsap.from(self.chars, {
|
|
||||||
duration: 1,
|
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
gsap.from(page.querySelectorAll(":scope > div"), {
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
duration: 1,
|
new SplitText(page.querySelector("h1"), {
|
||||||
delay: 0.3,
|
type: "words, chars",
|
||||||
opacity: 0,
|
autoSplit: true,
|
||||||
yPercent: -20,
|
mask: "chars",
|
||||||
ease: "expo.out",
|
charsClass: "char",
|
||||||
stagger: 0.1,
|
onSplit: (self) => {
|
||||||
|
gsap.from(self.chars, {
|
||||||
|
duration: 1,
|
||||||
|
yPercent: -120,
|
||||||
|
scale: 1.2,
|
||||||
|
stagger: 0.015,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
gsap.from(page.querySelectorAll(":scope > div"), {
|
||||||
|
duration: 1,
|
||||||
|
delay: 0.3,
|
||||||
|
opacity: 0,
|
||||||
|
yPercent: -20,
|
||||||
|
ease: "expo.out",
|
||||||
|
stagger: 0.1,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
|
||||||
const allPosts = Object.values(
|
|
||||||
import.meta.glob("./posts/*.md", { eager: true }),
|
|
||||||
);
|
|
||||||
const pageTitle = "My Astro Learning Blog";
|
|
||||||
---
|
|
||||||
|
|
||||||
<BaseLayout pageTitle={pageTitle}>
|
|
||||||
<p>This is where I will post about my journey learning Astro.</p>
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
allPosts.map((post: any) => (
|
|
||||||
<li>
|
|
||||||
<a href={post.url}>{post.frontmatter.title}</a>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</BaseLayout>
|
|
||||||
+27
-23
@@ -134,30 +134,34 @@ import BaseLayout from "../layouts/BaseLayout.astro";
|
|||||||
const page = document.querySelector(".privacy");
|
const page = document.querySelector(".privacy");
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
new SplitText(page.querySelector("h1"), {
|
const mm = gsap.matchMedia();
|
||||||
type: "words, chars",
|
|
||||||
autoSplit: true,
|
|
||||||
mask: "chars",
|
|
||||||
charsClass: "char",
|
|
||||||
onSplit: (self) => {
|
|
||||||
gsap.from(self.chars, {
|
|
||||||
duration: 1,
|
|
||||||
yPercent: -120,
|
|
||||||
scale: 1.2,
|
|
||||||
stagger: 0.015,
|
|
||||||
ease: "expo.out",
|
|
||||||
onComplete: () => self.revert(),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
gsap.from(page.querySelectorAll(".content > *"), {
|
mm.add("(prefers-reduced-motion: no-preference)", () => {
|
||||||
duration: 1,
|
new SplitText(page.querySelector("h1"), {
|
||||||
delay: 0.3,
|
type: "words, chars",
|
||||||
opacity: 0,
|
autoSplit: true,
|
||||||
yPercent: -20,
|
mask: "chars",
|
||||||
ease: "expo.out",
|
charsClass: "char",
|
||||||
stagger: 0.1,
|
onSplit: (self) => {
|
||||||
|
gsap.from(self.chars, {
|
||||||
|
duration: 1,
|
||||||
|
yPercent: -120,
|
||||||
|
scale: 1.2,
|
||||||
|
stagger: 0.015,
|
||||||
|
ease: "expo.out",
|
||||||
|
onComplete: () => self.revert(),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
gsap.from(page.querySelectorAll(".content > *"), {
|
||||||
|
duration: 1,
|
||||||
|
delay: 0.3,
|
||||||
|
opacity: 0,
|
||||||
|
yPercent: -20,
|
||||||
|
ease: "expo.out",
|
||||||
|
stagger: 0.1,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user