2026 · 0917
日期:2026-09-17 · 类型:站点特效更新(效果 2 背景粒子)· 关联版本:v1.1(当前版本)
首页 / 模型页背景「效果 2」(FlowGridCanvas,纯 Canvas 2D)两项特效更新:① 底层重构为全屏流体渐变——整屏一层连续波动的流体表面(复合物理效果),三八度漂移噪声高度场左右上下随机波动,高度映射多色阶渐变、波动的波峰为顶(波峰 = 最亮色阶),网格骑在流体表面上、波峰顶起网格;② 中层网格 logo 从格子中心移至线条交叉点,logo 周围留半径 15.5px(9.5 + 6)圆形间隙、线条在间隙边缘停住——线条碰不到 logo(6px padding 间隙,可见断开而非遮盖)。
本记录对应 VERSION.md 站点版本线 2026-09-17 的两条特效变更记录(当日先后完成),改动集中于 src/components/particles/FlowGridCanvas.tsx,无规约内容文档变更。
1. 发布内容
1.1 底层:独立流体团 → 全屏流体渐变(复合物理效果)
- 流体高度场:三八度漂移值噪声(大波向右下 / 中波向左上 / 细纹向下方漂移,漂移方向覆盖四向 = 左右上下随机波动),归一化 [0,1](0 = 波谷 → 1 = 波峰);叠加冲击波峰(局部高斯隆起,0.4s 升起后 3.2s 内平滑回落),流体表面周期性「涌起」。
- 波动的波峰为顶:高度映射多色阶渐变,波峰 = 最亮色阶——亮主题 = 香槟金水彩(浅奶油波谷 → 深金波峰,普通混合);暗主题 = 发光液体金(暗金波谷 → 近白高温波峰,加色发光)。
- 渲染路径:低分辨率缓冲(12× 降采样,1440×900 → 120×75)逐像素采样高度场 → 多色阶渐变色映射 → putImageData → 双线性放大全屏 = 平滑流体渐变(无像素颗粒感)。
- 波峰顶起网格:网格线条 / logo 用同一高度场驱动垂直位移(waveLift,幅度 16px)——波峰顶起网格、波谷下拉网格,网格「骑在」流体表面上。
- 冲击 = 表面涌起:大冲击(每 4~9s,随机位置,强度 0.9~1.3 → 顶起网格 + 涟漪位移 + 线条 / logo 点亮 + 冲击环 + 玻璃瞬时变清晰 3px→1.4px→3px)+ 小涟漪(每 5~10s,强度 ~0.3,仅轻微网格扰动、不驱动玻璃清晰)。
1.2 中层:logo 格子中心 → 线条交叉点 + padding 间隙
- 交叉点定位:节点坐标从格子中心(x = cell/2 + i*cell)改为竖线与横线的交点(x = i*cell、y = j*cell);边缘内缩从只处理右 / 下边改为四边,避免 logo 被视口边缘裁切。
- 6px padding 间隙:新增 NODE_PAD = 6;绘制 logo 前用
destination-out擦除每个节点(线条交叉点)周围半径 15.5px(NODE_SIZE/2 + NODE_PAD)的圆,线条在间隙边缘停住,logo 边缘(9.5px)与线条边缘(15.5px)之间留出 6px 间隙——线条碰不到 logo(可见间隙,而非不透明遮盖)。 - 擦除时机与实现要点:在所有线条(基础网格 + 撞击 reveal)绘制之后、logo 绘制之前执行,确保间隙干净切断所有线条;擦除必须用实心(alpha=1)fillStyle——destination-out 按源 alpha 擦除,若用闪光 / 环残留的径向渐变会导致擦除不完整、间隙边缘发虚。
- 其余逻辑不变:logo 统一 19px、source-in 染成与线条同色;常态可见性不变(暗主题线条 0.13 / logo 0.24,亮主题线条 0.10 / logo 0.15);撞击时由 reveal 包络进一步点亮(线条上限 0.7、logo 上限 0.6)。
2. 变更清单(2026-09-17)
| # | 文件 | 变更内容 |
|---|---|---|
| 1 | src/components/particles/FlowGridCanvas.tsx | 移除 Blob/Swirl 流体团数据结构与全部运动逻辑(curl 流场、惯性缓动、速度拉伸、帧间拖尾、边缘淡出);新增 heightField(三八度漂移值噪声 + 冲击高斯隆起)、mapStop(多色阶渐变色映射)、drawField(低分辨率缓冲 + 双线性放大)、waveLift(网格骑在流体表面) |
| 2 | src/components/particles/FlowGridCanvas.tsx | buildGrid 节点坐标改为线条交叉点(x = i*cell、y = j*cell)+ 四边边缘内缩;新增 NODE_PAD = 6,drawGrid 在 logo 绘制前用 destination-out(实心 fillStyle)擦除半径 15.5px 间隙圆,线条在间隙边缘停住 |
| 3 | scripts/incremental-verify.mjs | 粒子探针描述文案从「较大流体」更新为「流体渐变」(检查逻辑不变,仍统计流体画布上的品牌金色像素) |
3. 验证结果
| 项 | 结果 |
|---|---|
| 构建 | pnpm build 通过(新增本页前 182 页);tsc --noEmit 通过;无旧字段(blobs/Swirl/MAX_BLOBS/flowDir/TRAIL_FADE)残留引用 |
| 底层流体渐变 | 95%~97% 屏幕金色覆盖(全屏流体表面);亮主题平均色 (222,189,119) 香槟 / 暗主题平均色 (229,146,7) 发光金;流体场与网格均在动画(两帧 frame-diff hash 不同 = 左右上下随机波动) |
| 网格常态 / 撞击 | 暗主题常态 14.7k 有效可见像素;16s 采样:暗主题 ~15k → 20k~22k(撞击点亮)→ 缓落;亮主题 0 → 9k → 缓落;玻璃 blur 3 → ~2.0 → 3(大冲击瞬时变清晰) |
| logo 交叉点定位 | 以交叉点为中心 40×40 窗口平均金色像素 = 72(logo 在交叉点);以格子中心为中心 = 0(不再在格子中间) |
| padding 间隙 | logo 像素 logoPx = 81~88(logo 存在)/ 间隙环(15.5px 圆内、logo 外)gapRing = 12~15(仅 logo 抗锯齿边缘、无线条)/ 线条区(圆外)lineRegion = 132~133(线条在间隙外恢复) |
| 运行时错误 | 0 JS 错误(首页 / 模型页 × 亮 / 暗四组合探针) |
| 增量验证 | incremental-verify:home-light 5/5、home-dark 4/4、desktop-layout 5/5 + 0 错误(spec-home / width-align / spec-sync 失败为规约区既有问题,与本次无关) |
4. 结论变化
无结论级变化。本日为纯视觉特效更新(效果 2 背景粒子),不影响规约内容版本线与文档结论;另核对暗主题主色与 logo 颜色为同一色(#ffa400),确认维持现状不变。
5. 遗留事项
- 视觉效果确认口径:本记录的效果验证基于像素探针(getImageData,alpha 感知)与计算样式(当前环境无截图能力);实际视觉观感需真实浏览器确认。
- 暗主题导航栏 logo 发光提亮:nav.css 中暗主题 logo 保留 brightness(1.15) 发光效果,显示色略亮于主色 #ffa400,经确认属刻意效果、维持现状。
- 增量验证既有失败项:spec-home / width-align / spec-sync 为规约区既有问题,未在本日处理。
2026 · 0917
Date: 2026-09-17 · Type: site visual-effect update (Effect 2 background particles) · Related version: v1.1 (current)
Two effect updates to the home/model page background "Effect 2" (FlowGridCanvas, pure Canvas 2D): ① the bottom layer was rebuilt as a full-screen fluid gradient — the whole viewport is one continuous undulating fluid surface (a compound physical effect); a 3-octave drifting-noise height field undulates in all four directions, height maps to a multi-stop gradient with the wave crest on top (crest = brightest tone), and the grid rides on the fluid surface with crests lifting the grid; ② the middle-layer grid logo moved from cell centers to line intersections, with a 15.5px-radius (9.5 + 6) circular gap around each logo where lines stop at the gap edge — lines never touch the logo (a 6px padding gap: a visible break, not an opaque cover).
This record corresponds to the two 2026-09-17 effect entries on the site version line in VERSION.md (completed sequentially on the same day). All changes are confined to src/components/particles/FlowGridCanvas.tsx; no spec content documents were changed.
1. What Was Released
1.1 Bottom layer: independent fluid blobs → full-screen fluid gradient (compound physical effect)
- Fluid height field: 3-octave drifting value noise (large waves drift down-right / mid waves up-left / fine ripples downward; drift directions cover all four directions = random undulation in every direction), normalized to [0,1] (0 = trough → 1 = crest); plus impact crests (local Gaussian bulges, rising in 0.4s and settling over 3.2s), so the fluid surface periodically "surges".
- Crest on top: height maps to a multi-stop gradient, crest = brightest tone — light theme = champagne-gold watercolor (light-cream troughs → deep-gold crests, normal blending); dark theme = glowing liquid gold (dark-gold troughs → near-white hot crests, additive glow).
- Render path: a low-resolution buffer (12× downsample, 1440×900 → 120×75) samples the height field per pixel → multi-stop gradient mapping → putImageData → bilinear upscale to full screen = smooth fluid gradient (no pixel grain).
- Crests lift the grid: grid lines / logo use the same height field for vertical displacement (waveLift, amplitude 16px) — crests lift the grid, troughs pull it down; the grid "rides" the fluid surface.
- Impact = surface surge: big impact (every 4–9s, random position, strength 0.9–1.3 → grid lift + ripple displacement + line/logo illumination + impact ring + glass briefly sharpens 3px→1.4px→3px) + small ripples (every 5–10s, strength ~0.3, mild grid perturbation only, does not drive glass clarity).
1.2 Middle layer: logo cell centers → line intersections + padding gap
- Intersection placement: node coordinates moved from cell centers (x = cell/2 + i*cell) to vertical/horizontal line crossings (x = i*cell, y = j*cell); edge insets now apply on all four sides so logos are not clipped by the viewport edge.
- 6px padding gap: new constant NODE_PAD = 6; before drawing logos, a
destination-outpass erases a 15.5px-radius circle (NODE_SIZE/2 + NODE_PAD) around each node, so lines stop at the gap edge — a 6px gap between the logo edge (9.5px) and the line edge (15.5px): lines never touch the logo (a visible gap, not an opaque cover). - Timing and implementation notes: the erase runs after all lines (base grid + impact reveal) are drawn and before logos are drawn, so the gap cleanly cuts every line; the erase must use a solid (alpha=1) fillStyle — destination-out erases by source alpha, and a leftover radial gradient from the flash/ring would make the erase incomplete and the gap edge fuzzy.
- Everything else unchanged: logos stay 19px, tinted to the line color via source-in; rest visibility unchanged (dark theme lines 0.13 / logo 0.24, light theme lines 0.10 / logo 0.15); impacts further brighten via the reveal envelope (line cap 0.7, logo cap 0.6).
2. Change List (2026-09-17)
| # | File | Change |
|---|---|---|
| 1 | src/components/particles/FlowGridCanvas.tsx | Removed the Blob/Swirl fluid-blob data structures and all their motion logic (curl field, inertia easing, velocity stretch, frame trails, edge fade); added heightField (3-octave drifting value noise + impact Gaussian bulges), mapStop (multi-stop gradient mapping), drawField (low-res buffer + bilinear upscale), waveLift (grid rides the fluid surface) |
| 2 | src/components/particles/FlowGridCanvas.tsx | buildGrid node coordinates changed to line intersections (x = i*cell, y = j*cell) with four-side edge insets; added NODE_PAD = 6; drawGrid erases a 15.5px-radius gap circle (destination-out, solid fillStyle) before drawing logos, so lines stop at the gap edge |
| 3 | scripts/incremental-verify.mjs | Particle-probe description updated from "larger fluid" to "fluid gradient" (check logic unchanged — still counts brand-gold pixels on the fluid canvas) |
3. Verification Results
| Item | Result |
|---|---|
| Build | pnpm build passed (182 pages before this page was added); tsc --noEmit passed; no leftover references to removed fields (blobs/Swirl/MAX_BLOBS/flowDir/TRAIL_FADE) |
| Fluid gradient | 95%–97% screen coverage in gold (full-screen fluid surface); light-theme average color (222,189,119) champagne / dark-theme average (229,146,7) glowing gold; fluid field and grid both animate (two-frame diff hashes differ = random undulation in all directions) |
| Grid rest / impact | Dark theme 14.7k effectively visible pixels at rest; 16s sampling: dark ~15k → 20k–22k (impact illumination) → ease-down; light 0 → 9k → ease-down; glass blur 3 → ~2.0 → 3 (big impact briefly sharpens the glass) |
| Logo intersection placement | 40×40 window centered on an intersection: average gold pixels = 72 (logo at the intersection); centered on a cell center: 0 (no longer in cell centers) |
| Padding gap | Logo pixels logoPx = 81–88 (logo present) / gap ring (inside 15.5px circle, outside logo) gapRing = 12–15 (only logo antialiased edges, no lines) / line region (outside circle) lineRegion = 132–133 (lines resume beyond the gap) |
| Runtime errors | 0 JS errors (home/model × light/dark, four combinations) |
| Incremental verify | incremental-verify: home-light 5/5, home-dark 4/4, desktop-layout 5/5 + 0 errors (spec-home / width-align / spec-sync failures are pre-existing spec-area issues, unrelated to this update) |
4. Conclusion Changes
No conclusion-level changes. This is a pure visual-effect update (Effect 2 background particles) and does not affect the spec content version line or any document conclusions; the dark-theme accent color and logo color were cross-checked as the same color (#ffa400) and confirmed to remain as-is.
5. Outstanding Items
- Visual verification basis: the effect verification in this record is based on pixel probes (getImageData, alpha-aware) and computed styles (no screenshot capability in the current environment); the final look needs confirmation in a real browser.
- Dark-theme navbar logo glow: nav.css keeps a brightness(1.15) glow on the dark-theme logo, so its displayed color is slightly brighter than the #ffa400 accent; confirmed as an intentional effect and left as-is.
- Pre-existing verify failures: spec-home / width-align / spec-sync are pre-existing spec-area issues, not addressed today.