fix: the better animation for slideshow.

This commit is contained in:
Yufan Sheng 2024-12-04 21:39:36 +08:00
parent 8f1ba7136a
commit 00e6d2b93f
Signed by: syhily
GPG Key ID: DEB186763C308C31
8 changed files with 35 additions and 106 deletions

View File

@ -259,9 +259,6 @@ The source codes used from third party projects are:
- [images.ts](src/helpers/images.ts)
from [vercel/next.js](https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/image-blur-svg.ts)
with [license](licenses/LICENSE.vercel.txt)
- [photoswipe-auto-hide-ui.js](src/assets/scripts/photoswipe/photoswipe-auto-hide-ui.js)
from [arnowelzel/photoswipe-auto-hide-ui](https://github.com/arnowelzel/photoswipe-auto-hide-ui)
with [license](licenses/LICENSE.arnowelzel.txt)
- [photoswipe-slideshow.js](src/assets/scripts/photoswipe/photoswipe-slideshow.js)
- [photoswipe-slideshow.js](src/assets/scripts/photoswipe-slideshow.js)
from [junkfix/photoswipe-slideshow](https://github.com/junkfix/photoswipe-slideshow)
with [license](licenses/LICENSE.junkfix.txt)

2
package-lock.json generated
View File

@ -54,7 +54,7 @@
"unist-util-select": "^5.1.0"
},
"engines": {
"node": "22.11.0"
"node": "22.12.0"
}
},
"node_modules/@astrojs/check": {

View File

@ -88,6 +88,6 @@
},
"packageManager": "npm@10.9.1",
"engines": {
"node": "22.11.0"
"node": "22.12.0"
}
}

View File

@ -1,92 +0,0 @@
/**
* PhotoSwipe Auto Hide UI plugin v1.0.1
*
* https://github.com/arnowelzel/photoswipe-auto-hide-ui
*/
const defaultOptions = {
idleTime: 4000,
};
class PhotoSwipeAutoHideUI {
constructor(lightbox, options) {
this.options = {
...defaultOptions,
...options,
};
this.captionTimer = false;
this.lightbox = lightbox;
this.hasTouch = false;
this.lightbox.on('change', () => {
document.addEventListener(
'touchstart',
() => {
this.stopHideTimer();
this.hasTouch = true;
},
{ once: true },
);
document.addEventListener(
'mousemove',
() => {
this.startHideTimer();
},
{ once: true },
);
});
this.lightbox.on('destroy', () => {
this.stopHideTimer();
});
}
showUI() {
if (this.lightbox?.pswp?.element) {
this.lightbox.pswp.element.classList.add('pswp--ui-visible');
}
}
hideUI() {
if (this.lightbox?.pswp?.element) {
this.lightbox.pswp.element.classList.remove('pswp--ui-visible');
}
}
mouseMove() {
this.stopHideTimer();
if (this.lightbox) {
this.showUI();
this.startHideTimer();
}
}
startHideTimer() {
if (this.hasTouch) {
return;
}
this.stopHideTimer();
this.captionTimer = window.setTimeout(() => {
this.hideUI();
}, this.options.idleTime);
document.addEventListener(
'mousemove',
() => {
this.mouseMove();
},
{ once: true },
);
}
stopHideTimer() {
if (this.captionTimer) {
window.clearTimeout(this.captionTimer);
this.captionTimer = false;
}
}
}
export default PhotoSwipeAutoHideUI;

View File

@ -4,8 +4,7 @@ import PhotoSwipe from 'photoswipe';
import PhotoSwipeDynamicCaption from 'photoswipe-dynamic-caption-plugin';
import PhotoSwipeVideo from 'photoswipe-video-plugin';
import PhotoSwipeLightbox from 'photoswipe/lightbox';
import PhotoSwipeAutoHideUI from './photoswipe/photoswipe-auto-hide-ui.js';
import PhotoSwipeSlideshow from './photoswipe/photoswipe-slideshow.js';
import PhotoSwipeSlideshow from './photoswipe-slideshow.js';
import stickySidebar from './sticky-sidebar.js';
// Slideshow for Album.
@ -15,6 +14,8 @@ for (const album of document.querySelectorAll('.post-content .album')) {
gallery: album,
pswpModule: PhotoSwipe,
children: 'a',
showHideAnimationType: 'zoom',
zoomAnimationDuration: 400,
bgOpacity: 1,
});
@ -25,7 +26,7 @@ for (const album of document.querySelectorAll('.post-content .album')) {
// Add a slideshow to the PhotoSwipe gallery.
new PhotoSwipeSlideshow(lightbox, {
defaultDelayMs: 7000, // 7 seconds
defaultDelayMs: 7000,
restartOnSlideChange: true,
progressBarPosition: 'top',
autoHideProgressBar: false,
@ -34,9 +35,6 @@ for (const album of document.querySelectorAll('.post-content .album')) {
// Plugin to display video.
new PhotoSwipeVideo(lightbox, {});
// Hide the PhotoSwipe UI after some time of inactivity.
new PhotoSwipeAutoHideUI(lightbox, {});
lightbox.init();
}

View File

@ -9,6 +9,23 @@ interface Props {
const { id } = Astro.props;
const album = getAlbum(id);
const calculateCroppedWidth = (width: number, height: number, first: boolean): number => {
// 300 * 300
if (!first) {
if (width < 300 || height < 300) {
return width;
}
return width > height ? Math.round((300.0 / height) * width) : 300;
}
// 600 * 300
if (width < 600 || height < 300) {
return width;
}
return width > height ? (600.0 / width > 300.0 / height ? 600 : Math.round((300.0 / height) * width)) : 600;
};
const calculateCroppedHeight = (width: number, height: number, croppedWidth: number): number =>
croppedWidth === width ? height : Math.round(((1.0 * croppedWidth) / width) * height);
---
{
@ -25,8 +42,18 @@ const album = getAlbum(id);
class="media-content album-picture"
data-pswp-width={picture.width}
data-pswp-height={picture.height}
data-cropped="true"
>
<Image {...picture} alt={picture.title || ''} width={index === 0 ? 600 : 300} height={300} />
<Image
{...picture}
alt={picture.title || ''}
width={calculateCroppedWidth(picture.width as number, picture.height as number, index === 0)}
height={calculateCroppedHeight(
picture.width as number,
picture.height as number,
calculateCroppedWidth(picture.width as number, picture.height as number, index === 0),
)}
/>
<div class="overlay" />
<div class="album-picture-meta pswp-caption-content d-none">
{picture.title && <h3>{picture.title}</h3>}

View File

@ -13,7 +13,6 @@ const album = getAlbum(id);
{
album !== undefined && (
<Fragment>
<h2>{album.title}</h2>
{album.description && <Fragment set:html={album.description} />}
{album.pictures.map((picture) => (
<Fragment>