rust-dominator/examples/animation/src/main.rs

170 lines
4.9 KiB
Rust
Raw Normal View History

2018-03-15 06:54:18 -04:00
#[macro_use]
extern crate stdweb;
#[macro_use]
extern crate dominator;
#[macro_use]
extern crate futures_signals;
2018-03-15 06:54:18 -04:00
use std::rc::Rc;
use futures_signals::signal::SignalExt;
use futures_signals::signal_vec::MutableVec;
2018-03-15 06:54:18 -04:00
use dominator::traits::*;
use dominator::Dom;
2018-03-18 14:49:40 -04:00
use dominator::events::{MouseOverEvent, MouseOutEvent};
2018-03-15 06:54:18 -04:00
use dominator::animation::{Percentage, easing};
use dominator::animation::{MutableAnimation, AnimatedMapBroadcaster};
2018-03-15 06:54:18 -04:00
fn make_animated_box(value: u32, broadcaster: AnimatedMapBroadcaster) -> Dom {
let animation = Rc::new(MutableAnimation::new(3000.0));
2018-03-15 06:54:18 -04:00
let hover_animation = Rc::new(MutableAnimation::new(300.0));
2018-03-15 06:54:18 -04:00
let low: f64 = value as f64;
let high: f64 = (value + 60) as f64;
html!("div", {
.future(animation.signal().for_each(clone!(animation => move |x| {
let x: f64 = x.into_f64();
2018-03-15 06:54:18 -04:00
if x == 0.0 {
animation.animate_to(Percentage::new(1.0));
} else if x == 1.0 {
animation.animate_to(Percentage::new(0.0));
}
Ok(())
})))
2018-03-15 06:54:18 -04:00
.event(clone!(hover_animation => move |_: MouseOverEvent| {
hover_animation.animate_to(Percentage::new(1.0));
}))
2018-03-15 06:54:18 -04:00
.event(clone!(hover_animation => move |_: MouseOutEvent| {
hover_animation.animate_to(Percentage::new(0.0));
}))
2018-03-15 06:54:18 -04:00
.style("border-radius", "10px")
2018-03-15 06:54:18 -04:00
.style_signal("width", animation.signal()
2018-03-15 06:54:18 -04:00
.map(|t| easing::in_out(t, easing::cubic))
.map(|t| Some(format!("{}px", t.range_inclusive(167.0, 500.0)))))
2018-03-15 06:54:18 -04:00
.style("position", "relative")
2018-03-15 06:54:18 -04:00
.style_signal("margin-left", animation.signal()
2018-03-15 06:54:18 -04:00
.map(|t| t.invert())
.map(|t| easing::in_out(t, easing::cubic))
.map(|t| Some(format!("{}px", t.range_inclusive(20.0, 0.0)))))
2018-03-15 06:54:18 -04:00
.style_signal("left", broadcaster.signal()
2018-03-15 06:54:18 -04:00
.map(|t| easing::in_out(t, easing::cubic))
.map(|t| Some(format!("{}px", t.range_inclusive(100.0, 0.0)))))
.style_signal("height", map_ref! {
let animation = broadcaster.signal().map(|t| easing::in_out(t, easing::cubic)),
let hover = hover_animation.signal().map(|t| easing::out(t, easing::cubic)) =>
Some(format!("{}px", animation.range_inclusive(0.0, hover.range_inclusive(5.0, 15.0))))
})
2018-03-15 06:54:18 -04:00
.style_signal("background-color", animation.signal()
2018-03-15 06:54:18 -04:00
.map(|t| easing::in_out(t, easing::cubic))
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
t.range_inclusive(low, high),
t.range_inclusive(50.0, 100.0),
t.range_inclusive(50.0, 100.0)))))
2018-03-15 06:54:18 -04:00
.style("border-style", "solid")
2018-03-15 06:54:18 -04:00
.style_signal("border-width", broadcaster.signal()
.map(|t| easing::in_out(t, easing::cubic))
.map(|t| Some(format!("{}px", t.range_inclusive(0.0, 5.0)))))
2018-03-15 06:54:18 -04:00
.style_signal("border-color", animation.signal()
2018-03-15 06:54:18 -04:00
.map(|t| easing::in_out(t, easing::cubic))
.map(move |t| Some(format!("hsl({}, {}%, {}%)",
t.range_inclusive(high, low),
t.range_inclusive(100.0, 50.0),
t.range_inclusive(100.0, 50.0)))))
2018-03-15 06:54:18 -04:00
})
}
struct State {
boxes: MutableVec<u32>,
}
impl Drop for State {
fn drop(&mut self) {
js! {
console.log("Dropping");
}
}
}
fn main() {
let state = Rc::new(State {
2018-03-15 06:54:18 -04:00
boxes: MutableVec::new_with_values(vec![0]),
});
2018-03-15 06:54:18 -04:00
let mut color = 10;
let f = clone!(state => move || {
let mut lock = state.boxes.lock_mut();
if lock.len() >= 40 {
lock.remove(0);
2018-03-15 06:54:18 -04:00
}
lock.push(color % 360);
2018-03-15 06:54:18 -04:00
color += 10;
});
let _timer_id = js!(
return setInterval(function () {
2018-03-15 06:54:18 -04:00
@{f}();
}, 500);
);
/*dominator::append_dom(&body,
html!("button", {
event(clone!(state => move |_: ClickEvent| {
js! { @(no_return)
clearInterval(@{&timer_id});
}
2018-03-15 06:54:18 -04:00
state.boxes.clear();
}));
children(&mut [
text("Clear all animations")
]);
})
);*/
for _ in 0..1 {
2018-03-18 14:49:40 -04:00
dominator::append_dom(&dominator::body(),
2018-03-15 06:54:18 -04:00
html!("div", {
.style("display", "flex")
.children(&mut [
html!("div", {
.children_signal_vec(state.boxes.signal_vec()
.animated_map(2000.0, |value, t| {
make_animated_box(value, t)
}))
}),
html!("div", {
.children_signal_vec(state.boxes.signal_vec()
.animated_map(2000.0, |value, t| {
make_animated_box(value, t)
}))
}),
])
2018-03-15 06:54:18 -04:00
})
);
}
2018-03-15 06:54:18 -04:00
}