@@ -123,7 +123,7 @@ class="font-teko text-7xl md:text-9xl lg:text-[10rem] text-white uppercase leadi
123123 {{-- 2. SECCIÓN GALERÍA (sin cambios en su estructura) --}}
124124 <div class =" bg-surface text-on-surface" >
125125 <div class =" container mx-auto py-16 px-4" >
126- <div id =" gallery-container" class =" columns-2 md:columns-3 gap-4" ></div >
126+ <div id =" gallery-container" data-gallery-url = " {{ route ( ' projects.gallery ' , $project ) } } " class =" columns-2 md:columns-3 gap-4" ></div >
127127 </div >
128128 </div >
129129
@@ -316,98 +316,10 @@ function runCluster() {
316316 runCluster ();
317317 }
318318
319-
320- // ---------- GALERÍA ----------
321- async function buildFullGallery () {
322- if (! galleryContainer) return ;
323- try {
324- const res = await fetch (` {{ route (' projects.gallery' , $project ) } }` );
325- if (! res .ok ) throw new Error (' HTTP ' + res .status );
326- const images = await res .json ();
327- if (! images? .length ) {
328- galleryContainer .innerHTML = ' <p class="text-on-surface/60">Esta galería no tiene imágenes.</p>' ;
329- return ;
330- }
331- const frag = document .createDocumentFragment ();
332- images .forEach (img => {
333- const a = document .createElement (' a' );
334- a .href = img .src_full ;
335- a .className = ' gallery-item block mb-4 opacity-0 translate-y-4' ;
336-
337- const ph = document .createElement (' div' );
338- ph .className = ' gallery-item-placeholder w-full overflow-hidden' ;
339- if (img .height > 0 ) ph .style .aspectRatio = ` ${ img .width } / ${ img .height } ` ;
340-
341- const picture = document .createElement (' picture' );
342- picture .innerHTML = `
343- <source type =" image/avif" srcset =" ${img.srcset_avif}" sizes =" (max-width: 768px) 50vw, 33vw" >
344- <source type =" image/webp" srcset =" ${img.srcset_webp}" sizes =" (max-width: 768px) 50vw, 33vw" >
345- <img src =" ${img.src_fallback}" alt =" ${img.alt}" loading =" lazy" decoding =" async"
346- class =" w-full h-full object-cover opacity-0 transition-opacity duration-500" >
347- ` ;
348- const imgEl = picture .querySelector (' img' );
349- imgEl .onload = () => imgEl .classList .remove (' opacity-0' );
350- imgEl .onerror = () => {
351- imgEl .onerror = null ;
352- imgEl .classList .remove (' opacity-0' );
353- imgEl .style .backgroundColor = ' #e5e7eb' ;
354- imgEl .style .minHeight = ' 200px' ;
355- };
356-
357- ph .appendChild (picture);
358- a .appendChild (ph);
359- frag .appendChild (a);
360- });
361- galleryContainer .appendChild (frag);
362- } catch (err) {
363- console .error (' Galería:' , err);
364- }
365- }
366-
367- function setupGalleryAnimation () {
368- if (! galleryContainer) return ;
369- gsap .to (' .gallery-item' , {
370- opacity: 1 , y: 0 , duration: 0.8 , ease: ' power2.out' , stagger: 0.08 ,
371- scrollTrigger: {
372- trigger: " #gallery-container" ,
373- start: " top 85%" ,
374- toggleActions: " play none none none"
375- }
376- });
377- }
378-
379- // ---------- MODAL ----------
380- function setupModal () {
381- const modal = document .getElementById (' image-modal' );
382- if (! modal) return ;
383- const modalImage = document .getElementById (' modal-image' );
384- const modalCloseButton = document .getElementById (' modal-close-button' );
385-
386- const openModal = (url ) => {
387- modalImage .src = url;
388- modal .classList .remove (' opacity-0' , ' pointer-events-none' );
389- document .body .style .overflow = ' hidden' ;
390- };
391- const closeModal = () => {
392- modal .classList .add (' opacity-0' , ' pointer-events-none' );
393- document .body .style .overflow = ' ' ;
394- };
395-
396- galleryContainer? .addEventListener (' click' , e => {
397- const link = e .target .closest (' a.gallery-item' );
398- if (link) { e .preventDefault (); openModal (link .href ); }
399- });
400- modalCloseButton .addEventListener (' click' , closeModal);
401- modal .addEventListener (' click' , e => e .target === modal && closeModal ());
402- document .addEventListener (' keydown' , e => e .key === ' Escape' && closeModal ());
403- }
404-
405- // ---------- RUN ----------
319+ // ---------- RUN HERO ANIMATIONS ----------
406320 splitTitle ();
407321 applyInitialFonts ();
408322 playHeroTL ();
409- setupModal ();
410- buildFullGallery ().then (setupGalleryAnimation);
411323});
412324 </script >
413325
0 commit comments