灯箱 - 相册页原本已有一套无依赖灯箱(事件委托 + ClientRouter 友好), 但它写在 gallery/[album].astro 里,只有相册页能用。 现抽成 src/components/ImageLightbox.astro,挂到 BaseLayout,全站可用。 - 新增 src/plugins/rehype-image-lightbox.mjs:给正文里的 <img> 注入 data-lightbox-src。跳过链接内的图片(点击应跳转)和显式标记 data-lightbox-ignore 的图片。 - 顺带让灯箱大图继承原图的 alt 文本(原先固定为空)。 - 正文图片加 cursor: zoom-in 提示。 清理 - 删除 src/plugins/rehype-component-github-card.mjs(165 行)及其在 rehypeComponents 里的 github 映射:内容里从未使用过 ::github 指令。 验证:构建 41 页通过;文章页正文图片 4/4 带上 data-lightbox-src, 相册页 5 个触发元素不受影响;灯箱脚本按页内联(2.8KB 压缩后); 正文渲染文本与线上基线一致,无回归。
125 lines
4.5 KiB
Plaintext
125 lines
4.5 KiB
Plaintext
---
|
|
import BaseLayout from "@/layouts/BaseLayout.astro"
|
|
import SiteHeader from "@/components/site-header.astro"
|
|
import Footer from "@/components/footer.astro"
|
|
import { siteTitleSuffix } from "@/data/site"
|
|
import { galleryConfig } from "@/data/gallery"
|
|
import { getAlbumCover, scanAlbumPhotos } from "@/lib/gallery"
|
|
|
|
export function getStaticPaths() {
|
|
return galleryConfig.albums.map((album) => ({ params: { album: album.id } }))
|
|
}
|
|
|
|
const albumId = Astro.params.album as string
|
|
const album = galleryConfig.albums.find((a) => a.id === albumId)
|
|
|
|
if (!album) {
|
|
return Astro.redirect("/404/")
|
|
}
|
|
|
|
const photos = scanAlbumPhotos(album.id)
|
|
const cover = getAlbumCover(album, photos)
|
|
const columnWidth = galleryConfig.columnWidth || 240
|
|
|
|
const title = `${album.name} | ${siteTitleSuffix}`
|
|
const description = album.description ?? "相册"
|
|
---
|
|
|
|
<BaseLayout {title} {description} fontProfile="interface">
|
|
<div class="min-h-screen bg-background dark:bg-surface-subtle">
|
|
<SiteHeader />
|
|
<main class="pt-20 pb-16">
|
|
{/* 封面横幅 */}
|
|
<section class="relative w-full overflow-hidden">
|
|
{cover ? (
|
|
<div class="relative h-[240px] w-full sm:h-[320px]">
|
|
<img src={cover} alt={album.name} class="h-full w-full object-cover" />
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/35 to-black/10" />
|
|
|
|
<a
|
|
href="/gallery/"
|
|
class="absolute left-4 top-4 rounded-lg bg-black/35 px-3 py-1.5 text-sm text-white/90 backdrop-blur-sm transition-colors hover:bg-black/55 hover:text-white"
|
|
>
|
|
← 返回相册
|
|
</a>
|
|
|
|
<div class="absolute inset-x-0 bottom-0 p-6">
|
|
<div class="mx-auto max-w-6xl">
|
|
<h1 class="mb-2 text-2xl font-bold text-white drop-shadow-lg sm:text-3xl">
|
|
{album.name}
|
|
</h1>
|
|
{album.description && (
|
|
<p class="mb-2 max-w-2xl line-clamp-2 text-sm leading-relaxed text-white/75">
|
|
{album.description}
|
|
</p>
|
|
)}
|
|
<div class="flex flex-wrap items-center gap-4 text-sm text-white/80">
|
|
{album.date && <span>🗓 {album.date}</span>}
|
|
{album.location && <span>📍 {album.location}</span>}
|
|
<span>🖼 {photos.length} 张</span>
|
|
</div>
|
|
{album.tags && album.tags.length > 0 && (
|
|
<div class="mt-2.5 flex flex-wrap gap-1.5">
|
|
{album.tags.map((tag) => (
|
|
<span class="rounded bg-white/20 px-2 py-0.5 text-xs text-white/90 backdrop-blur-sm">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div class="mx-auto max-w-6xl px-6 pt-4">
|
|
<a href="/gallery/" class="mb-3 inline-block text-sm text-primary hover:underline">
|
|
← 返回相册
|
|
</a>
|
|
<h1 class="text-2xl font-bold text-foreground sm:text-3xl">{album.name}</h1>
|
|
</div>
|
|
)}
|
|
</section>
|
|
|
|
{/* 瀑布流 */}
|
|
<section class="mx-auto max-w-6xl px-6 pt-8">
|
|
{photos.length > 0 ? (
|
|
<div class="gallery-masonry" style={`--col-width: ${columnWidth}px;`}>
|
|
{photos.map((photo, index) => (
|
|
<button
|
|
type="button"
|
|
data-lightbox-src={photo}
|
|
data-lightbox-index={index}
|
|
aria-label={`查看第 ${index + 1} 张照片`}
|
|
class="gallery-photo mb-3 block w-full cursor-zoom-in overflow-hidden rounded-xl border border-border/50 bg-card p-0"
|
|
>
|
|
<img
|
|
src={photo}
|
|
alt=""
|
|
loading="lazy"
|
|
decoding="async"
|
|
class="h-auto w-full object-cover transition-transform duration-300 hover:scale-[1.03]"
|
|
/>
|
|
</button>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div class="py-20 text-center text-muted-foreground">
|
|
这个相册还没有照片。往 <code class="rounded bg-secondary px-1.5 py-0.5">public/gallery/{album.id}/</code> 里放图片即可。
|
|
</div>
|
|
)}
|
|
</section>
|
|
</main>
|
|
<Footer />
|
|
</div>
|
|
</BaseLayout>
|
|
|
|
<style is:global>
|
|
.gallery-masonry {
|
|
column-width: var(--col-width, 240px);
|
|
column-gap: 0.75rem;
|
|
}
|
|
.gallery-masonry .gallery-photo {
|
|
break-inside: avoid;
|
|
}
|
|
</style>
|