All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
AnimatorExample.cpp

This example demonstrates how to use animators to create animations.

AnimatorExample-screenshot.png
Screenshot of the AnimatorExample example

For this example, we create a custom widget, called AnimatorWidget, by inheriting from MultiWidgets::Widget. In our custom widget, we define a function createAnimations() that creates random animations to all child widgets. We also override the MultiWidgets::Widget::singleTap function, and just call createAnimations() when the widget receives a single-tap event:

void AnimatorWidget::singleTap(MultiWidgets::GrabManager & , const MultiWidgets::TrackedObjectArray & )
{
createAnimations();
}

The actual animator objects are created in the createAnimations function. We begin by iterating over all children of the widget:

for(ChildIterator it = childBegin(); it != childEnd(); ++it) {

We begin by removing all Operators that we might created earlier from each child widget. As animators are operators themselves, this basically removes all existing animators of given type from the child widgets:

// Remove any old operators.
w->removeOperatorType<MultiWidgets::AnimatorVector2f>();
w->removeOperatorType<MultiWidgets::AnimatorScale>();
w->removeOperatorType<MultiWidgets::AnimatorVector4f>();

Creating the animators is simple. We just create a specific type of an animator and tell it to animate some attribute. For example, to animate the location attribute of a child widget, we do the following:

// Animate the location of the widget
auto a1 =
std::make_shared<MultiWidgets::AnimatorVector2f>("location");
// Start from current location:
a1->addKey(0.0f, w->location());
// Animate to random location:
a1->addKey(t, Nimble::Vector2(m_random.randRange(50, width() - 50),
m_random.randRange(50, height() - 50)));
w->addOperator(a1);

In the createAnimations function we also add animators for scale and background-color for each child widget. Finally, we also remove all operators from the AnimatorWidget itself and animate its background-color:

removeOperatorType<MultiWidgets::AnimatorVector4f>();
// Animate the color of this widget:
auto acolor =
std::make_shared<MultiWidgets::AnimatorVector4f>("background-color");
acolor->addKey(0, backgroundColor());
// Animate to some rather dark color:
acolor->addKey(m_random.randMinMax(0.1f, 5.0f),
Nimble::Vector4(m_random.rand0X(0.3f),
m_random.rand0X(0.3f),
m_random.rand0X(0.3f),
1.0f));
addOperator(acolor);

In the main function of the example, we just create an instance of the AnimatorWidget. We adjust its input flags to only accept single-taps and pass the input it receives to its children. Then we create five child widgets for it and execute the application. The source code for the example is listed below:

AnimatorWidget.cpp:

/* Copyright (C) 2007-2013 Multi Touch Oy, Finland, http://www.multitaction.com
*
* This file is part of MultiTouch Cornerstone.
*
* All rights reserved. You may use this file only for purposes for which you
* have a specific, written permission from Multi Touch Oy.
*
*/
#include "AnimatorWidget.hpp"
#include <MultiWidgets/Animators.hpp>
namespace Examples
{
AnimatorWidget::AnimatorWidget()
: Widget(),
m_random(Radiant::TimeStamp::currentTime().value()) // Use time as the random seed
{}
AnimatorWidget::~AnimatorWidget() {}
void AnimatorWidget::createAnimations()
{
for(ChildIterator it = childBegin(); it != childEnd(); ++it) {
// Remove any old operators.
w->removeOperatorType<MultiWidgets::AnimatorVector2f>();
w->removeOperatorType<MultiWidgets::AnimatorScale>();
w->removeOperatorType<MultiWidgets::AnimatorVector4f>();
float t = m_random.randMinMax(0.1f, 1.0f); // Animation time, in seconds
// Animate the location of the widget
auto a1 =
std::make_shared<MultiWidgets::AnimatorVector2f>("location");
// Start from current location:
a1->addKey(0.0f, w->location());
// Animate to random location:
a1->addKey(t, Nimble::Vector2(m_random.randRange(50, width() - 50),
m_random.randRange(50, height() - 50)));
w->addOperator(a1);
// Animate the scale of the widget:
auto a2 = std::make_shared<MultiWidgets::AnimatorScale>();
// Start from current scale:
a2->addKey(0.0, w->scale());
// Animate to random scale:
a2->addKey(t, m_random.randMinMax(0.2f, 2.4f));
w->addOperator(a2);
// Animate the color of the widget:
auto a3 =
std::make_shared<MultiWidgets::AnimatorVector4f>("background-color");
// Start from current color:
a3->addKey(0.0, w->backgroundColor());
// Animate to random color:
a3->addKey(t, Nimble::Vector4(m_random.rand01(),
m_random.rand01(),
m_random.rand01(),
m_random.randMinMax(0.5, 1.0)));
w->addOperator(a3);
}
removeOperatorType<MultiWidgets::AnimatorVector4f>();
// Animate the color of this widget:
auto acolor =
std::make_shared<MultiWidgets::AnimatorVector4f>("background-color");
acolor->addKey(0, backgroundColor());
// Animate to some rather dark color:
acolor->addKey(m_random.randMinMax(0.1f, 5.0f),
Nimble::Vector4(m_random.rand0X(0.3f),
m_random.rand0X(0.3f),
m_random.rand0X(0.3f),
1.0f));
addOperator(acolor);
}
void AnimatorWidget::singleTap(MultiWidgets::GrabManager & , const MultiWidgets::TrackedObjectArray & )
{
createAnimations();
}
}

AnimatorWidget.hpp:

/* Copyright (C) 2007-2013 Multi Touch Oy, Finland, http://www.multitaction.com
*
* This file is part of MultiTouch Cornerstone.
*
* All rights reserved. You may use this file only for purposes for which you
* have a specific, written permission from Multi Touch Oy.
*
*/
#ifndef MULTIANIMATE_ANIMATOR_WIDGET_HPP
#define MULTIANIMATE_ANIMATOR_WIDGET_HPP
#include <MultiWidgets/Widget.hpp>
#include <Nimble/Random.hpp>
namespace Examples
{
class AnimatorWidget : public MultiWidgets::Widget
{
public:
AnimatorWidget();
virtual ~AnimatorWidget();
void createAnimations();
protected:
virtual void singleTap(MultiWidgets::GrabManager & gm, const MultiWidgets::TrackedObjectArray & objs) OVERRIDE;
private:
};
}
#endif

AnimatorExample.cpp:

/* Copyright (C) 2007-2013 Multi Touch Oy, Finland, http://www.multitaction.com
*
* This file is part of MultiTouch Cornerstone.
*
* All rights reserved. You may use this file only for purposes for which you
* have a specific, written permission from Multi Touch Oy.
*
*/
#include "AnimatorWidget.hpp"
#include <MultiWidgets/Application.hpp>
#include <Nimble/Random.hpp>
int main(int argc, char ** argv)
{
if(!app.init(argc, argv))
return 1;
// Create the main widget that we are going to use.
auto mainwidget = MultiWidgets::create<Examples::AnimatorWidget>();
app.mainLayer()->addChild(mainwidget);
mainwidget->setSize(app.mainLayer()->size());
/* Make it capture taps, but not drag, scale or rotation. We pass
the input to the children, so that the user can interact with the
objects. */
mainwidget->setInputFlags(MultiWidgets::Widget::INPUT_SINGLE_TAPS |
// Create 5 white widgets
for(int i = 0; i < 5; i++) {
// Create a blank widget
auto w = MultiWidgets::create<MultiWidgets::Widget>();
mainwidget->addChild(w);
// Set widget parameters:
w->setSize(Nimble::SizeF(100, 100));
w->setLocation(Nimble::Vector2(i * 50, i * 50));
}
mainwidget->createAnimations();
// Run the application:
return app.run();
}