diff --git a/src/components/ImageLightbox.astro b/src/components/ImageLightbox.astro index 2764f39..acd9e72 100644 --- a/src/components/ImageLightbox.astro +++ b/src/components/ImageLightbox.astro @@ -33,10 +33,71 @@ const lightbox = new PhotoSwipeLightbox({ pswpModule: () => import('photoswipe'), bgClickAction: 'close', + wheelToZoom: true, + allowPanToNext: true, + pinchToClose: true, showHideAnimationType: 'zoom', showAnimationDuration: 360, hideAnimationDuration: 300, - easing: 'cubic-bezier(0.22, 1, 0.36, 1)' + easing: 'cubic-bezier(0.22, 1, 0.36, 1)', + paddingFn: (viewportSize) => ({ + top: 16, + right: 16, + bottom: viewportSize.x < 640 ? 78 : 92, + left: 16 + }) + }); + + lightbox.on('uiRegister', () => { + lightbox.pswp?.ui?.registerElement({ + name: 'thumbnails', + className: 'pswp__thumbnails', + appendTo: 'root', + order: 20, + onInit: (element, pswp) => { + element.setAttribute('role', 'toolbar'); + element.setAttribute('aria-label', '图片预览'); + + const buttons = Array.from({ length: pswp.getNumItems() }, (_, itemIndex) => { + const item = pswp.getItemData(itemIndex); + const button = document.createElement('button'); + const thumbnail = document.createElement('img'); + const label = item.alt ? `查看图片:${item.alt}` : `查看第 ${itemIndex + 1} 张图片`; + + button.type = 'button'; + button.className = 'pswp__thumbnail'; + button.title = label; + button.setAttribute('aria-label', label); + button.addEventListener('click', () => pswp.goTo(itemIndex)); + + thumbnail.src = item.msrc || item.src || ''; + thumbnail.alt = ''; + thumbnail.draggable = false; + button.append(thumbnail); + element.append(button); + return button; + }); + + const updateCurrentThumbnail = () => { + buttons.forEach((button, itemIndex) => { + const isCurrent = itemIndex === pswp.currIndex; + button.classList.toggle('is-current', isCurrent); + if (isCurrent) { + button.setAttribute('aria-current', 'true'); + element.scrollTo({ + behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth', + left: button.offsetLeft - (element.clientWidth - button.clientWidth) / 2 + }); + } else { + button.removeAttribute('aria-current'); + } + }); + }; + + pswp.on('change', updateCurrentThumbnail); + updateCurrentThumbnail(); + } + }); }); lightbox.init(); return lightbox; @@ -91,4 +152,83 @@