forked from nostr/notecrumbs
add missing file
This commit is contained in:
parent
63899c9c68
commit
74bbdcb27f
84
src/gradient.rs
Normal file
84
src/gradient.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use egui::{lerp, Color32, Pos2, Rgba};
|
||||
|
||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Gradient(pub Vec<Color32>);
|
||||
|
||||
impl Gradient {
|
||||
pub fn linear(left: Color32, right: Color32) -> Self {
|
||||
let left = Rgba::from(left);
|
||||
let right = Rgba::from(right);
|
||||
|
||||
let n = 255;
|
||||
Self(
|
||||
(0..=n)
|
||||
.map(|i| {
|
||||
let t = i as f32 / n as f32;
|
||||
Color32::from(lerp(left..=right, t))
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn radial_alpha_gradient(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_color: Color32,
|
||||
end_color: Color32,
|
||||
) -> Self {
|
||||
let start_color = Rgba::from(start_color);
|
||||
let end_color = Rgba::from(end_color);
|
||||
|
||||
let diameter = (2.0 * radius) as i32;
|
||||
let mut pixels = Vec::new();
|
||||
|
||||
for x in 0..diameter {
|
||||
for y in 0..diameter {
|
||||
let dx = x as f32 - center.x;
|
||||
let dy = y as f32 - center.y;
|
||||
let distance = (dx * dx + dy * dy).sqrt();
|
||||
|
||||
if distance <= radius {
|
||||
let t = (distance / radius).clamp(0.0, 1.0);
|
||||
let tl = (x as f32) / (diameter as f32);
|
||||
let interpolated_color = Color32::from(lerp(start_color..=end_color, tl));
|
||||
let alpha = (1.0 - t).clamp(0.0, 1.0);
|
||||
|
||||
pixels.push(Color32::from_rgba_premultiplied(
|
||||
interpolated_color.r(),
|
||||
interpolated_color.g(),
|
||||
interpolated_color.b(),
|
||||
(alpha * 255.0) as u8,
|
||||
));
|
||||
} else {
|
||||
// Handle pixels outside the circle
|
||||
pixels.push(Color32::DEBUG_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Self(pixels)
|
||||
}
|
||||
|
||||
/// Do premultiplied alpha-aware blending of the gradient on top of the fill color
|
||||
/// in gamma-space.
|
||||
pub fn with_bg_fill(self, bg: Color32) -> Self {
|
||||
Self(
|
||||
self.0
|
||||
.into_iter()
|
||||
.map(|fg| {
|
||||
let a = fg.a() as f32 / 255.0;
|
||||
Color32::from_rgba_premultiplied(
|
||||
(bg[0] as f32 * (1.0 - a) + fg[0] as f32).round() as u8,
|
||||
(bg[1] as f32 * (1.0 - a) + fg[1] as f32).round() as u8,
|
||||
(bg[2] as f32 * (1.0 - a) + fg[2] as f32).round() as u8,
|
||||
(bg[3] as f32 * (1.0 - a) + fg[3] as f32).round() as u8,
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn to_pixel_row(&self) -> Vec<Color32> {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user