fix(ui-gpui): color interpolation instead of alpha (GPUI ignores alpha on bg)

This commit is contained in:
Hibryda 2026-03-19 08:03:24 +01:00
parent 573105eae6
commit 18cfe7979c

View file

@ -46,37 +46,46 @@ impl PulsingDot {
}
}
fn current_opacity(&self) -> f32 {
/// Interpolate between the bright color and background (SURFACE0) based on sine wave
fn current_color(&self) -> Rgba {
let base = self.base_color();
if !self.should_pulse() {
return 1.0;
return base;
}
let elapsed = self.start_time.elapsed().as_secs_f32();
// Sine wave: 2s period, oscillates between 0.4 and 1.0
0.7 + 0.3 * (elapsed * std::f32::consts::PI).sin()
// t oscillates 0.0 (bright) to 1.0 (dim) with 2s period
let t = 0.5 - 0.5 * (elapsed * std::f32::consts::PI).sin();
// Lerp between base color and SURFACE0 (background)
let bg = theme::SURFACE0;
Rgba {
r: base.r + (bg.r - base.r) * t,
g: base.g + (bg.g - base.g) * t,
b: base.b + (bg.b - base.b) * t,
a: 1.0,
}
}
}
impl Render for PulsingDot {
fn render(&mut self, window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
let base = self.base_color();
let alpha = self.current_opacity();
let color = self.current_color();
// Schedule next frame if pulsing — this is how GPUI does continuous animation
// Schedule next frame if pulsing
if self.should_pulse() {
window.request_animation_frame();
}
let r = (base.r * 255.0) as u32;
let g = (base.g * 255.0) as u32;
let b = (base.b * 255.0) as u32;
let a = (alpha * 255.0) as u32;
let color = rgba(r * 0x1000000 + g * 0x10000 + b * 0x100 + a);
let r = (color.r * 255.0) as u32;
let g = (color.g * 255.0) as u32;
let b = (color.b * 255.0) as u32;
let hex = rgba(r * 0x1000000 + g * 0x10000 + b * 0x100 + 0xFF);
div()
.w(px(self.size))
.h(px(self.size))
.rounded(px(self.size / 2.0))
.bg(color)
.bg(hex)
.flex_shrink_0()
}
}