summaryrefslogtreecommitdiffstats
path: root/examples/loading_spinners/src/easing.rs
diff options
context:
space:
mode:
authorLibravatar Nick Senger <dev@nsenger.com>2023-06-07 15:19:11 -0700
committerLibravatar Nick Senger <dev@nsenger.com>2023-06-07 15:42:13 -0700
commit2ebc92319711e6fa0dda310939257334625b59c9 (patch)
tree3643af813fbb72e4308893cd33d383c7a0c12986 /examples/loading_spinners/src/easing.rs
parentcdfb8b30680de164280b8b90fbc08a1638e597e2 (diff)
downloadiced-2ebc92319711e6fa0dda310939257334625b59c9.tar.gz
iced-2ebc92319711e6fa0dda310939257334625b59c9.tar.bz2
iced-2ebc92319711e6fa0dda310939257334625b59c9.zip
feat: use lyon for easing
Diffstat (limited to 'examples/loading_spinners/src/easing.rs')
-rw-r--r--examples/loading_spinners/src/easing.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/examples/loading_spinners/src/easing.rs b/examples/loading_spinners/src/easing.rs
new file mode 100644
index 00000000..04befa15
--- /dev/null
+++ b/examples/loading_spinners/src/easing.rs
@@ -0,0 +1,132 @@
+use iced_core::Point;
+use lyon::algorithms::measure::PathMeasurements;
+use lyon::path::builder::NoAttributes;
+use lyon::path::path::BuilderImpl;
+use lyon::path::Path;
+
+use once_cell::sync::Lazy;
+
+pub static EMPHASIZED: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.05, 0.0], [0.133333, 0.06], [0.166666, 0.4])
+ .cubic_bezier_to([0.208333, 0.82], [0.25, 1.0], [1.0, 1.0])
+ .build()
+});
+
+pub static EMPHASIZED_DECELERATE: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.05, 0.7], [0.1, 1.0], [1.0, 1.0])
+ .build()
+});
+
+pub static EMPHASIZED_ACCELERATE: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.3, 0.0], [0.8, 0.15], [1.0, 1.0])
+ .build()
+});
+
+pub static STANDARD: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.2, 0.0], [0.0, 1.0], [1.0, 1.0])
+ .build()
+});
+
+pub static STANDARD_DECELERATE: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.0, 0.0], [0.0, 1.0], [1.0, 1.0])
+ .build()
+});
+
+pub static STANDARD_ACCELERATE: Lazy<Easing> = Lazy::new(|| {
+ Easing::builder()
+ .cubic_bezier_to([0.3, 0.0], [1.0, 1.0], [1.0, 1.0])
+ .build()
+});
+
+pub struct Easing {
+ path: Path,
+ measurements: PathMeasurements,
+}
+
+impl Easing {
+ pub fn builder() -> Builder {
+ Builder::new()
+ }
+
+ pub fn y_at_x(&self, x: f32) -> f32 {
+ let mut sampler = self.measurements.create_sampler(
+ &self.path,
+ lyon::algorithms::measure::SampleType::Normalized,
+ );
+ let sample = sampler.sample(x);
+
+ sample.position().y
+ }
+}
+
+pub struct Builder(NoAttributes<BuilderImpl>);
+
+impl Builder {
+ pub fn new() -> Self {
+ let mut builder = Path::builder();
+ builder.begin(lyon::geom::point(0.0, 0.0));
+
+ Self(builder)
+ }
+
+ /// Adds a line segment. Points must be between 0,0 and 1,1
+ pub fn line_to(mut self, to: impl Into<Point>) -> Self {
+ self.0.line_to(Self::point(to));
+
+ self
+ }
+
+ /// Adds a quadratic bézier curve. Points must be between 0,0 and 1,1
+ pub fn quadratic_bezier_to(
+ mut self,
+ ctrl: impl Into<Point>,
+ to: impl Into<Point>,
+ ) -> Self {
+ self.0
+ .quadratic_bezier_to(Self::point(ctrl), Self::point(to));
+
+ self
+ }
+
+ /// Adds a cubic bézier curve. Points must be between 0,0 and 1,1
+ pub fn cubic_bezier_to(
+ mut self,
+ ctrl1: impl Into<Point>,
+ ctrl2: impl Into<Point>,
+ to: impl Into<Point>,
+ ) -> Self {
+ self.0.cubic_bezier_to(
+ Self::point(ctrl1),
+ Self::point(ctrl2),
+ Self::point(to),
+ );
+
+ self
+ }
+
+ pub fn build(mut self) -> Easing {
+ self.0.line_to(lyon::geom::point(1.0, 1.0));
+ self.0.end(false);
+
+ let path = self.0.build();
+ let measurements = PathMeasurements::from_path(&path, 0.0);
+
+ Easing { path, measurements }
+ }
+
+ fn point(p: impl Into<Point>) -> lyon::geom::Point<f32> {
+ let p: Point = p.into();
+ lyon::geom::point(p.x.min(1.0).max(0.0), p.y.min(1.0).max(0.0))
+ }
+}
+
+impl Default for Builder {
+ fn default() -> Self {
+ Self::new()
+ }
+}