pub struct Morph { /* private fields */ }Expand description
An interpolation between two RoundedPolygons: at any progress t it
yields one closed outline, the start shape at 0 and the end shape at 1.
§Cost
Building one is the expensive step — measuring both outlines, pairing
their corners and re-cutting the curves all happen in Morph::new. Build
a morph once and keep it (in widget state, a OnceLock, a cache keyed by
the shape pair); Morph::path is the per-frame call and does nothing but
interpolate the stored curve pairs into the path it returns.
Implementations§
Source§impl Morph
impl Morph
Sourcepub fn new(start: RoundedPolygon, end: RoundedPolygon) -> Morph
pub fn new(start: RoundedPolygon, end: RoundedPolygon) -> Morph
Builds the morph from start to end.
This measures both outlines, pairs their corners and re-cuts their
curves into matching pairs — see Morph’s note on cost for why that
belongs outside the frame loop.
§Panics
If either polygon has no measurable outline, or if two corners of one shape sit at the same point along its outline (upstream throws in both cases; every input here is a shape definition, not runtime data).
Sourcepub const fn start(&self) -> &RoundedPolygon
pub const fn start(&self) -> &RoundedPolygon
The shape at progress 0.
Sourcepub const fn end(&self) -> &RoundedPolygon
pub const fn end(&self) -> &RoundedPolygon
The shape at progress 1.
Sourcepub fn as_cubics(&self, progress: f64) -> Vec<Cubic>
pub fn as_cubics(&self, progress: f64) -> Vec<Cubic>
The morphed outline at progress, as its curves.
Allocates the returned list; Morph::path is the cheaper route when
the caller only wants to paint it.
Sourcepub fn path(&self, progress: f64) -> BezPath
pub fn path(&self, progress: f64) -> BezPath
The morphed outline at progress as a closed kurbo::BezPath: one
MoveTo, one CurveTo per curve, and a ClosePath.
progress is not clamped — a caller feeding a spring value may pass a
little past 0/1 to keep the spring’s overshoot, as long as it stays
close (far outside the range the outline is undefined).
This is the per-frame call: it allocates the path it returns and nothing else.
Sourcepub fn bounds(&self) -> Rect
pub fn bounds(&self) -> Rect
The axis-aligned bounds of every anchor and control point of both
shapes — cheap, and never tighter than Morph::exact_bounds.
This is the size to reserve for a morph: an interpolated control point
is a blend of the two shapes’ own, so for any progress in 0..=1 the
outline stays inside the hull these bounds describe (an overshooting
progress can leave it).
Sourcepub fn exact_bounds(&self) -> Rect
pub fn exact_bounds(&self) -> Rect
The true axis-aligned bounds of both shapes’ outlines.
Holds the outline at progress 0 and 1 exactly; in between, an
interpolated control point can pull a curve marginally outside it, which
is why Morph::bounds is the safer reservation.
Sourcepub fn max_bounds(&self) -> Rect
pub fn max_bounds(&self) -> Rect
The smallest square holding either shape in any rotation — what a UI element hosting a spinning morph needs to reserve.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Morph
impl RefUnwindSafe for Morph
impl Send for Morph
impl Sync for Morph
impl Unpin for Morph
impl UnsafeUnpin for Morph
impl UnwindSafe for Morph
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.