diff --git a/app/pages/gallery.vue b/app/pages/gallery.vue index acbd398..6ae8c81 100644 --- a/app/pages/gallery.vue +++ b/app/pages/gallery.vue @@ -2,6 +2,7 @@ import { LazyGalleryModal } from "#components"; import type { InternalApi } from "nitropack/types"; import { useElementSize } from "@vueuse/core"; +import gsap from "gsap"; const { data: images } = await useAsyncData( "gallery", @@ -49,6 +50,44 @@ const openModal = async (index: number) => { const getAspectRatio = (image: InternalApi["/api/gallery"]["get"][number]) => { return (image.height / image.width) * 100; }; + +const isAnimating = ref(true); + +onMounted(async () => { + await nextTick(); + + const scrollEl = scrollArea.value?.$el; + if (!scrollEl) return; + + const preventScroll = (e: Event) => { + e.preventDefault(); + e.stopPropagation(); + }; + + scrollEl.addEventListener("wheel", preventScroll, { passive: false }); + scrollEl.addEventListener("touchmove", preventScroll, { passive: false }); + + const items = document.querySelectorAll(".gallery-item"); + gsap.fromTo( + items, + { opacity: 0 }, + { + opacity: 1, + duration: 0.6, + stagger: (index) => { + const line = Math.floor(index / lanes.value); + const column = index % lanes.value; + return line * 0.1 + column * 0.05; + }, + ease: "power2.out", + onComplete: () => { + isAnimating.value = false; + scrollEl.removeEventListener("wheel", preventScroll); + scrollEl.removeEventListener("touchmove", preventScroll); + }, + }, + ); +}); + +