PistonDevelopers / conrod

An easy-to-use, 2D GUI library written entirely in Rust.
Other
3.35k stars 297 forks source link

Animations #946

Open ishitatsuyuki opened 7 years ago

ishitatsuyuki commented 7 years ago

Since the guide is quite incomplete, and I couldn't find any known resources about animations, I'm opening an issue here.

I'd like to do animations with this GUI library (for reference, Qt has it implemented in a simple API). The sprite crate is already implementing it, but unlike conrod, it has piston specific design.

Please put some docs on this, or implement if sprite is not sufficient.

karanahuja-android commented 7 years ago

I would live to use or make existing widhets have animation effects .

Example - Fade in Fade out Slide in Slide out Flip Overlay popout Shake

mitchmindtree commented 7 years ago

Hmm currently there's no API specifically for animations, however it certainly would be nice. I can't think of a nice way to do this in conrod just yet but I'll keep thinking about it. In the meantime, any ideas for the kind of API that you'd like to see for this would be greatly appreciated!

@ishitatsuyuki would you mind sharing/linking me to some examples of the Qt animations you mention? Qt has quite a different API to conrod so I'm not sure if the ideas will translate well, but I'm sure it's worth a look for ideas.

ishitatsuyuki commented 7 years ago

@mitchmindtree see here for native Qt examples, or here for QML examples.

ishitatsuyuki commented 7 years ago

Seems the sprite+ai_behavior crate already has some event handling like Button. Maybe we should adopt to use it, along with enabling animations.

ishitatsuyuki commented 7 years ago

By the way, here's a side suggestion: it would be good to see Text animated separately by line. This is useful for fading text in the order of character, which I want to do (something like the typing animation smoothed).

OtaK commented 6 years ago

I've created an animation engine (based on bezier-curve interpolation of value ranges), but it requires -for now- constant redraws as I've yet to find a way to tell conrod that there's an animation still going on. Definitely counter-intuitive for performance and how conrod handles itself for now (redrawing on event only). It's definitely possible though. Also, my API is still not mature at all, the interpolation generator is completely separate from conrod and requires manual assigning of values/durations/curves such as :

TweenValue::new(
    (start_value as f64, end_value as f64), // start/end values
    Duration::from_millis(animation_duration), // duration
    bezier!(x1, y1, x2, y2), // easing
    None // fps, defaults to 60
)
// Standard bezier easings such as ease_in etc are implemented in constants, I'm not giving custom bezier curves each time ofc
mitchmindtree commented 6 years ago

@OtaK nice, I actually really like the idea of having it be its own type where given some delta time it provides a resulting value. If there is one type managing all animations (maybe in a map from Id -> Animation or something like this), it could provide some method along the lines of any_animations_in_progress(&self) -> bool that returns true if there are any animations in progress and false otherwise, which could be used for consideration in whether or not redrawing is required. Conrod itself currently is not aware of event loop rates or anything along these lines, so an API along the lines of what you suggest sounds nice and non-intrusive.

OtaK commented 6 years ago

@mitchmindtree Thanks. Well I was thinking of refactoring it in general, since differential/per animation FPS rates does not make that much sense actually, and the fact that each animation manages its own value generator thread (+ hidden thread-based timer), I was thinking of creating an inner global event loop (rated at X iterations per second) that would emit any registered interpolations. A centralized event loop would mean a centralized instance, that would also mean that I'd be able to know if there's any animation which progress is not 100%. From that yes, I'll be able to determine whether or not I need to feed conrod::event::Input::Redraw to my event loop.

Maybe I should look at mio or tokio since global event loops is their thing. For now everything is homemade.

adamski commented 5 years ago

Was there any progress on this? I think the suggestion above makes sense - have a global timer (thread?) running at a pre-determined rate that handles any animations.