本文档描述了照片页面的当前实现。
当前文件结构h2
src/pages/photos/index.astro- 从
PHOTOS_CONFIG读取页面文本 - 从
PhotosList读取时间线数据
- 从
src/config.ts- 存储
PHOTOS_CONFIG
- 存储
src/lib/photos.ts- 存储
PhotosList - 自动导入照片文件
- 将一个文件夹的图片转换为
Photo[],使用getPhotos()
- 存储
src/types.ts- 定义
PhotoData、Photo和PolaroidVariant
- 定义
src/components/photos/PolaroidCard.tsx- 将每个
variant映射到实际的卡片尺寸
- 将每个
页面文本h2
页面标题和介绍文本来自 src/config.ts。
export const PHOTOS_CONFIG: PhotosConfig = { title: 'Photos', description: 'Here I will record some photos taken in daily life.', introduce: 'Here I will record some photos taken in daily life.',}src/pages/photos/index.astro renders the page like this:
---import { PHOTOS_CONFIG } from '~/config'import { PhotosList } from '~/lib/photos'
const { title, description, introduce } = PHOTOS_CONFIG---
<Layout {title} {description}> <PageTitle {title} {introduce} /> <PhotoTimeline photoData={PhotosList} /></Layout>PhotosListh2
PhotosList 在 src/lib/photos.ts 中定义。每一项是一个时间线条目。
export const PhotosList: PhotoData[] = [ { title: 'Ningbo - Botanical Garden', icon: { type: 'emoji', value: '🌼' }, description: 'It was early spring, so I went to see the cherry blossoms.', date: '2026-03-07', travel: '', photos: getPhotos('2026-03-07-botanicalGarden', 'Early spring cherry blossoms at the botanical garden', [ '3x4', '3x4', '3x4', '3x4', '3x4', '3x4', ]), },]PhotoData 字段h3
| 字段 | 含义 |
|---|---|
title | 时间线标题 |
icon | 左侧时间线图标 |
description | 可选的时间线描述 |
date | 时间线日期 |
travel | 可选的额外标签 |
photos | Photo 对象数组 |
getPhotos() 的工作原理h2
当前实现:
function getPhotos(dir: string, alt: string, variants: PolaroidVariant[]): Photo[] { return Object.entries(photoModules) .filter(([path]) => path.includes(`/${dir}/`)) .sort(([a], [b]) => a.localeCompare(b)) .map(([, mod], index) => { const img = mod.default return { src: img, alt, width: img.width, height: img.height, variant: variants[index] || '4x3', } })}参数含义h3
| 参数 | 含义 |
|---|---|
dir | src/assets/photos 下的文件夹名称 |
alt | 从该文件夹返回的每张图片的共享 alt 文本 |
variants | 与排序后的图片按索引匹配的比率列表 |
重要行为h3
getPhotos()首先按文件夹名称过滤所有导入的图片。- 然后使用
localeCompare对匹配的文件路径进行排序。 - 按排序顺序创建最终的
Photo[]。 variants[index]应用于相同索引的图片。- 如果
variants中缺少某个索引,该图片将回退到'4x3'。
第三个参数如何匹配h3
第三个参数不是随机元数据。它是基于位置的。
对于以下代码:
photos: getPhotos('2026-03-07-botanicalGarden', 'Early spring cherry blossoms at the botanical garden', [ '3x4', '3x4', '3x4', '3x4', '3x4', '3x4',])假设文件夹 src/assets/photos/2026-03-07-botanicalGarden/ 排序后包含以下文件:
01.webp02.webp03.webp04.webp05.webp06.webp那么映射关系是:
| 文件 | 应用的比例 |
|---|---|
01.webp | 数组第一个元素 -> 3x4 |
02.webp | 数组第二个元素 -> 3x4 |
03.webp | 数组第三个元素 -> 3x4 |
04.webp | 数组第四个元素 -> 3x4 |
05.webp | 数组第五个元素 -> 3x4 |
06.webp | 数组第六个元素 -> 3x4 |
因此,如果你想让文件夹中的第一张照片使用 3x4,第三个数组的第一个元素必须是 3x4。
如果你想混合比例,请按照排序文件的相同顺序编写:
photos: getPhotos('2025-03-01-dongqianhu', 'Ningbo - Dongqian Lake', ['4x5', '1x1', '4x3'])这意味着:
- 第一张排序后的图片 ->
4x5 - 第二张排序后的图片 ->
1x1 - 第三张排序后的图片 ->
4x3
如果文件夹中的照片多于数组长度:
photos: getPhotos('example-folder', 'Example alt', ['3x4', '4x5'])那么:
- 第一张排序后的图片 ->
3x4 - 第二张排序后的图片 ->
4x5 - 第三张及之后的图片 -> 默认
4x3
支持的比例h2
当前 PolaroidVariant 为:
export type PolaroidVariant = '1x1' | '4x5' | '4x3' | '3x4' | '9x16'src/components/photos/PolaroidCard.tsx 中的当前尺寸映射:
const polaroidVariants: Record<PolaroidVariant, string> = { '1x1': 'w-20 h-20', '4x5': 'w-20 h-24', '4x3': 'w-20 h-16', '3x4': 'w-[4.5rem] h-24', '9x16': 'w-20 h-32',}如何添加新的时间线条目h2
- 在
src/assets/photos/下创建一个文件夹,例如2026-04-01-spring-walk。 - 将图片文件放入该文件夹。
- 确保文件名按照排序后的顺序排列。
- 在
src/lib/photos.ts中向PhotosList添加一项。 - 将第三个参数按照排序文件的相同顺序传递给
getPhotos()。
示例:
{ title: 'Spring Walk', icon: { type: 'emoji', value: '🌿' }, description: 'A short walk with a camera.', date: '2026-04-01', travel: '', photos: getPhotos( '2026-04-01-spring-walk', 'Photos from a spring walk', ['3x4', '4x3', '4x5', '4x3'] ),}注意事项h2
alt应用于从同一文件夹返回的每张照片。- 顺序由排序后的文件路径决定,而不是编辑器中的导入顺序。
- 如果重命名文件,排序顺序可能会改变,
variants数组将映射到不同的照片。
Comments