Expressions: read bezier curve by position (#1884)

A missing or unusable curve no longer consumes the last value. The long form reads argument 5 and the short form argument 3, with the other arities falling back to linear interpolation. Adds the missing-curve and four-element-array cases reported in review.
This commit is contained in:
Camille Moine committed 2026-10-29 11:58:35 +01:00
1 parent efcdad04af
commit 7038f4f0ee
2 files changed
+13 -6

No files matched your search

+7 -6
View File
@@ -251,13 +251,14 @@ function __cubicBezier(curve) {
}
// bezier(t, tMin, tMax, value1, value2, curve), or bezier(t, value1, value2, curve): the curve is
// the last argument; everything before it follows linear / ease.
// the sixth / fourth argument. Read it by position, not from the end: when it is missing or
// unusable, the interpolation falls back to linear without consuming the last value.
function bezier() {
var curve = arguments[arguments.length - 1];
var shape = __cubicBezier(curve);
var args = [];
for (var i = 0; i < arguments.length - 1; i++) args.push(arguments[i]);
return __interp(shape, args);
var a = arguments, n = a.length;
if (n >= 6) return __interp(__cubicBezier(a[5]), [a[0], a[1], a[2], a[3], a[4]]);
if (n === 5) return __interp(__lin, [a[0], a[1], a[2], a[3], a[4]]);
if (n === 4) return __interp(__cubicBezier(a[3]), [a[0], a[1], a[2]]);
return __interp(__lin, [a[0], a[1], a[2]]);
}
// ---------------------------------------------------------------------------------------------
+6
View File
@@ -343,6 +343,12 @@ fn cubic_bezier_short_form_arrays_and_fallbacks() {
// A curve that is not four finite numbers falls back to linear instead of throwing.
assert_close!(f.num("bezier(0.5, 0, 1, 0, 100, [1, 0])", 0.0), 50.0);
assert_close!(f.num("bezier(0.5, 0, 1, 0, 100, 'ease')", 0.0), 50.0);
// A missing or unusable curve must not consume the last value: read the curve by position.
assert_close!(f.num("bezier(0.5, 0, 1, 0, 100)", 0.0), 50.0);
assert_close!(f.num("bezier(0.5, 0, 100)", 0.0), 50.0);
assert_close!(f.num("bezier(0.5, 0, 100, [1, 0])", 0.0), 50.0);
let v = f.ev(f.shape, "contents/#1/contents/fill/color", "bezier(0.5, 0, 1, [0, 0, 0, 1], [1, 1, 1, 1])", 0.0).unwrap();
assert_eq!(v, Value::Color([0.5, 0.5, 0.5, 1.0]));
// Exactly four values are a curve; extra ones mean the curve is malformed, so linear.
assert_close!(f.num("bezier(0.5, 0, 1, 0, 100, [0.42, 0, 0.58, 1, 0])", 0.0), 50.0);
assert_close!(f.num("bezier(0.5, 0, 1, 0, 100, [0.42, 0, 0.58, 1, 2, 3])", 0.0), 50.0);