doc/src/frameworks-technologies/animation.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \group animation
       
    44     \title Animation Framework
       
    45 */
       
    46 
       
    47 /*!
       
    48     \page animation-overview.html
       
    49     \title The Animation Framework
       
    50 
       
    51     \brief An overview of the Animation Framework
       
    52 
       
    53     \ingroup frameworks-technologies
       
    54 
       
    55     \keyword Animation
       
    56 
       
    57     The animation framework is part of the Kinetic project, and aims
       
    58     to provide an easy way for creating animated and smooth GUI's.  By
       
    59     animating Qt properties, the framework provides great freedom for
       
    60     animating widgets and other \l{QObject}s. The framework can also
       
    61     be used with the Graphics View framework.
       
    62 
       
    63     In this overview, we explain the basics of its architecture. We
       
    64     also show examples of the most common techniques that the
       
    65     framework allows for animating QObjects and graphics items.
       
    66 
       
    67     \tableofcontents
       
    68 
       
    69     \section1 The Animation Architecture
       
    70 
       
    71     We will in this section take a high-level look at the animation
       
    72     framework's architecture and how it is used to animate Qt
       
    73     properties. The following diagram shows the most important classes
       
    74     in the animation framework.
       
    75 
       
    76     \image animations-architecture.png
       
    77 
       
    78     The animation framework foundation consists of the base class
       
    79     QAbstractAnimation, and its two subclasses QVariantAnimation and
       
    80     QAnimationGroup. QAbstractAnimation is the ancestor of all
       
    81     animations. It represents basic properties that are common for all
       
    82     animations in the framework; notably, the ability to start, stop,
       
    83     and pause an animation. It is also receives the time change
       
    84     notifications.
       
    85 
       
    86     The animation framework further provides the QPropertyAnimation
       
    87     class, which inherits QVariantAnimation and performs animation of
       
    88     a Qt property, which is part of Qt's \l{Meta-Object
       
    89     System}{meta-object system}. The class performs an interpolation
       
    90     over the property using an easing curve. So when you want to
       
    91     animate a value, you can declare it as a property and make your
       
    92     class a QObject. Note that this gives us great freedom in
       
    93     animating already existing widgets and other \l{QObject}s.
       
    94 
       
    95     Complex animations can be constructed by building a tree structure
       
    96     of \l{QAbstractAnimation}s. The tree is built by using
       
    97     \l{QAnimationGroup}s, which function as containers for other
       
    98     animations. Note also that the groups are subclasses of
       
    99     QAbstractAnimation, so groups can themselves contain other groups.
       
   100 
       
   101     The animation framework can be used on its own, but is also
       
   102     designed to be part of the state machine framework (See the
       
   103     \l{The State Machine Framework}{state machine framework} for an
       
   104     introduction to the Qt state machine). The state machine provides
       
   105     a special state that can play an animation. A QState can also set
       
   106     properties when the state is entered or exited, and this special
       
   107     animation state will interpolate between these values when given a
       
   108     QPropertyAnimation. We will look more closely at this later.
       
   109 
       
   110     Behind the scenes, the animations are controlled by a global
       
   111     timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to
       
   112     all animations that are playing.
       
   113 
       
   114     For detailed descriptions of the classes' function and roles in
       
   115     the framework, please look up their class descriptions.
       
   116 
       
   117     \section1 Classes in the Animation Framework
       
   118     
       
   119     These classes provide a framework for creating both simple and complex
       
   120     animations.
       
   121 
       
   122     \annotatedlist animation
       
   123 
       
   124     \section1 Animating Qt Properties
       
   125 
       
   126     As mentioned in the previous section, the QPropertyAnimation class
       
   127     can interpolate over Qt properties. It is this class that should
       
   128     be used for animation of values; in fact, its superclass,
       
   129     QVariantAnimation, is an abstract class, and cannot be used
       
   130     directly.
       
   131 
       
   132     A major reason we chose to animate Qt properties is that it
       
   133     presents us with freedom to animate already existing classes in
       
   134     the Qt API. Notably, the QWidget class (which we can also embed in
       
   135     a QGraphicsView) has properties for its bounds, colors, etc.
       
   136     Let's look at a small example:
       
   137 
       
   138     \code
       
   139         QPushButton button("Animated Button");
       
   140         button.show();
       
   141 
       
   142         QPropertyAnimation animation(&button, "geometry");
       
   143         animation.setDuration(10000);
       
   144         animation.setStartValue(QRect(0, 0, 100, 30));
       
   145         animation.setEndValue(QRect(250, 250, 100, 30));
       
   146 
       
   147         animation.start();
       
   148     \endcode
       
   149 
       
   150     This code will move \c button from the top left corner of the
       
   151     screen to the position (250, 250) in 10 seconds (10000 milliseconds).
       
   152 
       
   153     The example above will do a linear interpolation between the
       
   154     start and end value. It is also possible to set values
       
   155     situated between the start and end value. The interpolation
       
   156     will then go by these points.
       
   157 
       
   158     \code
       
   159         QPushButton button("Animated Button");
       
   160         button.show();
       
   161 
       
   162         QPropertyAnimation animation(&button, "geometry");
       
   163         animation.setDuration(10000);
       
   164 
       
   165         animation.setKeyValueAt(0, QRect(0, 0, 100, 30));
       
   166         animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));
       
   167         animation.setKeyValueAt(1, QRect(0, 0, 100, 30));
       
   168 
       
   169         animation.start();
       
   170     \endcode
       
   171 
       
   172     In this example, the animation will take the button to (250, 250)
       
   173     in 8 seconds, and then move it back to its original position in
       
   174     the remaining 2 seconds. The movement will be linearly
       
   175     interpolated between these points.
       
   176 
       
   177     You also have the possibility to animate values of a QObject
       
   178     that is not declared as a Qt property. The only requirement is
       
   179     that this value has a setter. You can then subclass the class
       
   180     containing the value and declare a property that uses this setter.
       
   181     Note that each Qt property requires a getter, so you will need to
       
   182     provide a getter yourself if this is not defined.
       
   183 
       
   184     \code
       
   185         class MyGraphicsRectItem : public QObject, public QGraphicsRectItem
       
   186         {
       
   187             Q_OBJECT
       
   188             Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry)
       
   189         };
       
   190     \endcode
       
   191 
       
   192     In the above code example, we subclass QGraphicsRectItem and
       
   193     define a geometry property. We can now animate the widgets
       
   194     geometry even if QGraphicsRectItem does not provide the geometry
       
   195     property.
       
   196 
       
   197     For a general introduction to the Qt property system, see its
       
   198     \l{Qt's Property System}{overview}.
       
   199 
       
   200     \section1 Animations and the Graphics View Framework
       
   201 
       
   202     When you want to animate \l{QGraphicsItem}s, you also use
       
   203     QPropertyAnimation. However, QGraphicsItem does not inherit QObject.
       
   204     A good solution is to subclass the graphics item you wish to animate.
       
   205     This class will then also inherit QObject.
       
   206     This way, QPropertyAnimation can be used for \l{QGraphicsItem}s.
       
   207     The example below shows how this is done. Another possibility is
       
   208     to inherit QGraphicsWidget, which already is a QObject.
       
   209 
       
   210     \code
       
   211         class Pixmap : public QObject, public QGraphicsPixmapItem
       
   212         {
       
   213             Q_OBJECT
       
   214             Q_PROPERTY(QPointF pos READ pos WRITE setPos)
       
   215             ...
       
   216     \endcode
       
   217 
       
   218     As described in the previous section, we need to define
       
   219     properties that we wish to animate.
       
   220 
       
   221     Note that QObject must be the first class inherited as the
       
   222     meta-object system demands this.
       
   223 
       
   224     \section1 Easing Curves
       
   225 
       
   226     As mentioned, QPropertyAnimation performs an interpolation between
       
   227     the start and end property value. In addition to adding more key
       
   228     values to the animation, you can also use an easing curve. Easing
       
   229     curves describe a function that controls how the speed of the
       
   230     interpolation between 0 and 1 should be, and are useful if you
       
   231     want to control the speed of an animation without changing the
       
   232     path of the interpolation.
       
   233 
       
   234     \code
       
   235         QPushButton button("Animated Button");
       
   236         button.show();
       
   237 
       
   238         QPropertyAnimation animation(&button, "geometry");
       
   239         animation.setDuration(3000);
       
   240         animation.setStartValue(QRect(0, 0, 100, 30));
       
   241         animation.setEndValue(QRect(250, 250, 100, 30));
       
   242 
       
   243         animation.setEasingCurve(QEasingCurve::OutBounce);
       
   244 
       
   245         animation.start();
       
   246     \endcode
       
   247 
       
   248     Here the animation will follow a curve that makes it bounce like a
       
   249     ball as if it was dropped from the start to the end position.
       
   250     QEasingCurve has a large collection of curves for you to choose
       
   251     from. These are defined by the QEasingCurve::Type enum. If you are
       
   252     in need of another curve, you can also implement one yourself, and
       
   253     register it with QEasingCurve.
       
   254 
       
   255     \omit Drop this for the first Lab release
       
   256     (Example of custom easing curve (without the actual impl of
       
   257     the function I expect)
       
   258     \endomit
       
   259 
       
   260     \section1 Putting Animations Together
       
   261 
       
   262     An application will often contain more than one animation. For
       
   263     instance, you might want to move more than one graphics item
       
   264     simultaneously or move them in sequence after each other.
       
   265 
       
   266     The subclasses of QAnimationGroup (QSequentialAnimationGroup and
       
   267     QParallelAnimationGroup) are containers for other animations so
       
   268     that these animations can be animated either in sequence or
       
   269     parallel. The QAnimationGroup is an example of an animation that
       
   270     does not animate properties, but it gets notified of time changes
       
   271     periodically. This enables it to forward those time changes to its
       
   272     contained animations, and thereby controlling when its animations
       
   273     are played.
       
   274 
       
   275     Let's look at code examples that use both
       
   276     QSequentialAnimationGroup and QParallelAnimationGroup, starting
       
   277     off with the latter.
       
   278 
       
   279     \code
       
   280         QPushButton *bonnie = new QPushButton("Bonnie");
       
   281         bonnie->show();
       
   282 
       
   283         QPushButton *clyde = new QPushButton("Clyde");
       
   284         clyde->show();
       
   285 
       
   286         QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");
       
   287         // Set up anim1
       
   288 
       
   289         QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");
       
   290         // Set up anim2
       
   291 
       
   292         QParallelAnimationGroup *group = new QParallelAnimationGroup;
       
   293         group->addAnimation(anim1);
       
   294         group->addAnimation(anim2);
       
   295 
       
   296         group->start();
       
   297     \endcode
       
   298 
       
   299     A parallel group plays more than one animation at the same time.
       
   300     Calling its \l{QAbstractAnimation::}{start()} function will start
       
   301     all animations it governs.
       
   302 
       
   303     \code
       
   304         QPushButton button("Animated Button");
       
   305         button.show();
       
   306 
       
   307         QPropertyAnimation anim1(&button, "geometry");
       
   308         anim1.setDuration(3000);
       
   309         anim1.setStartValue(QRect(0, 0, 100, 30));
       
   310         anim1.setEndValue(QRect(500, 500, 100, 30));
       
   311 
       
   312         QPropertyAnimation anim2(&button, "geometry");
       
   313         anim2.setDuration(3000);
       
   314         anim2.setStartValue(QRect(500, 500, 100, 30));
       
   315         anim2.setEndValue(QRect(1000, 500, 100, 30));
       
   316 
       
   317         QSequentialAnimationGroup group;
       
   318 
       
   319         group.addAnimation(&anim1);
       
   320         group.addAnimation(&anim2);
       
   321 
       
   322         group.start();
       
   323     \endcode
       
   324 
       
   325     As you no doubt have guessed, QSequentialAnimationGroup plays
       
   326     its animations in sequence. It starts the next animation in
       
   327     the list after the previous is finished.
       
   328 
       
   329     Since an animation group is an animation itself, you can add
       
   330     it to another group. This way, you can build a tree structure
       
   331     of animations which specifies when the animations are played
       
   332     in relation to each other.
       
   333 
       
   334     \section1 Animations and States
       
   335 
       
   336     When using a \l{The State Machine Framework}{state machine}, we
       
   337     can associate one or more animations to a transition between states
       
   338     using a QSignalTransition or QEventTransition class. These classes
       
   339     are both derived from QAbstractTransition, which defines the
       
   340     convenience function \l{QAbstractTransition::}{addAnimation()} that
       
   341     enables the appending of one or more animations triggered when the
       
   342     transition occurs.
       
   343 
       
   344     We also have the possibility to associate properties with the
       
   345     states rather than setting the start and end values ourselves.
       
   346     Below is a complete code example that animates the geometry of a
       
   347     QPushButton.
       
   348 
       
   349     \code
       
   350         QPushButton *button = new QPushButton("Animated Button");
       
   351         button->show();
       
   352 
       
   353         QStateMachine *machine = new QStateMachine;
       
   354 
       
   355         QState *state1 = new QState(machine->rootState());
       
   356         state1->assignProperty(button, "geometry", QRect(0, 0, 100, 30));
       
   357         machine->setInitialState(state1);
       
   358 
       
   359         QState *state2 = new QState(machine->rootState());
       
   360         state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));
       
   361 
       
   362         QSignalTransition *transition1 = state1->addTransition(button,
       
   363             SIGNAL(clicked()), state2);
       
   364         transition1->addAnimation(new QPropertyAnimation(button, "geometry"));
       
   365 
       
   366         QSignalTransition *transition2 = state2->addTransition(button,
       
   367             SIGNAL(clicked()), state1);
       
   368         transition2->addAnimation(new QPropertyAnimation(button, "geometry"));
       
   369 
       
   370         machine->start();
       
   371     \endcode
       
   372 
       
   373     For a more comprehensive example of how to use the state machine
       
   374     framework for animations, see the states example (it lives in the
       
   375     \c{examples/animation/states} directory).
       
   376 */
       
   377