![]() |
ImFusion SDK 4.3
|
Animating objects within the ImFusion SDK. More...
Animating objects within the ImFusion SDK.
Any object or parameter within the ImFusionLib can be animated in order to have a smooth transition/appearance to the user. Conceptually, an animation is a function that is called repeatedly for a specified time frame with a progress indicator t
interpolated between 0.0 and 1.0 according to the duration and time passed since start. Practically, they are usually used to draw the user's attention to a change and/or to make your program feel more natural. This part of the SDK is implemented in the ImFusion::Animations namespace.
The Animation class represents a single animation and has a duration, which is the time it takes for the animation to transition from its initial state to its final state. The optimal duration for a UI transition animation is between 200 and 500 milliseconds. An animation of 100 ms seems instantaneous to the user, while an animation exceeding 1 second is disruptive to the user's flow of thought. See here for more information.
The rate of change (acceleration) of the animation's transition is determined by its EasingFunction. Our framework comes with a set of predefined easing functions. However, you can also define custom ones in case you need full flexibility. See here for more details.
The following example shows how you can use an Animation in your application.
There are a few things to notice in the code snippet above. Most importantly, the object being animated, in this case car
, must stay alive for at least the duration of the animation. You will notice the lambda function passed as the argument to Animation
's constructor captures the surrounding variables by value. That is, the lambda makes a copy of the pointer to car
and the start
and finish
positions.
Alternatively, if you don't want to manually take care of the lifetime management, you can connect to the Animation::signalUpdated signal instead of passing a callable directly to the Animation constructor. Using the signal interface enables you to utilize the lifetime management implemented with SignalReceiver. See Signals and Slots for more details.
Both the update function passed to the constructor and the signalUpdated
signal are called repeatedly with increasing values from 0.0 to 1.0. In case you need a finalizer of the animation, you can implement that in the update function for the case with t = 1.0
. The animation framwork will ensure that all animations will be updated with t = 1.0
as very last step unless canceled.
Animations are managed by the AnimationBackend interface, which takes care of dispatching and calling the update()
function at a regular time interval with the correct progress value t
. Since this functionality usually requires some form of event loop it is encapsulated in concrete derived classes of this interface. This enables you to choose an adequate backend for your application environment.
Our SDK currently comes with two available backends: AnimationBackendDummy will not execute any animation but only call its update() function exactly once with t = 1.0
. AnimationBackendQt will use the Qt event loop for dispatching the animation updates and is the default for GUI applications based on MainWindowBase.
For convenience, our framework comes with a global backend that you can install through Animations::setBackend() if needed. All free functions in the Animations namespace (such as Animations::runAnimation() or Animations::runLoopedAnimation()) will work on this global backend accessible from everywhere.
The animation backend can be disabled on demand (Animations::enableAnimations(), AnimationBackendBase::setEnabled()). If new animations are run while the backend is disabled the animation will not be dispatched but instead its update functionwill be called once with t = 1.0
so that the animation reaches its final state immediately. It is often convenient to temporarily disable animations and return the enabled status to whatever it was before. This can be achieved with the ScopedEnabler, for example:
Furthermore, you can configure a animation speed multiplier for the backend that enables you to change the speed of all animations consistently.
Normally, when launching multiple animations all of them will run independently until they are finished. However, sometimes you may wish to abort an animation currently in flight when adding a new animation of "the same kind" so that they don't interfere with each other.
You can use the Animations::UniqueId interface to help you in this situation: When you pass an instance of this type when running an animation the backend will cancel any running animations with the same ID before starting the new one. A unique ID can be described by the address of an object (usually you would pass the this
pointer of the caller if it was allocated on the heap), by a string identifier of sufficient uniqueness, or the combination of both.
Due to the asynchronous nature of animations, the main API of the Animations framework is thread-safe. This means that you can access an Animation object as well as the (global) backend from any thread in a safe fashion. However, this does obviously not include the callback function itself. Thus, it is your responsibility as the creator of an animation to ensure that whatever resources get updated while the Animation runs are not also being accessed or modifed by other threads.
Classes | |
class | AnimationBackendQt |
Concrete implementation of AnimationBackendBase using the Qt event loop for dispatching the animation updates. More... | |
struct | UniqueId |
Helper struct to uniquely describe a type of annotation. More... | |
class | ScopedEnabler |
A scope guard to set the globally available enabled property for animations. More... | |
class | Animation |
Helper class to define an animation, that is an interpolated transition between two states. More... | |
class | AnimationBackendBase |
Base interface for managing and dispatching animations. More... | |
class | AnimationBackendDummy |
Dummy implementation of the AnimationBackendBase interface that will not execute any animation but only call its update() function exactly once with t=1.0. More... | |
Functions | |
std::unique_ptr< AnimationBackendBase > | setBackend (std::unique_ptr< AnimationBackendBase > backend) |
Install a global animation backend that is used by the set of free functions in this namespace. | |
void | runAnimation (std::shared_ptr< Animation > animation, const std::optional< UniqueId > &uniqueId=std::nullopt) |
Run the given animation on the globally installed backend. | |
std::shared_ptr< Animation > | runAnimation (std::function< void(double t)> &&updateFunc, std::chrono::milliseconds duration=std::chrono::milliseconds(500), EasingCurve easingCurve=EasingCurve::InOutCubic, const std::optional< UniqueId > &uniqueId=std::nullopt) |
Create and run a one-shot animation with the given configuration on the globally installed backend. | |
std::shared_ptr< Animation > | runLoopedAnimation (std::function< void(double)> &&updateFunc, std::chrono::milliseconds duration=std::chrono::milliseconds(500), EasingCurve easingCurve=EasingCurve::InOutCubic, const std::optional< UniqueId > &uniqueId=std::nullopt) |
Create and run a looped animation with the given configuration on the globally installed backend. | |
bool | animationsEnabled () |
Check whether the animations are globally enabled within the application. | |
void | enableAnimations (bool enabled) |
Globally enable or disable animations within the application. | |
double | animationDurationFactor () |
Returns the duration multiplier for run animations; enables you to change the speed of all animations consistently. | |
void | setAnimationDurationFactor (double value) |
Sets the duration multiplier for run animations, must be >= 0; enables you to change the speed of all animations consistently. | |
void | cancelAnimation (const UniqueId &id) |
Cancels the animation with the given id. | |
void | cancelAllAnimations () |
Cancels all animations currently in flight. | |
std::unique_ptr< AnimationBackendBase > setBackend | ( | std::unique_ptr< AnimationBackendBase > | backend | ) |
#include <ImFusion/GUI/Animations.h>
Install a global animation backend that is used by the set of free functions in this namespace.
The provided backend must not be null. Returns the previously installed animation backend.
void runAnimation | ( | std::shared_ptr< Animation > | animation, |
const std::optional< UniqueId > & | uniqueId = std::nullopt ) |
#include <ImFusion/GUI/Animations.h>
Run the given animation on the globally installed backend.
animation | Animation to execute, must not be null. |
uniqueId | Optional identifier for this animation to prevent multiple concurrent animations of the same ID. If not empty, the backend will cancel any running animations with the same ID before starting the new one. Make sure to use a sufficiently unique ID to avoid conflicts with other users of this interface. |
t = 1.0
so that the animation reaches its final state immediately. std::shared_ptr< Animation > runAnimation | ( | std::function< void(double t)> && | updateFunc, |
std::chrono::milliseconds | duration = std::chrono::milliseconds(500), | ||
EasingCurve | easingCurve = EasingCurve::InOutCubic, | ||
const std::optional< UniqueId > & | uniqueId = std::nullopt ) |
#include <ImFusion/GUI/Animations.h>
Create and run a one-shot animation with the given configuration on the globally installed backend.
The created Animation object is returned to enable you to keep track of it or cancel it from the outside.
updateFunc | Callback function that is called at regular time intervals with t having values interpolated between 0.0 and 1.0 according to the duration and time passed since start. |
duration | Duration of the animation, will be multiplied with the global animationSpeed(). |
easingCurve | Optional easing curve describing the speed of the interpolation between 0.0 and 1.0. |
uniqueId | Optional identifier for this animation to prevent multiple concurrent animations of the same ID. If not empty, the backend will cancel any running animations with the same ID before starting the new one. Make sure to use a sufficiently unique ID to avoid conflicts with other users of this interface. |
t = 1.0
so that the animation reaches its final state immediately. std::shared_ptr< Animation > runLoopedAnimation | ( | std::function< void(double)> && | updateFunc, |
std::chrono::milliseconds | duration = std::chrono::milliseconds(500), | ||
EasingCurve | easingCurve = EasingCurve::InOutCubic, | ||
const std::optional< UniqueId > & | uniqueId = std::nullopt ) |
#include <ImFusion/GUI/Animations.h>
Create and run a looped animation with the given configuration on the globally installed backend.
The created Animation object is returned to enable you to keep track of it or cancel it from the outside.
updateFunc | Callback function that is called at regular time intervals with t having values interpolated between 0.0 and 1.0 according to the duration and time passed since start. |
duration | Duration of the animation, will be multiplied with the global animationSpeed(). |
easingCurve | Optional easing curve describing the speed of the interpolation between 0.0 and 1.0. |
uniqueId | Optional identifier for this animation to prevent multiple concurrent animations of the same ID. If not empty, the backend will cancel any running animations with the same ID before starting the new one. Make sure to use a sufficiently unique ID to avoid conflicts with other users of this interface. |
t = 1.0
so that the animation reaches its final state immediately.