This commit is contained in:
@@ -7,10 +7,11 @@
|
||||
* @property {(photoId: number, previewSrc: string) => void} [onUpgradeQuality]
|
||||
* @property {boolean} [borderLess]
|
||||
* @property {boolean} [waterfall]
|
||||
* @property {number} [index]
|
||||
*/
|
||||
|
||||
/** @type {PhotoCardProps} */
|
||||
let { photo, onUpgradeQuality, borderLess = false, waterfall = false } = $props();
|
||||
let { photo, onUpgradeQuality, borderLess = false, waterfall = false, index = 0 } = $props();
|
||||
|
||||
// 使用 $derived 确保响应式更新
|
||||
let previewSrc = $derived(`/api/v1/photo/${photo.id}/preview`);
|
||||
@@ -18,10 +19,13 @@
|
||||
// 根据原始宽高比计算瀑布流显示比例,防止图片加载前容器塌陷
|
||||
let aspectRatioStyle = $derived(
|
||||
waterfall && photo.width && photo.height
|
||||
? `aspect-ratio: ${photo.width} / ${photo.height};`
|
||||
? `${photo.width} / ${photo.height}`
|
||||
: ''
|
||||
);
|
||||
|
||||
// 砖块模式:交错延迟(按网格行顺序);瀑布模式:同时入场(避免列填充顺序与延迟不匹配)
|
||||
let animationDelay = $derived(waterfall ? '0ms' : `${Math.min(index, 20) * 35}ms`);
|
||||
|
||||
function handleMouseEnter() {
|
||||
if (onUpgradeQuality) {
|
||||
onUpgradeQuality(photo.id, previewSrc);
|
||||
@@ -35,8 +39,8 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<a href={resolve(`/photo/${photo.id}`)} class="photo-card" class:photo-card-waterfall={waterfall} class:photo-card-compact-waterfall={borderLess && waterfall}>
|
||||
<div class="photo-wrapper" class:photo-borderless={borderLess} class:photo-waterfall={waterfall} style={aspectRatioStyle}>
|
||||
<a href={resolve(`/photo/${photo.id}`)} class="photo-card" class:photo-card-waterfall={waterfall} class:photo-card-compact-waterfall={borderLess && waterfall} style={`--wf-aspect: ${aspectRatioStyle}; --wf-delay: ${animationDelay};`}>
|
||||
<div class="photo-wrapper" class:photo-borderless={borderLess} class:photo-waterfall={waterfall}>
|
||||
{#if photo.mimeType?.startsWith('video/')}
|
||||
<div class="video-indicator">🎬</div>
|
||||
<div class="photo-placeholder">
|
||||
@@ -65,6 +69,19 @@
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
animation: card-enter 0.35s cubic-bezier(0.4, 0, 0.2, 1) both;
|
||||
animation-delay: var(--wf-delay, 0ms);
|
||||
}
|
||||
|
||||
@keyframes card-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(12px) scale(0.96);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 瀑布流模式:防止卡片被列截断,并添加间距 */
|
||||
@@ -97,7 +114,7 @@
|
||||
|
||||
/* 瀑布流模式:保持原始宽高比 */
|
||||
.photo-waterfall {
|
||||
aspect-ratio: auto;
|
||||
aspect-ratio: var(--wf-aspect, auto);
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -136,7 +153,6 @@
|
||||
/* 瀑布流模式下 placeholder 默认 4:3 */
|
||||
.photo-waterfall .photo-placeholder {
|
||||
aspect-ratio: 4/3;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.video-indicator {
|
||||
|
||||
@@ -40,11 +40,13 @@
|
||||
<Empty message={m.no_photos()} icon="📷" />
|
||||
{:else}
|
||||
<div class="photo-scroll-container" bind:this={scrollContainer}>
|
||||
{#key waterfall + '_' + borderLess}
|
||||
<div class="photo-grid" class:photo-grid-borderless={borderLess} class:photo-grid-waterfall={waterfall}>
|
||||
{#each getVisiblePhotos() as photo (photo.id)}
|
||||
<PhotoCard {photo} {onUpgradeQuality} {borderLess} {waterfall} />
|
||||
{#each getVisiblePhotos() as photo, i (photo.id)}
|
||||
<PhotoCard {photo} {onUpgradeQuality} {borderLess} {waterfall} index={i} />
|
||||
{/each}
|
||||
</div>
|
||||
{/key}
|
||||
|
||||
{#if isLoading}
|
||||
<div class="loading-trigger">
|
||||
|
||||
Reference in New Issue
Block a user