add animation
This commit is contained in:
parent
86f61ff3f6
commit
bcb69805ef
4 changed files with 215 additions and 4 deletions
|
@ -19,14 +19,15 @@ pub mod prelude {
|
||||||
pub use super::primitives::Nothing;
|
pub use super::primitives::Nothing;
|
||||||
pub use super::primitives::Side;
|
pub use super::primitives::Side;
|
||||||
pub use super::primitives::Size;
|
pub use super::primitives::Size;
|
||||||
|
pub use super::primitives::animation::{Animated, Animation, Delay, Duration, Scope, Timing};
|
||||||
pub use super::primitives::aspect::Aspect;
|
pub use super::primitives::aspect::Aspect;
|
||||||
pub use super::primitives::background::Background;
|
pub use super::primitives::background::Background;
|
||||||
pub use super::primitives::container::Container;
|
pub use super::primitives::container::Container;
|
||||||
pub use super::primitives::cursor::Cursor;
|
pub use super::primitives::cursor::Cursor;
|
||||||
pub use super::primitives::div::Div;
|
pub use super::primitives::div::Div;
|
||||||
pub use super::primitives::flex::{Flex, Justify};
|
pub use super::primitives::flex::{Flex, FlexBasis, FlexGrow, Justify};
|
||||||
pub use super::primitives::header::Header;
|
pub use super::primitives::header::Header;
|
||||||
pub use super::primitives::height::HeightWidget;
|
pub use super::primitives::height::{Height, MaxHeight, MinHeight};
|
||||||
pub use super::primitives::image::Image;
|
pub use super::primitives::image::Image;
|
||||||
pub use super::primitives::link::Link;
|
pub use super::primitives::link::Link;
|
||||||
pub use super::primitives::margin::Margin;
|
pub use super::primitives::margin::Margin;
|
||||||
|
@ -38,7 +39,7 @@ pub mod prelude {
|
||||||
pub use super::primitives::space::{ScreenValue, SpaceBetween};
|
pub use super::primitives::space::{ScreenValue, SpaceBetween};
|
||||||
pub use super::primitives::text::{Paragraph, Span, Text};
|
pub use super::primitives::text::{Paragraph, Span, Text};
|
||||||
pub use super::primitives::visibility::Visibility;
|
pub use super::primitives::visibility::Visibility;
|
||||||
pub use super::primitives::width::Width;
|
pub use super::primitives::width::{MaxWidth, MinWidth, Width};
|
||||||
pub use super::primitives::zindex::ZIndex;
|
pub use super::primitives::zindex::ZIndex;
|
||||||
pub use super::wrapper::Hover;
|
pub use super::wrapper::Hover;
|
||||||
}
|
}
|
||||||
|
|
204
src/ui/primitives/animation.rs
Normal file
204
src/ui/primitives/animation.rs
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
use maud::{Markup, Render, html};
|
||||||
|
|
||||||
|
use crate::ui::UIWidget;
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn Animated<T: UIWidget + 'static>(inner: T) -> AnimatedWidget {
|
||||||
|
AnimatedWidget {
|
||||||
|
inner: Box::new(inner),
|
||||||
|
scope: Scope::Normal,
|
||||||
|
timing: None,
|
||||||
|
delay: None,
|
||||||
|
duration: None,
|
||||||
|
animation: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AnimatedWidget {
|
||||||
|
inner: Box<dyn UIWidget>,
|
||||||
|
scope: Scope,
|
||||||
|
timing: Option<Timing>,
|
||||||
|
delay: Option<Delay>,
|
||||||
|
duration: Option<Duration>,
|
||||||
|
animation: Option<Animation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnimatedWidget {
|
||||||
|
pub fn scope(mut self, scope: Scope) -> Self {
|
||||||
|
self.scope = scope;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn timing(mut self, timing: Timing) -> Self {
|
||||||
|
self.timing = Some(timing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delay(mut self, delay: Delay) -> Self {
|
||||||
|
self.delay = Some(delay);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn duration(mut self, duration: Duration) -> Self {
|
||||||
|
self.duration = Some(duration);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn animate(mut self, animation: Animation) -> Self {
|
||||||
|
self.animation = Some(animation);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for AnimatedWidget {
|
||||||
|
fn render(&self) -> Markup {
|
||||||
|
self.render_with_class("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UIWidget for AnimatedWidget {
|
||||||
|
fn can_inherit(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_class(&self) -> Vec<String> {
|
||||||
|
let mut ret = vec![self.scope.to_value().to_string()];
|
||||||
|
|
||||||
|
if let Some(timing) = &self.timing {
|
||||||
|
ret.push(timing.to_value().to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(delay) = &self.delay {
|
||||||
|
ret.push(delay.to_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(duration) = &self.duration {
|
||||||
|
ret.push(duration.to_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(anim) = &self.animation {
|
||||||
|
ret.push(anim.to_value().to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extended_class(&self) -> Vec<String> {
|
||||||
|
let mut c = self.base_class();
|
||||||
|
c.extend_from_slice(&self.inner.extended_class());
|
||||||
|
c
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_with_class(&self, class: &str) -> Markup {
|
||||||
|
if self.inner.as_ref().can_inherit() {
|
||||||
|
self.inner
|
||||||
|
.as_ref()
|
||||||
|
.render_with_class(&format!("{} {class}", self.base_class().join(" ")))
|
||||||
|
} else {
|
||||||
|
html! {
|
||||||
|
div class=(format!("{} {class}", self.base_class().join(" "))) {
|
||||||
|
(self.inner.as_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Scope {
|
||||||
|
None,
|
||||||
|
All,
|
||||||
|
Normal,
|
||||||
|
Colors,
|
||||||
|
Opacity,
|
||||||
|
Shadow,
|
||||||
|
Transform,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scope {
|
||||||
|
pub fn to_value(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Scope::None => "transition-none",
|
||||||
|
Scope::All => "transition-all",
|
||||||
|
Scope::Normal => "transition",
|
||||||
|
Scope::Colors => "transition-colors",
|
||||||
|
Scope::Opacity => "transition-opacity",
|
||||||
|
Scope::Shadow => "transition-shadow",
|
||||||
|
Scope::Transform => "transition-transform",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! num_opt {
|
||||||
|
($name:ident, $id:literal) => {
|
||||||
|
pub enum $name {
|
||||||
|
Custom(String),
|
||||||
|
_0,
|
||||||
|
_75,
|
||||||
|
_100,
|
||||||
|
_150,
|
||||||
|
_200,
|
||||||
|
_300,
|
||||||
|
_500,
|
||||||
|
_700,
|
||||||
|
_1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $name {
|
||||||
|
pub fn to_value(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Custom(s) => format!("{}-[{s}]", $id),
|
||||||
|
Self::_0 => concat!($id, "-0").to_string(),
|
||||||
|
Self::_75 => concat!($id, "-75").to_string(),
|
||||||
|
Self::_100 => concat!($id, "-100").to_string(),
|
||||||
|
Self::_150 => concat!($id, "-150").to_string(),
|
||||||
|
Self::_200 => concat!($id, "-200").to_string(),
|
||||||
|
Self::_300 => concat!($id, "-300").to_string(),
|
||||||
|
Self::_500 => concat!($id, "-500").to_string(),
|
||||||
|
Self::_700 => concat!($id, "-700").to_string(),
|
||||||
|
Self::_1000 => concat!($id, "-1000").to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
num_opt!(Duration, "duration");
|
||||||
|
num_opt!(Delay, "delay");
|
||||||
|
|
||||||
|
pub enum Timing {
|
||||||
|
EaseLinear,
|
||||||
|
EaseIn,
|
||||||
|
EaseOut,
|
||||||
|
EaseInOut,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timing {
|
||||||
|
pub const fn to_value(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Timing::EaseLinear => "ease-linear",
|
||||||
|
Timing::EaseIn => "ease-in",
|
||||||
|
Timing::EaseOut => "ease-out",
|
||||||
|
Timing::EaseInOut => "ease-in-out",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Animation {
|
||||||
|
None,
|
||||||
|
Spin,
|
||||||
|
Ping,
|
||||||
|
Pulse,
|
||||||
|
Bounce,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation {
|
||||||
|
pub fn to_value(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Animation::None => "animate-none",
|
||||||
|
Animation::Spin => "animate-spin",
|
||||||
|
Animation::Ping => "animate-ping",
|
||||||
|
Animation::Pulse => "animate-pulse",
|
||||||
|
Animation::Bounce => "animate-bounce",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use maud::{PreEscaped, html};
|
||||||
|
|
||||||
use super::UIWidget;
|
use super::UIWidget;
|
||||||
|
|
||||||
|
pub mod animation;
|
||||||
pub mod aspect;
|
pub mod aspect;
|
||||||
pub mod background;
|
pub mod background;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
|
|
|
@ -41,7 +41,12 @@ impl UIWidget for HoverWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extended_class(&self) -> Vec<String> {
|
fn extended_class(&self) -> Vec<String> {
|
||||||
self.base_class()
|
let mut ret = self.base_class();
|
||||||
|
if let Some(inner) = &self.0 {
|
||||||
|
ret.extend_from_slice(&inner.extended_class());
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_with_class(&self, class: &str) -> Markup {
|
fn render_with_class(&self, class: &str) -> Markup {
|
||||||
|
|
Loading…
Add table
Reference in a new issue