Skip to content

Commit 490714d

Browse files
claude-code-bestglm-5.2
andcommitted
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>
1 parent ac348a2 commit 490714d

3 files changed

Lines changed: 46 additions & 30 deletions

File tree

src/components/EffortPanel/EffortPanel.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,16 @@ export function EffortPanel({ appStateEffort, onDone }: Props): React.ReactNode
123123
Effort
124124
</Text>
125125
{envActive && <Text color="warning">{`⚠ CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides this session`}</Text>}
126-
{rippleActive ? <RippleContent renderRow={renderRippleRow} cursor={cursor} /> : <PlainContent cursor={cursor} />}
127-
<Box marginTop={1}>
128-
<Text color="subtle">←/→ adjust · Enter confirm · Esc cancel</Text>
129-
</Box>
126+
{rippleActive ? (
127+
<RippleContent renderRow={renderRippleRow} cursor={cursor} />
128+
) : (
129+
<>
130+
<PlainContent cursor={cursor} />
131+
<Box marginTop={1}>
132+
<Text color="subtle">←/→ adjust · Enter confirm · Esc cancel</Text>
133+
</Box>
134+
</>
135+
)}
130136
</Box>
131137
);
132138
}
@@ -218,20 +224,27 @@ function RippleContent({ renderRow, cursor }: RippleContentProps): React.ReactNo
218224
x: segmentTextStartX(cursorIdx, SUBLABEL_ULTRACODE.length),
219225
color: COLOR_LABEL_DEFAULT,
220226
};
227+
const hintOverlay: Overlay = {
228+
text: '←/→ adjust · Enter confirm · Esc cancel',
229+
x: 0,
230+
color: COLOR_LABEL_DEFAULT,
231+
};
221232

222233
// 各行 y 坐标(相对震源 RIPPLE_SOURCE_Y = 档位名行)
223234
// y=-3: Faster/Smarter
224235
// y=-2: 分隔线
225236
// y=-1: ▲
226237
// y=0: 档位名(震源)
227238
// y=1: 副标签
239+
// y=2: 快捷键行(y 方向延伸覆盖到底部)
228240
return (
229241
<>
230242
<RippleRow segments={renderRow(-3, [fasterOverlay, smarterOverlay])} />
231243
<RippleRow segments={renderRow(-2, [separatorOverlay])} />
232244
<RippleRow segments={renderRow(-1, [cursorOverlay])} />
233245
<RippleRow segments={renderRow(0, labelOverlays)} />
234246
<RippleRow segments={renderRow(1, [sublabelOverlay])} />
247+
<RippleRow segments={renderRow(2, [hintOverlay])} />
235248
</>
236249
);
237250
}

src/components/EffortPanel/__tests__/rippleAnimation.test.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import {
1111

1212
describe('intensityToColor', () => {
1313
test('intensity=0 → 最暗档(不再是 transparent,作面板底色)', () => {
14-
expect(intensityToColor(0)).toBe('#0a0d1a')
14+
expect(intensityToColor(0)).toBe('#1a1f3a')
1515
})
1616

1717
test('intensity < 0 钳到 0 → 最暗档', () => {
18-
expect(intensityToColor(-0.5)).toBe('#0a0d1a')
18+
expect(intensityToColor(-0.5)).toBe('#1a1f3a')
1919
})
2020

2121
test('intensity > 0 → 永远是 #hex 颜色字符串(不返回 transparent)', () => {
@@ -95,17 +95,26 @@ describe('computeRippleCells', () => {
9595
).toEqual([])
9696
})
9797

98-
test('震源点处颜色为最亮档(dist=0,falloff=1,intensity 高)', () => {
99-
const cells = computeRippleCells({
98+
test('震源点 time=0 时为波谷(最暗档),time 推进后出现亮档', () => {
99+
// dist=0,time=0 时 phase = -0 = 0,sin(0)=0 → wave=0 → intensity=0 → 最暗档
100+
const t0 = computeRippleCells({
100101
y: 5,
101102
width: 11,
102103
time: 0,
103104
sourceX: 5,
104105
sourceY: 5,
105106
})
106-
// 震源在 (5,5),dist=0,falloff=1,dist<6 触发高频涟漪叠加
107-
// 波峰附近颜色应较高档(非最暗)
108-
expect(cells[5].color).not.toBe('#0a0d1a')
107+
expect(t0[5].color).toBe('#1a1f3a')
108+
109+
// time 推进,phase 变化,震源会扫过波峰
110+
const t1 = computeRippleCells({
111+
y: 5,
112+
width: 11,
113+
time: 1500,
114+
sourceX: 5,
115+
sourceY: 5,
116+
})
117+
expect(t1[5].color).not.toBe('#1a1f3a')
109118
})
110119

111120
test('覆盖半径扩大:dist=65(左侧远端)仍有非最暗颜色', () => {
@@ -132,7 +141,7 @@ describe('computeRippleCells', () => {
132141
sourceX: 65,
133142
sourceY: 0,
134143
})
135-
const nonDarkest = t1.filter(c => c.color !== '#0a0d1a')
144+
const nonDarkest = t1.filter(c => c.color !== '#1a1f3a')
136145
expect(nonDarkest.length).toBeGreaterThan(0)
137146
})
138147

src/components/EffortPanel/rippleAnimation.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
* "暗紫蓝海洋"作为底色,波峰在底色上流动。这样波纹颜色变化更明显,
2121
* 波谷也有暗色(不会"消失")。
2222
*
23-
* 波峰最高升到 suggestion (#5769F7),避免与文字 overlay(也用 suggestion 系)
24-
* 同色互相吞噬。文字用更亮的高光色(#a3b5ff)保持对比。
23+
* 最暗档用 #1a1f3a(紫黑,亮度 ~12%),不是纯黑——避免远端波谷
24+
* 看起来像"硬黑边"。波峰最高升到 suggestion (#5769F7),避免与
25+
* 文字 overlay(也用 suggestion 系)同色互相吞噬。
2526
*/
2627
const RIPPLE_COLOR_STOPS = [
27-
'#0a0d1a', // 0.00 ~ 0.14 — 最暗,波谷底色
28-
'#15182b', // 0.14 ~ 0.28
29-
'#1f2543', // 0.28 ~ 0.42
30-
'#2a3360', // 0.42 ~ 0.56
28+
'#1a1f3a', // 0.00 ~ 0.14 — 最暗(紫黑底色,非纯黑)
29+
'#1f2543', // 0.14 ~ 0.28
30+
'#252c55', // 0.28 ~ 0.42
31+
'#2e3870', // 0.42 ~ 0.56
3132
'#3a4582', // 0.56 ~ 0.70
3233
'#4a5bb0', // 0.70 ~ 0.84
3334
'#5769F7', // 0.84 ~ 1.00 — suggestion (波峰)
@@ -37,7 +38,7 @@ const RIPPLE_COLOR_STOPS = [
3738
* 强度(任意实数)→ 颜色字符串。
3839
*
3940
* 钳到 [0, 1],按 RIPPLE_COLOR_STOPS 分级。永不返回 transparent。
40-
* intensity=0 → 最暗档(#0a0d1a,作为面板底色)。
41+
* intensity=0 → 最暗档(#1a1f3a,作为面板底色)。
4142
*/
4243
export function intensityToColor(intensity: number): string {
4344
const v = intensity < 0 ? 0 : intensity > 1 ? 1 : intensity
@@ -98,18 +99,17 @@ const RIPPLE_BG_CHAR = ' '
9899
/**
99100
* 计算面板某一行 y 的完整波纹 cell 列表。
100101
*
101-
* 波纹数学(v2调慢 + 扩大覆盖):
102+
* 波纹数学(v3简化,移除震源高频涟漪):
102103
* dx = x - sourceX
103104
* dy = (y - sourceY) * 1.5 (y 方向视觉拉伸,行高 > 字宽)
104105
* dist = sqrt(dx² + dy²)
105106
* phase = dist * 0.35 - time * 0.004 (速度调慢至原 1/3)
106107
* wave = max(0, sin(phase))
107-
* falloff = max(0, 1 - dist / 90) (覆盖半径扩到 90,让左侧 dist=65 也可见
108+
* falloff = max(0, 1 - dist / 90) (覆盖半径扩到 90)
108109
* intensity = wave * falloff
109-
* 震源附近 (dist < 6):叠加高频涟漪 max(intensity, 0.5 + 0.5*sin(time*0.02 - dist*1.2))
110110
*
111111
* 每位置强度经 intensityToColor → 颜色字符串(永不 transparent),写入 cell。
112-
* 即使 intensity=0(波谷)也得到最暗档 #0a0d1a 作为面板底色。
112+
* 即使 intensity=0(波谷)也得到最暗档 #1a1f3a 作为面板底色。
113113
*
114114
* @returns 长度严格等于 width 的 Cell 数组
115115
*/
@@ -135,13 +135,7 @@ export function computeRippleCells(args: {
135135

136136
// 距离衰减(覆盖半径扩到 90:原 40)
137137
const falloff = Math.max(0, 1 - dist / 90)
138-
let intensity = wave * falloff
139-
140-
// 震源附近高频涟漪
141-
if (dist < 6) {
142-
const ripple = 0.5 + 0.5 * Math.sin(time * 0.02 - dist * 1.2)
143-
if (ripple > intensity) intensity = ripple
144-
}
138+
const intensity = wave * falloff
145139

146140
cells[x] = {
147141
char: RIPPLE_BG_CHAR,

0 commit comments

Comments
 (0)