134 件奶龙主题艺术作品,五大展厅,一次策展式浏览。 线上地址:https://nailong-studio.github.io/website/
上一版是 Vite + glightbox 的单页画廊,存在两个线上缺陷(灯箱大图 404、家族导航链接 404), 本站为按重构计划 v2.0 的完整重写:Astro 静态站 + 构建期内容管线 + 零运行时依赖的交互层。
浏览器路线(全部作品页,滚动浏览):
作品墙总览(134 张缩略图拼成的墙,缓慢拉远):
WebP 动图(GitHub 可直接播放);GIF 兼容版用
DEMO_GIF=1 npm run demo:wall/DEMO_GIF=1 npm run demo:scroll本地生成。 静态总览海报:docs/artworks-wall.jpg;验收拼版:桌面 / 移动与状态。
- 零框架运行时:Astro 默认输出纯 HTML,交互(灯箱 / 筛选 / 主题 / 专注模式)用一个约 9KB 的原生 TS 脚本搞定。
- 构建期内容管线:扫描 134 件作品的清单,自动生成 slug、主色、LQIP 模糊占位、CDN 多档 srcset,构建产物不含原图(原图走 CDN)。
- 图片策略:缩略图本地 WebP(400px),大图走 wsrv.nl 按
640/1024/1600/2048四档 WebP 转码,loading=lazy+fetchpriority分级,宽高比占位防 CLS。 - 无障碍与体感:
prefers-reduced-motion全量降级、一键专注模式(关动效与装饰层,不改变用户选定的深浅色)、键盘可达灯箱、语义化标题层级;深/浅两套配色均通过 axe-core 对比度检查。 - 质量门禁:内容校验 + 单元测试 + 类型检查 + 构建产物链接自检 + 体积预算,全部进 CI。
src/
data/
site.json # 站点配置(base/title/仓库地址)——单一事实源
gallery.json # 原始作品清单(134 条,来自旧站,保持兼容)
artworks.meta.json # 人工策展覆盖(标题/故事/标签/精选)
themes.json # 五大展厅定义(slogan/描述/主色)
manifest.json # 构建产物:由脚本生成,勿手改
lib/ # url()、作品查询、类型定义
layouts/BaseLayout.astro
components/ # Nav / Hero / ThemeRail / FilterBar / MasonryGrid / ArtCard / Lightbox / Footer
pages/
index.astro # 首页:滚动叙事 Hero + 展厅索引 + 编辑精选
gallery/index.astro # 全部作品(含即时筛选)
gallery/[category].astro # 单展厅
artwork/[category]/[slug].astro # 作品详情(143 页之一,可分享)
about.astro / 404.astro
scripts/site.ts # 交互层(原生 TS,无依赖)
scripts/
build-artworks.mjs # 内容管线:清单 → manifest.json(slug/主色/LQIP/CDN srcset)
verify-content.mjs # 内容校验:数量/唯一性/字段/缩略图存在
check-links.mjs # 构建产物自检:内部链接与缩略图必须命中
make-wall-demo.mjs # 生成 docs/demo-wall.webp(作品墙拉远动图,仅需 sharp)
make-scroll-demo.mjs # 生成 docs/demo-scroll.webp(画廊滚动动图,需 puppeteer-core)
docs/ # 动图与验收截图(README 引用)
public/thumbs/… # 134 张 400px WebP 缩略图(提交入库)
npm install # 安装依赖(Node ≥ 20.3)
npm run dev # 本地开发 http://localhost:4321/website/
npm run build # 内容管线 + 校验 + 构建 + 链接自检 → dist/
npm run test # Vitest 单元测试(数据完整性 / 过滤 / 链接构造)
npm run lint # tsc --noEmit 类型检查
npm run content:verify # 只跑内容校验
npm run check # 内容校验 + 测试 + 类型检查(CI 同款)
npm run preview # 预览构建产物
npm run demo:wall # 生成作品墙总览动图(仅需 sharp)
npm run demo:scroll # 生成画廊滚动动图(需 DevDep: puppeteer-core + PUPPETEER_CHROME)推送到 main 后由 GitHub Actions 自动部署到 GitHub Pages:
.github/workflows/ci.yml:内容校验 → 测试 → 类型检查 → 构建 → 体积预算(JS ≤ 64KB / CSS ≤ 48KB)→ 上传 dist 构件。.github/workflows/deploy.yml:同样的校验步骤 +upload-pages-artifact+deploy-pages(需仓库 Settings → Pages → Source 选 GitHub Actions)。
本站按子路径部署,base 只在 src/data/site.json 里定义一次,astro.config.mjs 与 src/lib/url.ts 都读它 —— 改域名/子路径只动一个文件。
scripts/build-artworks.mjs读src/data/gallery.json+src/data/artworks.meta.json。- 从文件名解析标题与变体(如
孤独奶龙主义_10s.png→ 标题「孤独奶龙主义」/ 变体「10s」),生成 URL 安全 slug 与中文标题。 - 用 sharp 从本地缩略图算出主色与 24px LQIP(base64,缓存于
.cache/,幂等)。 - 组装 CDN 多档
srcset(wsrv.nl + raw.githubusercontent.com),输出src/data/manifest.json。 verify-content.mjs断言数量、slug 唯一性、字段合法性、缩略图存在;check-links.mjs在构建后复查所有内部链接。
新增作品:把图丢进 wallpaper 仓 对应分类目录,本地生成 400px WebP 缩略图放进 public/thumbs/<分类>/,更新 gallery.json,跑 npm run build。
| 项 | 结果 |
|---|---|
| 构建 | 143 页,dist 6.4 MB(不含 CDN 原图) |
| 内容校验 | 134 件作品、134 张缩略图、分类计数一致 |
| 内部链接自检 | 280 个唯一目标,0 缺失 |
| 单元测试 / 类型 | Vitest 11/11,tsc --noEmit 无错 |
| 体积预算 | JS 5.0 KB(≤ 64 KB)· CSS 14.9 KB(≤ 48 KB) |
| 真机渲染(headless Chrome 153) | 6 条路由 × 深浅主题:0 console error / 0 断图 / 0 横向溢出 |
| 无障碍(axe-core 4.10.2) | 6 路由(含两页浅色)violations = 0,passes 34–37 |
复测要点:截图/扫描必须 setCacheEnabled(false) 并清 localStorage,否则会拿到旧 CSS 或继承的专注模式状态导致误报。
- 图库原图约 280 MB,继续走 CDN 不入构建产物;如需完全自托管,建议接 Cloudflare Images 或对象存储。
- 详情页「深缩放」浏览、WebGL 展陈(Three.js)为计划中的下一阶段,当前以 2D canvas Hero 与原生灯箱打底。
- Lighthouse 未纳入门禁:容器内 0–100 分依赖真实网络到 CDN,噪声大;CI 暂以体积预算 + 链接自检 + 内容校验作为回归面,axe 已用本地 headless Chrome 跑通但未进 CI。
- 中文正文换行与首屏字体:当前依赖系统字体回退,后续可自托管 Inter + 子集化中文字体(需评估体积)。
- 缩略图为 400 px 单档,未出 2x srcset(4K 屏偏软)。
- 主仓:Nailong-Studio/NaiLong-Universe — palette.json 单源 + 主题
- 壁纸库:Nailong-Studio/wallpaper — 134 张原图
- VSCode 主题:Nailong-Studio/nailong-vscode-theme

