fix(effort): 波纹 v3 — 去黑边 + 删中心高频涟漪 + y 轴覆盖快捷键行

用户反馈三个问题:
1. "黑色边感觉不太对" — 最暗档 #0a0d1a (rgb 10,13,26) 太接近纯黑,
   远端波谷看起来像硬黑边。改为 #1a1f3a (rgb 26,31,58),紫蓝感
   更强而非纯黑。
2. "中心的快速波纹有点奇怪" — 删除震源附近 dist<6 的高频涟漪叠加
   (time*0.02,5 倍主波纹频率)。原本想让震源附近"水波感"更强,
   实际效果像"快速闪烁"反而突兀。主波纹已经足够,无需叠加。
3. "y 方向覆盖快捷键" — RippleContent 新增 y=2 行渲染快捷键 overlay
   ("←/→ adjust · Enter confirm · Esc cancel")。PlainContent 路径
   保持原 Box marginTop=1 + Text 渲染。

色阶调整(紫蓝感更强):
- #1a1f3a (原 #0a0d1a) — 最暗档
- #1f2543 / #252c55 / #2e3870 / #3a4582 / #4a5bb0 / #5769F7
  (中间档略调亮度,保持平滑过渡)

测试:震源点测试更新为"time=0 时波谷最暗,time 推进后扫过波峰变亮",
反映删除高频涟漪后的纯主波纹行为。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-06-14 15:25:00 +08:00
parent ac348a2b6a
commit 490714dbcb
3 changed files with 46 additions and 30 deletions

View File

@@ -11,11 +11,11 @@ import {
describe('intensityToColor', () => {
test('intensity=0 → 最暗档(不再是 transparent作面板底色', () => {
expect(intensityToColor(0)).toBe('#0a0d1a')
expect(intensityToColor(0)).toBe('#1a1f3a')
})
test('intensity < 0 钳到 0 → 最暗档', () => {
expect(intensityToColor(-0.5)).toBe('#0a0d1a')
expect(intensityToColor(-0.5)).toBe('#1a1f3a')
})
test('intensity > 0 → 永远是 #hex 颜色字符串(不返回 transparent', () => {
@@ -95,17 +95,26 @@ describe('computeRippleCells', () => {
).toEqual([])
})
test('震源点处颜色为最亮档dist=0falloff=1intensity 高)', () => {
const cells = computeRippleCells({
test('震源点 time=0 时为波谷最暗档time 推进后出现亮档', () => {
// dist=0time=0 时 phase = -0 = 0sin(0)=0 → wave=0 → intensity=0 → 最暗档
const t0 = computeRippleCells({
y: 5,
width: 11,
time: 0,
sourceX: 5,
sourceY: 5,
})
// 震源在 (5,5)dist=0falloff=1dist<6 触发高频涟漪叠加
// 波峰附近颜色应较高档(非最暗)
expect(cells[5].color).not.toBe('#0a0d1a')
expect(t0[5].color).toBe('#1a1f3a')
// time 推进phase 变化,震源会扫过波峰
const t1 = computeRippleCells({
y: 5,
width: 11,
time: 1500,
sourceX: 5,
sourceY: 5,
})
expect(t1[5].color).not.toBe('#1a1f3a')
})
test('覆盖半径扩大dist=65左侧远端仍有非最暗颜色', () => {
@@ -132,7 +141,7 @@ describe('computeRippleCells', () => {
sourceX: 65,
sourceY: 0,
})
const nonDarkest = t1.filter(c => c.color !== '#0a0d1a')
const nonDarkest = t1.filter(c => c.color !== '#1a1f3a')
expect(nonDarkest.length).toBeGreaterThan(0)
})