T00 foundation: theme, motion, assets, icon, buttons, gallery
Theme tokens in light and dark with high contrast, a palette cross-fade, motion curves and a damped spring, embedded Lucide icons with Inter and JetBrains Mono, Icon, Button, IconButton, and a gallery that captures its own window. Reviewed by codex gpt-6-astra (max): PASS in round 3.
This commit is contained in:
258 files changed
+16908
No files matched your search
@@ -0,0 +1,78 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gpui::App;
|
||||
|
||||
use crate::theme::ActiveTheme;
|
||||
|
||||
pub const FAST: Duration = Duration::from_millis(120);
|
||||
pub const BASE: Duration = Duration::from_millis(200);
|
||||
pub const SLOW: Duration = Duration::from_millis(320);
|
||||
pub const THEME: Duration = Duration::from_millis(280);
|
||||
|
||||
const DAMPING: f32 = 0.75;
|
||||
const OMEGA: f32 = 6.91 / DAMPING;
|
||||
|
||||
/// `base`, or one millisecond under reduced motion.
|
||||
pub fn duration(base: Duration, cx: &App) -> Duration {
|
||||
if cx.theme().reduced_motion {
|
||||
Duration::from_millis(1)
|
||||
} else {
|
||||
base
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lerp(from: f32, to: f32, t: f32) -> f32 {
|
||||
from + (to - from) * t
|
||||
}
|
||||
|
||||
pub fn ease_out_cubic(t: f32) -> f32 {
|
||||
1.0 - (1.0 - t).powi(3)
|
||||
}
|
||||
|
||||
pub fn ease_in_out_cubic(t: f32) -> f32 {
|
||||
if t < 0.5 {
|
||||
4.0 * t * t * t
|
||||
} else {
|
||||
1.0 - (-2.0 * t + 2.0).powi(3) / 2.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Damped spring. Overshoots; not a gpui easing.
|
||||
pub fn spring(t: f32) -> f32 {
|
||||
if t >= 1.0 {
|
||||
return 1.0;
|
||||
}
|
||||
let damped = OMEGA * (1.0 - DAMPING * DAMPING).sqrt();
|
||||
let decay = (-DAMPING * OMEGA * t).exp();
|
||||
1.0 - decay * ((damped * t).cos() + DAMPING * OMEGA / damped * (damped * t).sin())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn easings_pin_their_ends() {
|
||||
for ease in [ease_out_cubic, ease_in_out_cubic, spring] {
|
||||
assert!(ease(0.0).abs() < 1e-6);
|
||||
assert_eq!(ease(1.0), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spring_overshoots_a_little_then_settles() {
|
||||
let peak = (0..=100)
|
||||
.map(|i| spring(i as f32 / 100.0))
|
||||
.fold(0.0, f32::max);
|
||||
assert!(peak > 1.01 && peak < 1.05, "peak {peak}");
|
||||
assert!((spring(0.95) - 1.0).abs() < 0.01);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ease_in_out_is_symmetric() {
|
||||
for i in 0..=10 {
|
||||
let t = i as f32 / 10.0;
|
||||
assert!((ease_in_out_cubic(t) + ease_in_out_cubic(1.0 - t) - 1.0).abs() < 1e-5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mod curve;
|
||||
|
||||
pub use curve::*;
|
||||
Reference in new issue
Block a user