class new in Git master
#include <Magnum/Ui/NodeAnimator.h>
NodeAnimator Node animator.
Each animation interpolates between given node offset, size and opacity endpoints, optionally modifying node flags and allowing to automatically remove the node once the animation stops. If you need to execute arbitrary extra code during a node animation, use GenericNodeAnimator.
Setting up an animator instance
The animator doesn't have any shared state or configuration, so it's just about constructing it from a fresh AbstractUserInterface::
Ui::NodeAnimator& animator = ui.setNodeAnimatorInstance( Containers::pointer<Ui::NodeAnimator>(ui.createAnimator()));
Unlike builtin layers or layouters, the default UserInterface implementation doesn't implicitly provide a NodeAnimator instance.
Creating animations
An animation is created by calling create() with a NodeAnimation helper that specifies which properties — node offset, size, opacity or flags — should be animated, an easing function from Animation::
The following code animates a popup sliding from the top edge of the screen to the center. Besides that, it enables NodeFlag::
Ui::NodeHandle popup = …; Vector2 popupSize = ui.nodeSize(popup); animator.create( Ui::NodeAnimation{} .fromOffset({(ui.size().x() - popupSize.x())*0.5f, -popupSize.y()}) .toOffset((ui.size() - popupSize)*0.5f) .addFlagsBegin(Ui::NodeFlag::NoEvents) .clearFlagsEnd(Ui::NodeFlag::NoEvents), Animation::Easing::cubicIn, now, 0.5_sec, popup);
If either the source or the target offset, size or opacity value is omitted, the animation picks the value the node has at the time the animation is being played. In the following snippet, a context menu is being closed, shrinking it from its current size to zero. NodeFlag::
Ui::NodeHandle contextMenu = …; animator.create( Ui::NodeAnimation{} .toSize({0.0f, 0.0f}) .addFlagsBegin(Ui::NodeFlag::Clip) .addFlagsEnd(Ui::NodeFlag::Hidden), Animation::Easing::backOut, now, 1.0_sec, contextMenu);
It's also possible to animate just horizontal or vertical offset and size alone, with the other direction staying unchanged, using NodeAnimation::
With NodeAnimation::
Ui::NodeHandle tooltip = …; animator.create( Ui::NodeAnimation{} .toOpacity(0.0f) .setRemoveNodeAfter(true), Animation::Easing::exponentialIn, now + 10.0_sec, 0.3_sec, tooltip);
Reversible animations
In cases where for example opening and closing a menu is animated the same way, just in reverse, it's possible to create a single animation and drive it either forward or backward. In the following case, the menu is initially NodeFlag::
Ui::NodeHandle menu = ui.createNode(…, Ui::NodeFlag::Hidden); Ui::AnimationHandle menuAnimation = animator.create( Ui::NodeAnimation{} .fromOffsetY(-ui.nodeSize(menu).y()) .toOffsetY(0.0f) .clearFlagsBegin(Ui::NodeFlag::Hidden) .addFlagsBegin(Ui::NodeFlag::NoEvents) .clearFlagsEnd(Ui::NodeFlag::NoEvents), Animation::Easing::elasticIn, now, 0.5_sec, menu, Ui::AnimationFlag::KeepOncePlayed);
When AnimationFlag::
animator.addFlags(menuAnimation, Ui::AnimationFlag::Reverse); animator.play(menuAnimation, now);
Furthermore, such an animation can be reversed during the time it's played using the addFlags() / clearFlags() overloads that additionally take current time, which will make the animation continue back from where it ended up being at given time. The following code will first attempt to make the animation play backward assuming it's still playing, and if it's not it plays it from the start:
animator.addFlags(menuAnimation, Ui::AnimationFlag::Reverse, now); if(animator.state(menuAnimation) != Ui::AnimationState::Playing) animator.play(menuAnimation, now);
Animation lifetime and node attachment
As with all other animations, they're implicitly removed once they're played. Pass AnimationFlag::
As the animations are associated with nodes they animate, when the node the animation is attached to is removed, the animation gets removed as well. If you want to preserve the animation when the node is removed, call attach(AnimationHandle, NodeHandle) with NodeHandle::
Note that if NodeAnimation::
Multiple animations affecting a single node
Currently, if multiple animations simultaenously affect the same property of the same node, the behavior is unspecified and will likely result in the animations overwriting each other's output. There's no guarantee about the order in which the animations are applied to a particular node, nor there's any merging done.
On the other hand, having one NodeAnimator animation affect for example just an offset and another just a size or opacity will work correctly if both animations are coming from NodeAnimator. One practical use case is having a different easing function for each. There's however no way to guarantee this when the node animations are combined with GenericNodeAnimator or custom animators.
Base classes
- class AbstractNodeAnimator new in Git master
- Base for node animators.
Constructors, destructors, conversion operators
- NodeAnimator(AnimatorHandle handle) explicit
- Constructor.
- NodeAnimator(const NodeAnimator&) deleted
- Copying is not allowed.
- NodeAnimator(NodeAnimator&&) noexcept
- Move constructor.
Public functions
- auto operator=(const NodeAnimator&) -> NodeAnimator& deleted
- Copying is not allowed.
- auto operator=(NodeAnimator&&) -> NodeAnimator& noexcept
- Move assignment.
- auto create(const NodeAnimation& animation, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, NodeHandle node, UnsignedInt repeatCount = 1, AnimationFlags flags = {}) -> AnimationHandle
- Create an animation.
- auto create(const NodeAnimation& animation, Float(*)(Float) easing, Nanoseconds start, Nanoseconds duration, NodeHandle node, AnimationFlags flags) -> AnimationHandle
- Create an animation.
- void remove(AnimationHandle handle)
- Remove an animation.
- void remove(AnimatorDataHandle handle)
- Remove an animation assuming it belongs to this animator.
-
auto offsets(AnimationHandle handle) const -> Containers::
Pair<Vector2, Vector2> - Animation source and target offsets.
-
auto offsets(AnimatorDataHandle handle) const -> Containers::
Pair<Vector2, Vector2> - Animation source and target offsets assuming it belongs to this animator.
-
auto sizes(AnimationHandle handle) const -> Containers::
Pair<Vector2, Vector2> - Animation source and target sizes.
-
auto sizes(AnimatorDataHandle handle) const -> Containers::
Pair<Vector2, Vector2> - Animation source and target sizes assuming it belongs to this animator.
-
auto opacities(AnimationHandle handle) const -> Containers::
Pair<Float, Float> - Animation source and target opacities.
-
auto opacities(AnimatorDataHandle handle) const -> Containers::
Pair<Float, Float> - Animation source and target opacities assuming it belongs to this animator.
-
auto flagsAdd(AnimationHandle handle) const -> Containers::
Pair<NodeFlags, NodeFlags> - Node flags to add at animation begin and end.
-
auto flagsAdd(AnimatorDataHandle handle) const -> Containers::
Pair<NodeFlags, NodeFlags> - Node flags to add at animation begin and end assuming it belongs to this animator.
-
auto flagsClear(AnimationHandle handle) const -> Containers::
Pair<NodeFlags, NodeFlags> - Node flags to clear at animation begin and end.
-
auto flagsClear(AnimatorDataHandle handle) const -> Containers::
Pair<NodeFlags, NodeFlags> - Node flags to clear at animation begin and end assuming it belongs to this animator.
- auto hasRemoveNodeAfter(AnimationHandle handle) const -> bool
- Whether the node the animation is assigned to is removed when the animation stops.
- auto hasRemoveNodeAfter(AnimatorDataHandle handle) const -> bool
- Whether the node the animation is assigned to is removed when the animation stops assuming it belongs to this animator.
- auto easing(AnimationHandle handle) -> auto
- Animation easing function.
- auto easing(AnimatorDataHandle handle) -> auto
- Animation easing function assuming it belongs to this animator.
Function documentation
Magnum:: Ui:: NodeAnimator:: NodeAnimator(AnimatorHandle handle) explicit
Constructor.
Parameters | |
---|---|
handle | Handle returned by AbstractUserInterface:: |
Magnum:: Ui:: NodeAnimator:: NodeAnimator(NodeAnimator&&) noexcept
Move constructor.
Performs a destructive move, i.e. the original object isn't usable afterwards anymore.
AnimationHandle Magnum:: Ui:: NodeAnimator:: create(const NodeAnimation& animation,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
NodeHandle node,
UnsignedInt repeatCount = 1,
AnimationFlags flags = {})
Create an animation.
Parameters | |
---|---|
animation | Offset, size, opacity and flag animation properties |
easing | Easing function between 0.0f and 1.0f , used for offset, size and opacity. Pick one from Animation:: |
start | Time at which the animation starts. Use Nanoseconds:: |
duration | Duration of a single play of the animation |
node | Node the animation is attached to. Use NodeHandle:: |
repeatCount | Repeat count. Use 0 for an indefinitely repeating animation. |
flags | Flags |
Expects that easing
is not nullptr
if animation
affects node offset, size or opacity. Delegates to AbstractAnimator::
AnimationHandle Magnum:: Ui:: NodeAnimator:: create(const NodeAnimation& animation,
Float(*)(Float) easing,
Nanoseconds start,
Nanoseconds duration,
NodeHandle node,
AnimationFlags flags)
Create an animation.
Same as calling create(const NodeAnimation&, Float(*)(Float), Nanoseconds, Nanoseconds, NodeHandle, UnsignedInt, AnimationFlags) with repeatCount
set to 1
.
void Magnum:: Ui:: NodeAnimator:: remove(AnimationHandle handle)
Remove an animation.
Delegates to AbstractAnimator::
void Magnum:: Ui:: NodeAnimator:: remove(AnimatorDataHandle handle)
Remove an animation assuming it belongs to this animator.
Like remove(AnimationHandle) but delegates to AbstractAnimator::
Containers:: Pair<Vector2, Vector2> Magnum:: Ui:: NodeAnimator:: offsets(AnimationHandle handle) const
Animation source and target offsets.
Expects that handle
is valid. Components that are NaN are taken from the AbstractUserInterface at the time the animation starts. If a component is a NaN in both the source and the target offset, it's not animated at all.
Containers:: Pair<Vector2, Vector2> Magnum:: Ui:: NodeAnimator:: offsets(AnimatorDataHandle handle) const
Animation source and target offsets assuming it belongs to this animator.
Like offsets(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
Containers:: Pair<Vector2, Vector2> Magnum:: Ui:: NodeAnimator:: sizes(AnimationHandle handle) const
Animation source and target sizes.
Expects that handle
is valid. Components that are NaN are taken from the AbstractUserInterface at the time the animation starts. If a component is a NaN in both the source and the target size, it's not animated at all.
Containers:: Pair<Vector2, Vector2> Magnum:: Ui:: NodeAnimator:: sizes(AnimatorDataHandle handle) const
Animation source and target sizes assuming it belongs to this animator.
Like sizes(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
Containers:: Pair<Float, Float> Magnum:: Ui:: NodeAnimator:: opacities(AnimationHandle handle) const
Animation source and target opacities.
Expects that handle
is valid. Values that are NaN are taken from the AbstractUserInterface at the time the animation starts. If both the source and the target opacity is a NaN, it's not animated at all.
Containers:: Pair<Float, Float> Magnum:: Ui:: NodeAnimator:: opacities(AnimatorDataHandle handle) const
Animation source and target opacities assuming it belongs to this animator.
Like opacities(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
Containers:: Pair<NodeFlags, NodeFlags> Magnum:: Ui:: NodeAnimator:: flagsAdd(AnimationHandle handle) const
Node flags to add at animation begin and end.
Expects that handle
is valid.
Containers:: Pair<NodeFlags, NodeFlags> Magnum:: Ui:: NodeAnimator:: flagsAdd(AnimatorDataHandle handle) const
Node flags to add at animation begin and end assuming it belongs to this animator.
Like flagsAdd(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
Containers:: Pair<NodeFlags, NodeFlags> Magnum:: Ui:: NodeAnimator:: flagsClear(AnimationHandle handle) const
Node flags to clear at animation begin and end.
Expects that handle
is valid.
Containers:: Pair<NodeFlags, NodeFlags> Magnum:: Ui:: NodeAnimator:: flagsClear(AnimatorDataHandle handle) const
Node flags to clear at animation begin and end assuming it belongs to this animator.
Like flagsClear(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
bool Magnum:: Ui:: NodeAnimator:: hasRemoveNodeAfter(AnimationHandle handle) const
Whether the node the animation is assigned to is removed when the animation stops.
Expects that handle
is valid.
bool Magnum:: Ui:: NodeAnimator:: hasRemoveNodeAfter(AnimatorDataHandle handle) const
Whether the node the animation is assigned to is removed when the animation stops assuming it belongs to this animator.
Like hasRemoveNodeAfter(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.
auto Magnum:: Ui:: NodeAnimator:: easing(AnimationHandle handle)
Animation easing function.
Expects that handle
is valid. The returned pointer is only guaranteed to not be nullptr
if given animation affects node offset, size or opacity.
auto Magnum:: Ui:: NodeAnimator:: easing(AnimatorDataHandle handle)
Animation easing function assuming it belongs to this animator.
Like easing(AnimationHandle) const but without checking that handle
indeed belongs to this animator. See its documentation for more information.