mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
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:
@@ -123,10 +123,16 @@ export function EffortPanel({ appStateEffort, onDone }: Props): React.ReactNode
|
||||
Effort
|
||||
</Text>
|
||||
{envActive && <Text color="warning">{`⚠ CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides this session`}</Text>}
|
||||
{rippleActive ? <RippleContent renderRow={renderRippleRow} cursor={cursor} /> : <PlainContent cursor={cursor} />}
|
||||
<Box marginTop={1}>
|
||||
<Text color="subtle">←/→ adjust · Enter confirm · Esc cancel</Text>
|
||||
</Box>
|
||||
{rippleActive ? (
|
||||
<RippleContent renderRow={renderRippleRow} cursor={cursor} />
|
||||
) : (
|
||||
<>
|
||||
<PlainContent cursor={cursor} />
|
||||
<Box marginTop={1}>
|
||||
<Text color="subtle">←/→ adjust · Enter confirm · Esc cancel</Text>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -218,6 +224,11 @@ function RippleContent({ renderRow, cursor }: RippleContentProps): React.ReactNo
|
||||
x: segmentTextStartX(cursorIdx, SUBLABEL_ULTRACODE.length),
|
||||
color: COLOR_LABEL_DEFAULT,
|
||||
};
|
||||
const hintOverlay: Overlay = {
|
||||
text: '←/→ adjust · Enter confirm · Esc cancel',
|
||||
x: 0,
|
||||
color: COLOR_LABEL_DEFAULT,
|
||||
};
|
||||
|
||||
// 各行 y 坐标(相对震源 RIPPLE_SOURCE_Y = 档位名行)
|
||||
// y=-3: Faster/Smarter
|
||||
@@ -225,6 +236,7 @@ function RippleContent({ renderRow, cursor }: RippleContentProps): React.ReactNo
|
||||
// y=-1: ▲
|
||||
// y=0: 档位名(震源)
|
||||
// y=1: 副标签
|
||||
// y=2: 快捷键行(y 方向延伸覆盖到底部)
|
||||
return (
|
||||
<>
|
||||
<RippleRow segments={renderRow(-3, [fasterOverlay, smarterOverlay])} />
|
||||
@@ -232,6 +244,7 @@ function RippleContent({ renderRow, cursor }: RippleContentProps): React.ReactNo
|
||||
<RippleRow segments={renderRow(-1, [cursorOverlay])} />
|
||||
<RippleRow segments={renderRow(0, labelOverlays)} />
|
||||
<RippleRow segments={renderRow(1, [sublabelOverlay])} />
|
||||
<RippleRow segments={renderRow(2, [hintOverlay])} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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=0,falloff=1,intensity 高)', () => {
|
||||
const cells = computeRippleCells({
|
||||
test('震源点 time=0 时为波谷(最暗档),time 推进后出现亮档', () => {
|
||||
// dist=0,time=0 时 phase = -0 = 0,sin(0)=0 → wave=0 → intensity=0 → 最暗档
|
||||
const t0 = computeRippleCells({
|
||||
y: 5,
|
||||
width: 11,
|
||||
time: 0,
|
||||
sourceX: 5,
|
||||
sourceY: 5,
|
||||
})
|
||||
// 震源在 (5,5),dist=0,falloff=1,dist<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)
|
||||
})
|
||||
|
||||
|
||||
@@ -20,14 +20,15 @@
|
||||
* "暗紫蓝海洋"作为底色,波峰在底色上流动。这样波纹颜色变化更明显,
|
||||
* 波谷也有暗色(不会"消失")。
|
||||
*
|
||||
* 波峰最高升到 suggestion (#5769F7),避免与文字 overlay(也用 suggestion 系)
|
||||
* 同色互相吞噬。文字用更亮的高光色(#a3b5ff)保持对比。
|
||||
* 最暗档用 #1a1f3a(紫黑,亮度 ~12%),不是纯黑——避免远端波谷
|
||||
* 看起来像"硬黑边"。波峰最高升到 suggestion (#5769F7),避免与
|
||||
* 文字 overlay(也用 suggestion 系)同色互相吞噬。
|
||||
*/
|
||||
const RIPPLE_COLOR_STOPS = [
|
||||
'#0a0d1a', // 0.00 ~ 0.14 — 最暗,波谷底色
|
||||
'#15182b', // 0.14 ~ 0.28
|
||||
'#1f2543', // 0.28 ~ 0.42
|
||||
'#2a3360', // 0.42 ~ 0.56
|
||||
'#1a1f3a', // 0.00 ~ 0.14 — 最暗(紫黑底色,非纯黑)
|
||||
'#1f2543', // 0.14 ~ 0.28
|
||||
'#252c55', // 0.28 ~ 0.42
|
||||
'#2e3870', // 0.42 ~ 0.56
|
||||
'#3a4582', // 0.56 ~ 0.70
|
||||
'#4a5bb0', // 0.70 ~ 0.84
|
||||
'#5769F7', // 0.84 ~ 1.00 — suggestion (波峰)
|
||||
@@ -37,7 +38,7 @@ const RIPPLE_COLOR_STOPS = [
|
||||
* 强度(任意实数)→ 颜色字符串。
|
||||
*
|
||||
* 钳到 [0, 1],按 RIPPLE_COLOR_STOPS 分级。永不返回 transparent。
|
||||
* intensity=0 → 最暗档(#0a0d1a,作为面板底色)。
|
||||
* intensity=0 → 最暗档(#1a1f3a,作为面板底色)。
|
||||
*/
|
||||
export function intensityToColor(intensity: number): string {
|
||||
const v = intensity < 0 ? 0 : intensity > 1 ? 1 : intensity
|
||||
@@ -98,18 +99,17 @@ const RIPPLE_BG_CHAR = ' '
|
||||
/**
|
||||
* 计算面板某一行 y 的完整波纹 cell 列表。
|
||||
*
|
||||
* 波纹数学(v2 — 调慢 + 扩大覆盖):
|
||||
* 波纹数学(v3 — 简化,移除震源高频涟漪):
|
||||
* dx = x - sourceX
|
||||
* dy = (y - sourceY) * 1.5 (y 方向视觉拉伸,行高 > 字宽)
|
||||
* dist = sqrt(dx² + dy²)
|
||||
* phase = dist * 0.35 - time * 0.004 (速度调慢至原 1/3)
|
||||
* wave = max(0, sin(phase))
|
||||
* falloff = max(0, 1 - dist / 90) (覆盖半径扩到 90,让左侧 dist=65 也可见)
|
||||
* falloff = max(0, 1 - dist / 90) (覆盖半径扩到 90)
|
||||
* intensity = wave * falloff
|
||||
* 震源附近 (dist < 6):叠加高频涟漪 max(intensity, 0.5 + 0.5*sin(time*0.02 - dist*1.2))
|
||||
*
|
||||
* 每位置强度经 intensityToColor → 颜色字符串(永不 transparent),写入 cell。
|
||||
* 即使 intensity=0(波谷)也得到最暗档 #0a0d1a 作为面板底色。
|
||||
* 即使 intensity=0(波谷)也得到最暗档 #1a1f3a 作为面板底色。
|
||||
*
|
||||
* @returns 长度严格等于 width 的 Cell 数组
|
||||
*/
|
||||
@@ -135,13 +135,7 @@ export function computeRippleCells(args: {
|
||||
|
||||
// 距离衰减(覆盖半径扩到 90:原 40)
|
||||
const falloff = Math.max(0, 1 - dist / 90)
|
||||
let intensity = wave * falloff
|
||||
|
||||
// 震源附近高频涟漪
|
||||
if (dist < 6) {
|
||||
const ripple = 0.5 + 0.5 * Math.sin(time * 0.02 - dist * 1.2)
|
||||
if (ripple > intensity) intensity = ripple
|
||||
}
|
||||
const intensity = wave * falloff
|
||||
|
||||
cells[x] = {
|
||||
char: RIPPLE_BG_CHAR,
|
||||
|
||||
Reference in New Issue
Block a user