diff options
| author | Horu <73709188+HigherOrderLogic@users.noreply.github.com> | 2025-08-29 15:31:50 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-29 05:31:50 +0000 |
| commit | 1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f (patch) | |
| tree | 60aa82866d4f3fa0105447419d154c69fba521f1 /niri-config/src | |
| parent | d9833fc1c3de306f500662471ae001094813dbd5 (diff) | |
| download | niri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.tar.gz niri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.tar.bz2 niri-1ffda91e0cc3938af1a9d4f1f1b6a87afa3c210f.zip | |
feat: cubic-bezier curve for animation (#2059)
* feat: bezier curve for animation
* fixes
---------
Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
Diffstat (limited to 'niri-config/src')
| -rw-r--r-- | niri-config/src/animations.rs | 92 | ||||
| -rw-r--r-- | niri-config/src/lib.rs | 11 |
2 files changed, 100 insertions, 3 deletions
diff --git a/niri-config/src/animations.rs b/niri-config/src/animations.rs index 90ff0bf2..d265026e 100644 --- a/niri-config/src/animations.rs +++ b/niri-config/src/animations.rs @@ -69,12 +69,13 @@ pub struct EasingParams { pub curve: Curve, } -#[derive(knuffel::DecodeScalar, Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Curve { Linear, EaseOutQuad, EaseOutCubic, EaseOutExpo, + CubicBezier(f64, f64, f64, f64), } #[derive(Debug, Clone, Copy, PartialEq)] @@ -540,7 +541,94 @@ impl Animation { )); } - easing_params.curve = Some(parse_arg_node("curve", child, ctx)?); + let mut iter_args = child.arguments.iter(); + let val = iter_args.next().ok_or_else(|| { + DecodeError::missing(child, "additional argument `curve` is required") + })?; + let animation_curve_string: String = + knuffel::traits::DecodeScalar::decode(val, ctx)?; + + let animation_curve = match animation_curve_string.as_str() { + "linear" => Some(Curve::Linear), + "ease-out-quad" => Some(Curve::EaseOutQuad), + "ease-out-cubic" => Some(Curve::EaseOutCubic), + "ease-out-expo" => Some(Curve::EaseOutExpo), + "cubic-bezier" => { + let val = iter_args.next().ok_or_else(|| { + DecodeError::missing( + child, + "missing x1 coordinate for cubic Bézier curve control point", + ) + })?; + // the X axis represents time frame so it cannot be negative + // or larger than 1 + let x1: FloatOrInt<0, 1> = + knuffel::traits::DecodeScalar::decode(val, ctx)?; + let val = iter_args.next().ok_or_else(|| { + DecodeError::missing( + child, + "missing y1 coordinate for cubic Bézier curve control point", + ) + })?; + let y1: FloatOrInt<{ i32::MIN }, { i32::MAX }> = + knuffel::traits::DecodeScalar::decode(val, ctx)?; + let val = iter_args.next().ok_or_else(|| { + DecodeError::missing( + child, + "missing x2 coordinate for cubic Bézier curve control point", + ) + })?; + let x2: FloatOrInt<0, 1> = + knuffel::traits::DecodeScalar::decode(val, ctx)?; + let val = iter_args.next().ok_or_else(|| { + DecodeError::missing( + child, + "missing y2 coordinate for cubic Bézier curve control point", + ) + })?; + let y2: FloatOrInt<{ i32::MIN }, { i32::MAX }> = + knuffel::traits::DecodeScalar::decode(val, ctx)?; + + Some(Curve::CubicBezier(x1.0, y1.0, x2.0, y2.0)) + } + unexpected_curve => { + ctx.emit_error(DecodeError::unexpected( + &val.literal, + "argument", + format!( + "unexpected animation curve `{unexpected_curve}`. \ + Niri only supports five animation curves: \ + `ease-out-quad`, `ease-out-cubic`, `ease-out-expo`, `linear` and `cubic-bezier`." + ), + )); + + None + } + }; + + if let Some(val) = iter_args.next() { + ctx.emit_error(DecodeError::unexpected( + &val.literal, + "argument", + "unexpected argument", + )); + } + for name in child.properties.keys() { + ctx.emit_error(DecodeError::unexpected( + name, + "property", + format!("unexpected property `{}`", name.escape_default()), + )); + } + for child in child.children() { + ctx.emit_error(DecodeError::unexpected( + child, + "node", + format!("unexpected node `{}`", child.node_name.escape_default()), + )); + } + + easing_params.curve = animation_curve; } name_str => { if !process_children(child, ctx)? { diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index ce821c5e..8e07839e 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -441,6 +441,10 @@ mod tests { } window-open { off; } + + window-close { + curve "cubic-bezier" 0.05 0.7 0.1 1 + } } gestures { @@ -1038,7 +1042,12 @@ mod tests { kind: Easing( EasingParams { duration_ms: 150, - curve: EaseOutQuad, + curve: CubicBezier( + 0.05, + 0.7, + 0.1, + 1.0, + ), }, ), }, |
