Skip to content

Commit e4e56e6

Browse files
committed
Add chain! macro
Cleans up a lot of the imports for cosmic-time aniomation building.
1 parent 786e5cb commit e4e56e6

File tree

13 files changed

+263
-135
lines changed

13 files changed

+263
-135
lines changed

examples/counter/src/main.rs

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use iced::{
55
Alignment, Application, Command, Element, Event, Length, Settings, Subscription, Theme,
66
};
77

8-
use cosmic_time::{self, keyframes, Timeline};
8+
use cosmic_time::{self, chain, keyframes, Timeline};
99

1010
use once_cell::sync::Lazy;
1111

@@ -40,36 +40,27 @@ impl Application for Counter {
4040
// timeline Struct and the "timeline" itself here.
4141
// Though more complicated applications will likely do this in the `update`
4242
let mut timeline = Timeline::new();
43-
let animation = cosmic_time::container::Chain::new(CONTAINER.clone())
44-
// .loop_forever() // Uncomment this line to loop the animation!
45-
.link(
46-
keyframes::Container::new(Duration::ZERO)
47-
.width(0.)
48-
.height(100.),
49-
)
50-
.link(
51-
keyframes::Container::new(Duration::from_secs(2))
52-
.width(200.)
53-
.height(100.),
54-
)
55-
.link(
56-
keyframes::Container::new(Duration::from_secs(2))
57-
.width(200.)
58-
.height(300.)
59-
.padding([0, 0, 0, 0]),
60-
)
61-
.link(
62-
keyframes::Container::new(Duration::from_secs(2))
63-
.width(700.)
64-
.height(300.)
65-
.padding([0, 0, 0, 500]),
66-
)
67-
.link(
68-
keyframes::Container::new(Duration::from_secs(2))
69-
.width(150.)
70-
.height(150.)
71-
.padding([0, 0, 0, 0]),
72-
);
43+
let animation = chain![
44+
CONTAINER,
45+
keyframes::Container::new(Duration::ZERO)
46+
.width(0.)
47+
.height(100.),
48+
keyframes::Container::new(Duration::from_secs(2))
49+
.width(200.)
50+
.height(100.),
51+
keyframes::Container::new(Duration::from_secs(2))
52+
.width(200.)
53+
.height(300.)
54+
.padding([0, 0, 0, 0]),
55+
keyframes::Container::new(Duration::from_secs(2))
56+
.width(700.)
57+
.height(300.)
58+
.padding([0, 0, 0, 500]),
59+
keyframes::Container::new(Duration::from_secs(2))
60+
.width(150.)
61+
.height(150.)
62+
.padding([0, 0, 0, 0]),
63+
];
7364

7465
// Notice how we had to specify the start and end of the widget dimensions?
7566
// Iced's default values for widgets are usually not animatable, because

examples/pokedex/src/main.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use iced::{
66
};
77

88
use cosmic_time::{
9-
self, keyframes, Back, Bounce, Circular, Ease, Elastic, Exponential, Linear, Quadratic,
9+
self, chain, keyframes, Back, Bounce, Circular, Ease, Elastic, Exponential, Linear, Quadratic,
1010
Quartic, Quintic, Sinusoidal, Timeline,
1111
};
1212
use once_cell::sync::Lazy;
@@ -246,19 +246,17 @@ impl Pokemon {
246246
EASE_IN[rand], EASE_OUT[rand]
247247
);
248248

249-
let animation = cosmic_time::space::Chain::new(SPACE.clone())
250-
.link(keyframes::Space::new(Duration::ZERO).height(50.))
251-
.link(
252-
keyframes::Space::new(Duration::from_millis(1500))
253-
.height(250.)
254-
.ease(EASE_IN[rand]),
255-
)
256-
.link(
257-
keyframes::Space::new(Duration::from_millis(3000))
258-
.height(50.)
259-
.ease(EASE_OUT[rand]),
260-
)
261-
.loop_forever();
249+
let animation = chain![
250+
SPACE,
251+
keyframes::Space::new(Duration::ZERO).height(50.),
252+
keyframes::Space::new(Duration::from_millis(1500))
253+
.height(250.)
254+
.ease(EASE_IN[rand]),
255+
keyframes::Space::new(Duration::from_millis(3000))
256+
.height(50.)
257+
.ease(EASE_OUT[rand])
258+
]
259+
.loop_forever();
262260

263261
timeline.set_chain(animation).start();
264262

examples/pong/src/main.rs

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use iced::widget::{column, container, row, Space};
55
use iced::{executor, Application, Command, Event, Length, Settings, Subscription};
66
use iced_native::window;
77

8-
use cosmic_time::{self, keyframes, Duration, Instant, Speed, Timeline};
8+
use cosmic_time::{self, chain, keyframes, Duration, Instant, Speed, Timeline};
99

1010
use once_cell::sync::Lazy;
1111
use rand::prelude::*;
@@ -195,7 +195,8 @@ impl Pong {
195195
if self.left != direction {
196196
self.left = direction;
197197
Some(match direction {
198-
Direction::Down => cosmic_time::space::Chain::new(PADDLE_LEFT.clone())
198+
Direction::Down => chain![
199+
PADDLE_LEFT,
199200
// OOh here are the lazy keyframes!
200201
// This means that this animation will start at wherever the previous
201202
// animation left off!
@@ -209,14 +210,14 @@ impl Pong {
209210
// The animation is only as granular as your definition in the chain.
210211
// If you animation time is not in exact seconds, I highly recommend
211212
// using a smaller unit.
212-
.link(keyframes::Space::lazy(Duration::ZERO))
213-
.link(
214-
keyframes::Space::new(Speed::per_millis(0.3))
215-
.height(self.window.height - 100.),
216-
),
217-
Direction::Up => cosmic_time::space::Chain::new(PADDLE_LEFT.clone())
218-
.link(keyframes::Space::lazy(Duration::ZERO))
219-
.link(keyframes::Space::new(Speed::per_millis(0.3)).height(0.)),
213+
keyframes::Space::lazy(Duration::ZERO),
214+
keyframes::Space::new(Speed::per_millis(0.3)).height(self.window.height - 100.),
215+
],
216+
Direction::Up => chain![
217+
PADDLE_LEFT,
218+
keyframes::Space::lazy(Duration::ZERO),
219+
keyframes::Space::new(Speed::per_millis(0.3)).height(0.)
220+
],
220221
})
221222
} else {
222223
None
@@ -227,15 +228,16 @@ impl Pong {
227228
if self.right != direction {
228229
self.right = direction;
229230
Some(match direction {
230-
Direction::Down => cosmic_time::space::Chain::new(PADDLE_RIGHT.clone())
231-
.link(keyframes::Space::lazy(Duration::ZERO))
232-
.link(
233-
keyframes::Space::new(Speed::per_millis(0.3))
234-
.height(self.window.height - 100.),
235-
),
236-
Direction::Up => cosmic_time::space::Chain::new(PADDLE_RIGHT.clone())
237-
.link(keyframes::Space::lazy(Duration::ZERO))
238-
.link(keyframes::Space::new(Speed::per_millis(0.3)).height(0.)),
231+
Direction::Down => chain![
232+
PADDLE_RIGHT,
233+
keyframes::Space::lazy(Duration::ZERO),
234+
keyframes::Space::new(Speed::per_millis(0.3)).height(self.window.height - 100.),
235+
],
236+
Direction::Up => chain![
237+
PADDLE_RIGHT,
238+
keyframes::Space::lazy(Duration::ZERO),
239+
keyframes::Space::new(Speed::per_millis(0.3)).height(0.)
240+
],
239241
})
240242
} else {
241243
None
@@ -245,64 +247,66 @@ impl Pong {
245247
fn init_ball_y(&mut self) -> cosmic_time::space::Chain {
246248
let min = self.window.height * 0.3;
247249
let max = self.window.height - min - self.window.paddle_height;
248-
cosmic_time::space::Chain::new(BALL_Y.clone())
249-
.link(keyframes::Space::new(Duration::ZERO).height(self.rng.gen_range(min..max)))
250+
let height = self.rng.gen_range(min..max);
251+
252+
chain![BALL_Y, keyframes::Space::new(Duration::ZERO).height(height)]
250253
}
251254

252255
fn init_ball_x(&mut self) -> cosmic_time::space::Chain {
253256
let min = self.window.width * 0.3;
254257
let max = self.window.width - min - self.window.paddle_width;
255-
cosmic_time::space::Chain::new(BALL_X.clone())
256-
.link(keyframes::Space::new(Duration::ZERO).width(self.rng.gen_range(min..max)))
258+
let width = self.rng.gen_range(min..max);
259+
260+
chain![BALL_X, keyframes::Space::new(Duration::ZERO).width(width)]
257261
}
258262

259263
fn rand_vertical_bounce(&mut self) -> cosmic_time::space::Chain {
260264
let speed = 100. * self.rng.gen_range(0.9..1.1);
261265
if self.rng.gen() {
262-
cosmic_time::space::Chain::new(BALL_Y.clone())
263-
.link(keyframes::Space::lazy(Duration::ZERO))
264-
.link(
265-
keyframes::Space::new(Speed::per_secs(speed))
266-
.height(self.window.height - self.window.paddle_width),
267-
)
268-
.link(keyframes::Space::new(Speed::per_secs(speed)).height(0.))
269-
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
270-
.loop_forever()
266+
chain![
267+
BALL_Y,
268+
keyframes::Space::lazy(Duration::ZERO),
269+
keyframes::Space::new(Speed::per_secs(speed))
270+
.height(self.window.height - self.window.paddle_width),
271+
keyframes::Space::new(Speed::per_secs(speed)).height(0.),
272+
keyframes::Space::lazy(Speed::per_secs(speed))
273+
]
274+
.loop_forever()
271275
} else {
272-
cosmic_time::space::Chain::new(BALL_Y.clone())
273-
.link(keyframes::Space::lazy(Duration::ZERO))
274-
.link(keyframes::Space::new(Speed::per_secs(speed)).height(0.))
275-
.link(
276-
keyframes::Space::new(Speed::per_secs(speed))
277-
.height(self.window.height - self.window.paddle_width),
278-
)
279-
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
280-
.loop_forever()
276+
chain![
277+
BALL_Y,
278+
keyframes::Space::lazy(Duration::ZERO),
279+
keyframes::Space::new(Speed::per_secs(speed)).height(0.),
280+
keyframes::Space::new(Speed::per_secs(speed))
281+
.height(self.window.height - self.window.paddle_width),
282+
keyframes::Space::lazy(Speed::per_secs(speed))
283+
]
284+
.loop_forever()
281285
}
282286
}
283287

284288
fn rand_horizontal_bounce(&mut self) -> cosmic_time::space::Chain {
285289
let speed = 100. * self.rng.gen_range(0.9..1.1);
286290
if self.rng.gen() {
287-
cosmic_time::space::Chain::new(BALL_X.clone())
288-
.link(keyframes::Space::lazy(Duration::ZERO))
289-
.link(
290-
keyframes::Space::new(Speed::per_secs(speed))
291-
.width(self.window.width - self.window.paddle_width),
292-
)
293-
.link(keyframes::Space::new(Speed::per_secs(speed)).width(0.))
294-
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
295-
.loop_forever()
291+
chain![
292+
BALL_X,
293+
keyframes::Space::lazy(Duration::ZERO),
294+
keyframes::Space::new(Speed::per_secs(speed))
295+
.width(self.window.width - self.window.paddle_width),
296+
keyframes::Space::new(Speed::per_secs(speed)).width(0.),
297+
keyframes::Space::lazy(Speed::per_secs(speed))
298+
]
299+
.loop_forever()
296300
} else {
297-
cosmic_time::space::Chain::new(BALL_X.clone())
298-
.link(keyframes::Space::lazy(Duration::ZERO))
299-
.link(keyframes::Space::new(Speed::per_secs(speed)).width(0.))
300-
.link(
301-
keyframes::Space::new(Speed::per_secs(speed))
302-
.width(self.window.width - self.window.paddle_width),
303-
)
304-
.link(keyframes::Space::lazy(Speed::per_secs(speed)))
305-
.loop_forever()
301+
chain![
302+
BALL_X,
303+
keyframes::Space::lazy(Duration::ZERO),
304+
keyframes::Space::new(Speed::per_secs(speed)).width(0.),
305+
keyframes::Space::new(Speed::per_secs(speed))
306+
.width(self.window.width - self.window.paddle_width),
307+
keyframes::Space::lazy(Speed::per_secs(speed))
308+
]
309+
.loop_forever()
306310
}
307311
}
308312
}

examples/stopwatch/src/main.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use self::widget::Element;
88
use theme::Theme;
99

1010
use cosmic_time::{
11-
self,
11+
self, chain,
1212
style_button::{self, StyleButton},
1313
style_container::{self, StyleContainer},
1414
Sinusoidal, Timeline,
@@ -183,42 +183,39 @@ impl Application for Stopwatch {
183183
}
184184

185185
fn anim_to_primary() -> style_button::Chain {
186-
style_button::Chain::new(BUTTON.clone())
187-
.link(StyleButton::new(Duration::ZERO).style(button_u8(theme::Button::Destructive)))
188-
.link(StyleButton::new(Duration::from_millis(500)).style(button_u8(theme::Button::Primary)))
186+
chain![
187+
BUTTON,
188+
StyleButton::new(Duration::ZERO).style(button_u8(theme::Button::Destructive)),
189+
StyleButton::new(Duration::from_millis(500)).style(button_u8(theme::Button::Primary))
190+
]
189191
}
190192

191193
fn anim_to_destructive() -> style_button::Chain {
192-
style_button::Chain::new(BUTTON.clone())
193-
.link(StyleButton::new(Duration::ZERO).style(button_u8(theme::Button::Primary)))
194-
.link(
195-
StyleButton::new(Duration::from_millis(500))
196-
.style(button_u8(theme::Button::Destructive)),
197-
)
194+
chain![
195+
BUTTON,
196+
StyleButton::new(Duration::ZERO).style(button_u8(theme::Button::Primary)),
197+
StyleButton::new(Duration::from_millis(500)).style(button_u8(theme::Button::Destructive))
198+
]
198199
}
199200

200201
fn anim_background() -> style_container::Chain {
201-
style_container::Chain::new(CONTAINER.clone())
202-
.link(StyleContainer::new(Duration::ZERO).style(theme::Container::Red))
203-
.link(
204-
StyleContainer::new(Duration::from_secs(1))
205-
// Notice how we can just pass the enum value here, where in the `anim_to_primary/destructive`
206-
// we have to use the fucntion `button_u8`? Because we use a implemented a custom iced theme,
207-
// we can just impl Into<u8> on the enum, and it works here!
208-
.style(theme::Container::Green)
209-
.ease(Sinusoidal::In),
210-
)
211-
.link(
212-
StyleContainer::new(Duration::from_secs(2))
213-
.style(theme::Container::Blue)
214-
.ease(Sinusoidal::In),
215-
)
216-
.link(
217-
StyleContainer::new(Duration::from_secs(3))
218-
.style(theme::Container::Red)
219-
.ease(Sinusoidal::In),
220-
)
221-
.loop_forever()
202+
chain![
203+
CONTAINER,
204+
StyleContainer::new(Duration::ZERO).style(theme::Container::Red),
205+
StyleContainer::new(Duration::from_secs(1))
206+
// Notice how we can just pass the enum value here, where in the `anim_to_primary/destructive`
207+
// we have to use the fucntion `button_u8`? Because we use a implemented a custom iced theme,
208+
// we can just impl Into<u8> on the enum, and it works here!
209+
.style(theme::Container::Green)
210+
.ease(Sinusoidal::In),
211+
StyleContainer::new(Duration::from_secs(2))
212+
.style(theme::Container::Blue)
213+
.ease(Sinusoidal::In),
214+
StyleContainer::new(Duration::from_secs(3))
215+
.style(theme::Container::Red)
216+
.ease(Sinusoidal::In)
217+
]
218+
.loop_forever()
222219
}
223220

224221
// Style implementations

src/keyframes.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ pub use toggler::Toggler;
1616

1717
use crate::Timeline;
1818

19+
#[macro_export]
20+
macro_rules! chain{
21+
($id:expr) => {
22+
$id.clone().to_chain()
23+
};
24+
($id:expr, $($x:expr),+ $(,)?) => {
25+
$id.clone().to_chain_with_children(vec![$($x),+])
26+
};
27+
}
28+
1929
#[derive(Debug, Copy, Clone, PartialEq, Default)]
2030
pub enum Repeat {
2131
#[default]

0 commit comments

Comments
 (0)