105 lines
4.7 KiB
Plaintext
105 lines
4.7 KiB
Plaintext
---
|
||
// 走秀 / 街拍详情页共享的全屏大图灯箱:大图 + 左/右翻页 + 单图收藏。
|
||
//
|
||
// 左栏「所有图片缩略图条」已移除:翻页/定位已由顶部计数 + 左右箭头 + 键盘 ←/→ + ?img= 深链完整覆盖,
|
||
// 缩略条属冗余导航;去掉后主图可用面积更大。主图翻页实际读的是图集网格里 [data-image-index] 的
|
||
// figure(第 6 张起的 extraImages 也已在网格里渲染),与左栏无关,故移除不影响翻页。
|
||
//
|
||
// 视觉遵循全站「黑白编辑风」:直角细框、小字 + 宽字距、零填充计数、hover 反色(bg-black + 白字)。
|
||
// 交互逻辑全部在 src/lib/gallery.ts(createGalleryView);本组件只负责标记。
|
||
//
|
||
// 各页独有的附加层通过具名插槽 details 注入(走秀页塞「当前 look 的细节图簇」,街拍页不传)。
|
||
import { getI18n } from "@/lib/i18n"
|
||
|
||
const { t } = getI18n(Astro)
|
||
---
|
||
|
||
<div
|
||
x-show="lbOpen"
|
||
x-cloak
|
||
@keydown.window.escape="lbOpen && closeLb()"
|
||
@keydown.window.arrow-right="lbOpen && nextLb()"
|
||
@keydown.window.arrow-left="lbOpen && prevLb()"
|
||
class="fixed inset-0 z-[100] bg-white flex flex-col select-none"
|
||
aria-hidden="true"
|
||
>
|
||
{/* 计数:小字 + 0.22em 字距(全站「小标与计数」档),直角细框,零填充 */}
|
||
<div
|
||
class="absolute top-5 left-1/2 -translate-x-1/2 z-30 border border-black/15 bg-white/90 px-3 py-1 text-[11px] tracking-[0.22em] text-[#111] backdrop-blur-md"
|
||
x-text="`${String(lbIndex + 1).padStart(2, '0')} / ${String(imageCount).padStart(2, '0')}`"
|
||
></div>
|
||
|
||
{/* 单图收藏:圆形,与列表卡片 .fav-toggle / 详情页右下角 #fav-fab 的全站「收藏=圆形」语义保持一致 */}
|
||
<button
|
||
login-required
|
||
type="button"
|
||
@click.stop="toggleFav(currentFavId(), currentFavUrl())"
|
||
:class="isFav(currentFavId()) ? 'is-fav' : ''"
|
||
class="fav-btn absolute top-5 right-[68px] z-30 w-10 h-10 rounded-full border border-black/15 bg-white/90 text-[#111] flex items-center justify-center backdrop-blur-md hover:bg-black hover:text-white transition-colors cursor-pointer"
|
||
aria-label={t('save')}
|
||
>
|
||
<svg class="w-[18px] h-[18px]" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M12 21C12 21 4 14.5 4 8.8C4 6.1 6.1 4 8.7 4C10.3 4 11.5 4.8 12 6C12.5 4.8 13.7 4 15.3 4C17.9 4 20 6.1 20 8.8C20 14.5 12 21 12 21Z"/>
|
||
</svg>
|
||
</button>
|
||
|
||
<button
|
||
type="button"
|
||
@click="closeLb()"
|
||
class="absolute top-5 right-5 z-30 w-10 h-10 border border-black/15 bg-white/90 text-[#111] flex items-center justify-center backdrop-blur-md hover:bg-black hover:text-white transition-colors cursor-pointer"
|
||
aria-label={t('Close')}
|
||
>
|
||
<svg class="w-4 h-4" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" />
|
||
</svg>
|
||
</button>
|
||
|
||
<div class="flex-1 min-h-0 flex items-stretch overflow-hidden relative">
|
||
<button
|
||
type="button"
|
||
@click.stop="prevLb()"
|
||
class="absolute left-2 sm:left-5 top-1/2 -translate-y-1/2 z-20 w-10 h-10 border border-black/15 bg-white/90 text-[#111] flex items-center justify-center backdrop-blur-md hover:bg-black hover:text-white transition-colors cursor-pointer"
|
||
aria-label={t('Previous image')}
|
||
>
|
||
<svg class="w-5 h-5 stroke-current fill-none stroke-2" viewBox="0 0 24 24">
|
||
<path d="M15 6l-6 6 6 6" />
|
||
</svg>
|
||
</button>
|
||
|
||
<button
|
||
type="button"
|
||
@click.stop="nextLb()"
|
||
class="absolute right-2 sm:right-5 top-1/2 -translate-y-1/2 z-20 w-10 h-10 border border-black/15 bg-white/90 text-[#111] flex items-center justify-center backdrop-blur-md hover:bg-black hover:text-white transition-colors cursor-pointer"
|
||
aria-label={t('Next image')}
|
||
>
|
||
<svg class="w-5 h-5 stroke-current fill-none stroke-2" viewBox="0 0 24 24">
|
||
<path d="M9 6l6 6-6 6" />
|
||
</svg>
|
||
</button>
|
||
|
||
<div
|
||
id="lb-main"
|
||
@click.self="closeLb()"
|
||
class="flex-1 min-w-0 min-h-0 relative flex justify-center px-4 sm:px-18"
|
||
x-bind:class="lbZoomed
|
||
? 'overflow-y-auto overflow-x-hidden items-start'
|
||
: 'items-center'"
|
||
>
|
||
<img
|
||
id="lb-image"
|
||
src=""
|
||
alt=""
|
||
@click="toggleZoom()"
|
||
decoding="async"
|
||
class="block select-none transition-opacity duration-200"
|
||
x-bind:class="lbZoomed
|
||
? 'w-full max-w-full h-auto max-h-none cursor-zoom-out'
|
||
: 'max-w-full max-h-full object-contain cursor-zoom-in'"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 各页独有的附加层(走秀页注入「当前 look 的细节图簇」;街拍页不传) */}
|
||
<slot name="details" />
|
||
</div>
|