Create products showcase section

This commit is contained in:
marzban-dev
2025-02-21 19:59:26 +03:30
parent 3656be81a1
commit 1c47378895
@@ -0,0 +1,135 @@
<script lang="ts" setup>
// state
const { $gsap: gsap, $ScrollTrigger: ScrollTrigger } = useNuxtApp();
const slides = [
{
id: 1,
title: "موبایل iPhone 16 Pro Max",
description: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم.",
image: "/img/showcase-1.png"
},
{
id: 2,
title: "موبایل iPhone 16 Pro Max",
description: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم.",
image: "/img/showcase-2.png"
},
{
id: 3,
title: "موبایل iPhone 16 Pro Max",
description: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم.",
image: "/img/showcase-1.png"
}
];
let gsapTimeline: gsap.core.Timeline;
// lifecycle
onMounted(() => {
gsapTimeline = gsap.timeline();
gsapTimeline
.fromTo("#header-navbar", {
background: "white",
filter: "invert(0%)"
}, {
background: "transparent",
filter: "invert(100%)"
});
const showcaseElements = gsap.utils.toArray<HTMLElement>(".showcase-slide");
showcaseElements.forEach((element, index) => {
gsapTimeline.fromTo(element, index === 0 ? {
opacity: 1,
scale: 1,
// rotateX: -25,
y: 0,
ease: "none"
} : {
opacity: 0,
scale: 0.97,
// rotateX: -25,
y: 20,
ease: "none"
}, {
opacity: 1,
scale: 1,
// rotateX: 0,
y: 0,
ease: "none"
}, index === 0 ? "-=0%" : undefined);
if (index < showcaseElements.length - 1) {
gsapTimeline.to(element, {
opacity: 0,
scale: 1.03,
// rotateX: 25,
y: -20,
ease: "none"
});
}
});
gsapTimeline.to("#header-navbar", {
background: "white",
filter: "invert(0%)"
});
ScrollTrigger.create({
trigger: "#products-showcase-container",
animation: gsapTimeline,
scrub: 1,
pin: true,
start: "top top",
// markers: true,
end: "bottom top"
});
});
onUnmounted(() => {
gsapTimeline.progress(1).pause();
gsapTimeline.kill();
});
</script>
<template>
<div
id="products-showcase-container"
class="mt-80 mb-40 perspective-midrange w-full h-[125svh] bg-black flex items-center justify-center"
>
<div
v-for="slide in slides"
:key="slide.id"
class="showcase-slide origin-bottom absolute size-full bg-transparent flex items-center justify-center"
>
<div
class="blur-[150px] w-[600px] h-[80px] bg-white/70 absolute z-10"
/>
<img
class="w-[650px] z-20 mb-30"
:src="slide.image"
:style="{
mask: 'linear-gradient(to bottom, black 0%, rgba(0,0,0,0) 100%)',
}"
alt=""
/>
<div class="flex flex-col items-center justify-center gap-4 text-center absolute z-20 mt-20">
<span class="text-white typo-h-3">
{{ slide.title }}
</span>
<p class="text-white max-w-[750px] typo-p-lg">
{{ slide.description }}
</p>
</div>
</div>
</div>
</template>