1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Evenly spaced ramp samples.
//!
//! Mirrors culori 4.0.2's `samples.js`:
//!
//! ```js
//! const samples = (n = 2, γ = 1) => {
//! let ease = gamma(γ);
//! if (n < 2) {
//! return n < 1 ? [] : [ease(0.5)];
//! }
//! let res = [];
//! for (let i = 0; i < n; i++) {
//! res.push(ease(i / (n - 1)));
//! }
//! return res;
//! };
//! ```
//!
//! [`samples`] keeps the linear (γ = 1) shorthand for backwards compatibility.
//! [`samples_with_easing`] takes any `Fn(f64) -> f64`, letting callers plug in
//! [`crate::easing_gamma`], smoothstep, or a custom curve.
/// Returns `n` evenly spaced values in `[0, 1]` (linear, γ = 1).
///
/// Edge cases (matching culori exactly):
/// - `n == 0` returns an empty vector.
/// - `n == 1` returns `[0.5]`.
/// - `n >= 2` returns `[0, 1/(n-1), 2/(n-1), …, 1]`.
///
/// Pair with [`crate::interpolate()`] to drive evenly spaced ramp generation:
///
/// ```rust
/// use culors::{interpolate, parse, samples};
/// let a = parse("oklch(70% 0.15 30deg)").unwrap();
/// let b = parse("oklch(70% 0.15 200deg)").unwrap();
/// let ramp = interpolate(&[a, b], "oklab");
/// let stops: Vec<_> = samples(11).into_iter().map(ramp).collect();
/// assert_eq!(stops.len(), 11);
/// ```
/// `n` evenly spaced ramp positions, each transformed by `easing`.
///
/// Equivalent to culori's `samples(n, γ)` when `easing` is
/// [`crate::easing_gamma(γ)`](crate::easing_gamma); the broader signature
/// accepts any easing curve including [`crate::easing_smoothstep`].
///
/// ```rust
/// use culors::{easing_gamma, samples_with_easing};
/// // culori: samples(5, 2.2)
/// let v = samples_with_easing(5, easing_gamma(2.2));
/// assert!((v[2] - 0.217637640824031).abs() < 1e-12);
/// ```