mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
feat: cubic-bezier curve for animation (#2059)
* feat: bezier curve for animation * fixes --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
@@ -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)? {
|
||||
|
||||
+10
-1
@@ -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,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user