% Copyright 2016 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


\section{Animation System Layer}
\label{section-pgfsys-anim}

\makeatletter

\def\animationexample#1#2#3{%
  \tikz[fill=blue!25, draw=blue, ultra thick] {
    \pgfidrefnextuse{\objid}{#1}
    \pgfsysanimkeywhom{\objid}{#2}
    \pgfidrefnextuse{\nodeid}{node}
    \pgfsysanimkeyevent{\nodeid}{}{click}{}{begin}
    #3
    \node [font=\footnotesize, circle, fill, draw, align=center]
      (node) {Click \\ here};
  }%
}

In conjunction with the right output format (namely \textsc{svg}), you can
specify that certain parts of you graphics can be animated. For this, there are
a number of commands that cover, currently, what \textsc{svg 1.1} can do
regarding animations. For a detailed introduction to animations, please see
Section~\ref{section-base-animations}; the current section assumes that you are
familiar with the concepts explained there.

The animation system consists of two layer itself: Commands starting with
|\pgfsys@anim...| and commands starting with |\pgfsysanim|. These work as
follows:
%
\begin{enumerate}
    \item The commands starting with |\pgfsys@anim...| insert the actual
        animation commands into the output stream. A driver must implement
        these commands.
    \item The command starting with |\pgfsysanim...| provide an. These
        commands, which are the ones that should be called by higher layers,
        implement the snapshot mechanism: When the command
        |\pgfsysanimsnapshot| is used, the |\pgfsysanim...| commands do
        \emph{not} call the |\pgfsys@anim...| commands but, instead, insert
        non-animation commands to show the values of the attributes at the
        snapshot's time. To use this abstraction layer, you have to load the
        file |pgfsysanimations.code.tex|, which is not loaded by default (but
        is loaded by the \pgfname\ module |animations|).
\end{enumerate}

The bottom line is that if you wish to implement a new driver, you need to
implement the |\pgfsys@anim...| commands, if you use the animation layer, you
call the |\pgfsysanim...| commands.


\subsection{Animations and Snapshots}

To add an animation to a graphic, use the following command (as described
above, the first command is the one you actually call, the second is the one a
driver implements):

\begin{command}{\pgfsysanimate\marg{attribute}}
\end{command}

\begin{command}{\pgfsys@animate\marg{attribute}}
    The system layer animation subsystem follows the following philosophy: An
    animation always concerns an \emph{attribute} of a \emph{graphic object}. A
    \emph{timeline} specifies how the attribute changes its value over time.
    Finally, a set of \emph{keys} configures the animation as a whole like
    whether the timeline repeats or a event that triggers the start of the
    animation. The four parts of an animation, namely the \emph{attribute}, the
    \emph{graphic object}, the \emph{timeline}, and the \emph{keys}, are
    specified in different ways:
    %
    \begin{enumerate}
        \item You choose the \emph{attribute} using the system layer command
            |\pgfsysanimate|.
        \item The \emph{graphic object} whose attribute is to be animated is
            \emph{always} specified by naming the ID of the graphic object
            \emph{before} this object is created, see
            Section~\ref{section-sys-id}. (However, in the context of
            \tikzname, it suffices that the animation is given in the object's
            options since these are executed before the actual object is
            created).
        \item The \emph{timeline} is specified using the commands
            |\pgfsysanimkeytime|, which specifies a time in seconds, and
            |\pgfsys@animation@val...|, which specify a value at this
            particular time. The timeline specifies for a sequence of times the
            values the attribute will have at these times. In between these
            \emph{key times,} the value is interpolated.
        \item The \emph{animation keys} are specified by commands starting
            |\pgfsys@animation@...| and have the following effect: They set
            some property (like, say, whether the animation repeats or whether
            its effect is additive) to a given value \emph{for the current
            \TeX\ scope,} but do not create any animations. Rather, when
            |\pgfsysanimate| is called, a snapshot of the current values of all
            animation keys is taken and added to this animation of the
            attribute.

            When you set an animation key to a value, this will replace the
            value previously stored for the key (all keys are empty by default
            at the beginning).

            Note that animation keys are local to \TeX\ scopes, not graphics
            scopes; indeed, they have little to do with the settings of the
            graphics scope other than the fact that a graphic scope is also a
            \TeX\ scope and thereby influence the values of these keys.
    \end{enumerate}

    A typical example of how all of this works is the following:
    %
\begin{codeexample}[code only]
\pgfsysanimkeyrepeatindefinite % Both of the following animations
                                    % repeat indefinitely
{
  \pgfsysanimkeywhom{\someid}{}% The id of a later object
  \pgfsysanimkeyevent{}{}{click}{0}{begin}% Begin on a click ...
  \pgfsysanimkeytime{5}{1}{1}{0}{0} % Timeline starts after 5s
  \pgfsysanimvalscalar{0} % With a value of 0
  \pgfsysanimkeytime{8}{1}{1}{0}{0} % Timeline ends after 8s
  \pgfsysanimvalscalar{0.9} % With a value of 0.9
  \pgfsysanimate{fillopacity}% ... and the attribute is the fill opacity
}
{
  \pgfsysanimkeywhom{\someid}{}% The id of a later object
  \pgfsysanimkeyoffset{0}{begin}% Begin right away ...
  \pgfsysanimkeytime{1}{1}{1}{0}{0} % Timeline starts after 1s
  \pgfsysanimvalcurrent % With the current value
  \pgfsysanimkeytime{5}{1}{1}{0}{0} % Timeline ends after 5s
  \pgfsysanimvaldimension{5pt} % With a value of 5pt
  \pgfsysanimate{linewidth}% ... and the attribute is the line width
}
\end{codeexample}
    %
    As a real-life example, consider the following definitions, which will be
    used in many examples in the rest of this section: Both take three
    parameters: The \pgfname/\tikzname\ name of a to-be animated object, a type
    (relevant for objects that have subtypes or parts), and some code for
    triggering the actual animation. The animation will always start when the
    button is clicked. The second macro sets up things in such a way that the
    animation will last two seconds, while the first leaves the timing open.
    %
\begin{codeexample}[code only]
\def\animationexample#1#2#3{
  \tikz[fill=blue!25, draw=blue, ultra thick] {
    \pgfidrefnextuse{\objid}{#1}
    \pgfsysanimkeywhom{\objid}{#2}
    \pgfidrefnextuse{\nodeid}{node}
    \pgfsysanimkeyevent{\nodeid}{}{click}{}{begin}
    #3
    \node [font=\scriptsize, circle, fill, draw, align=center]
      (node) {Click \\ here};
  }
}
\end{codeexample}
    %
    Now the example, where the circle will disappear, when clicked:
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimate{opacity}
}
\end{codeexample}
    %
\end{command}

The ``opposite'' of |\pgfsysanimate| is the following command:

\begin{command}{\pgfsysanimsnapshot\marg{time}}
    Use this command in a scope prior to calling any other commands documented
    in this section concerning the configuration of animations. In this case,
    all uses of |\pgfsysanimate| inside the \TeX\ scope no longer insert an
    animation into the output file. Instead, a ``snapshot'' is inserted of what
    the animation ``would like at time \meta{time}''. For instance, if an
    animation inserts a movement of an object by 4cm over a time of 2s and you
    take a snapshot with $\meta{time} = 2\mathrm s$, you get a picture in which
    the object is moved by 1cm.

    A lot of care has been taken to make the output produced by the snapshot be
    as close as possible as what the animation really would look like at time
    \meta{time}, but note the following restrictions:
    %
    \begin{enumerate}
        \item Interactive events of all kinds (like |click| or |mouseover|)
            make little sense for snapshots, which are created once and for all
            during the typesetting of the document. For this reason, all events
            are ignored for snapshots (even sync bases, and |begin| and |end|
            events, which might make some sense also in a snapshot setting).

            However, there is one command which helps you with ``simulating''
            the effect of events:
            %
            \begin{command}{\pgfsysanimkeysnapshotstart\marg{time offset}}
                This command specifies that for the current animation the
                ``moment |0s|'' of the timeline is at \meta{time offset}. Thus,
                it works like |\pgfsysanimkeyoffset|, only the offset is now
                solely for the snapshot timeline. It has no effect on the
                actual animation.
            \end{command}
            %
        \item The command |\pgfsysanimvalcurrent| cannot be used with snapshots
            since \pgfname\ has no chance of computing the correct current
            value. You always have to specify the start value explicitly.
        \item The computation of time splines (entry and exit splines) and the
            accumulation of values after a large number of repeats may not be
            numerically stable.
    \end{enumerate}
    %
\begin{codeexample}[width=5cm]
\foreach \t in {0.5,1,1.5,2} {
  \pgfsysanimsnapshot{\t}
  \tikz {
    \pgfidrefnextuse{\objid}{node}
    \pgfsysanimkeywhom{\objid}{}
    \pgfsysanimkeytime{0}{1}{1}{0}{0}
    \pgfsysanimvalscalar{1}
    \pgfsysanimkeytime{2}{1}{1}{0}{0}
    \pgfsysanimvalscalar{0}
    \pgfsysanimate{opacity}
    \node (node) [draw = blue, very thick, fill=blue!20, circle] {Hi};
  }
}
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimsnapshotafter\marg{time}}
    Works like the previous command, only the ``moment'' that \meta{time}
    refers to is conceptually $\meta{time} + \epsilon$: When timeline specifies
    several values for \meta{time}, this command will select the last value at
    \meta{time}, while |\pgfsnapshot| will select the first value at
    \meta{time}. Similarly, when a timeline ends at \meta{time}, |\pgfsnapshot|
    will select the last value of the timeline while |\pgfsnapshotafter| will
    not apply the animation any more.
\end{command}


\subsection{Commands for Animating an Attribute: Color, Opacity, Visibility, Staging}

The commands from this and the next sections specify that some attribute should
be animated. We start with rather basic animation attributes for color,
visibility, and opacity.

\begin{sysanimateattribute}{opacity}
    Adds an animation of the opacity to the graphic object specified using
    |\pgfsysanimkeywhom|. If the driver supports this, this is a bit different
    from animating the fill and stroke opacities individually: Paths are
    treated as transparency groups for this key. Typically, ``this is what you
    want''.

    Specify values with |\pgfsysanimvalscalar|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimate{opacity}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{fillopacity}
    Adds an animation of only the opacity of fill operations.

    Specify values with |\pgfsysanimvalscalar|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimate{fillopacity}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{strokeopacity}
    Adds an animation of only the opacity of draw (stroke) operations.

    Specify values with |\pgfsysanimvalscalar|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimate{strokeopacity}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{visibility}
    Adds an animation of the ``visibility''.

    Specify values with |\pgfsysanimvaltext|. However, only two values are
    allowed: |visible| and |hidden|.
    %
\begin{codeexample}[animation list={-1,0,1,2,3}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltext{hidden}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltext{hidden}
  \pgfsysanimate{visibility}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{strokecolor}
    Adds an animation of the stroke color.

    Specify values with |\pgfsysanimvalcolorrgb| and friends.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalcolorrgb{0}{0}{0}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalcolorrgb{1}{0}{0}
  \pgfsysanimate{strokecolor}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{fillcolor}
    Adds an animation of the fill color.

    Specify values with |\pgfsysanimvalcolorrgb| and friends.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalcolorrgb{0}{0}{0}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalcolorrgb{1}{0}{0}
  \pgfsysanimate{fillcolor}
}
\end{codeexample}
    %
\end{sysanimateattribute}


\subsection{Commands for Animating an Attribute: Paths and Their Rendering}

The following attributes influence paths and how they are rendered.

\begin{sysanimateattribute}{path}
    Adds an animation of the path itself. That means that the path will morph
    its form from one path to another. When morphing a path, all ``values'',
    which are the paths, must consist of the \emph{exact same} path
    construction commands; they may only differ with respect to the numbers
    used in these descriptions.

    Specify values with |\pgfsysanimvalpath|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2},animation bb={(0.9,-0.1)rectangle(2.1,1.1)}]
\animationexample{my path}{path}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalpath{\pgfsys@moveto{1cm}{0cm}%
                     \pgfsys@lineto{1cm}{1cm}%
                     \pgfsys@lineto{2cm}{0cm}}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalpath{\pgfsys@moveto{1cm}{1cm}%
                     \pgfsys@lineto{2cm}{1cm}%
                     \pgfsys@lineto{1cm}{0cm}}
  \pgfsysanimate{path}
  \filldraw [ultra thick,draw=blue,fill=blue!20, name=my path]
    (1,0) -- (1,1) -- (2,0); }
\end{codeexample}

    You can attach arrow tips to paths that are animated and these arrow tips
    will correctly ``rotate and move along'' with the path's end points
    \emph{if} you take the following points into considerations:
    %
    \begin{itemize}
        \item Arrow tips that ``rotate and move along'' with a path must be
            specified using a special animation command, see below. The normal
            arrow tips added to a path would \emph{not} be animated
            automatically and, indeed, if you add arrow tips to a path using
            |\pgfsetarrows| and then animate the path, you will get an error
            message.
        \item Internally, the arrow tips that ``rotate and move along'' are
            drawn using so-called \emph{markers.} These are little graphic
            objects that can be added to the start and end of paths and that
            are automatically rotated and move along with the path.

            In principle, the rendering rules used by \textsc{svg} for markers
            are the same as for normal arrow tips: The markers are rotated and
            moved so that the point along a tangent of the path at the start or
            end of the path. However, when it comes to special cases such as a
            path with multiple segments, a path with degenerate segments, a
            closed path, and so on, the rules used by for instance \textsc{svg}
            may differ from the placement that \pgfname\ will compute.

            Thus, it is best to add arrow tips only to ``normal'' paths
            consisting of a single open path segment whose ends can be
            shortened a bit without causing degeneration.
        \item When an arrow tip is added to a path, the path must typically be
            shortened a bit so that the \emph{tip} of the arrow ends where the
            path would usually end. This shortening is not done by the system
            layer for to-be-animated paths; you must compute and then animate
            these shortened paths yourself. (However, the basic layer animation
            module will do this for you, so you only have to worry about this
            when you use the system layer directly.)
    \end{itemize}

    Let us now have a look at how we add arrow tip markers:
    %
    \begin{command}{\pgfsysanimkeytipmarkers\marg{start marker}\marg{end marker}}
    \end{command}
    %
    \begin{command}{\pgfsys@animation@tip@markers\marg{start marker}\marg{end marker}}
        This command specifies that during a path animation the two markers
        provided as parameters should be added (and rotated and moved along
        with the path) at the start and end. The \meta{start marker} must
        either be empty (in which case no marker is added at the start) or it
        must be a macro storing a value returned by the command
        |\pgfsys@marker@declare|. In this case, the marker declared symbol will
        be added to the start during the animation. The same situation applies
        to the end of the path.

        As pointed out earlier, only arrow tips / markers added to paths using
        this command will be animated along with the path. In particular, you
        should \emph{not} add arrow tips to to-be-animated paths using
        |\pgfsetarrow|. However, when you use a base value
        (|\pgfsys@animation@base|) to set a path, the arrow tips will also be
        added to this base path.

        To sum up, the ``correct'' way of adding arrow tips to a path that is
        animated is to proceed as follows:
        %
        \begin{enumerate}
            \item You specify arrow tips for a path using this command.
            \item You specify times and values of the to-be-animated path,
                shortened as necessary to accommodate the length of the arrow
                tips.
            \item You specify the first (or, possibly, some other) value in the
                time--value sequence as a base value.
            \item You create a path animation that applies to a future path.
            \item You create this future path as an empty path without arrow
                tips and draw it. Because of the setting of the base value,
                instead of the empty path the base path will be used as the
                ``real'' path and the animation's arrow tips will be added as
                arrow tips.
        \end{enumerate}

        When you have more than one animation for a given path, these different
        animations may use different arrow tips / markers. This allows you to
        animate (change) which arrow tip is used on a path over time.
        %
\begin{codeexample}[animation list={0.5,1,1.5,2},animation bb={(0.7,-0.3)rectangle(2.3,1.3)}]
% Declare a marker:
\pgfsys@marker@declare\mymarker{%
  \pgfscope%
    \pgfsetcolor{red!75}%
    \pgfpathmoveto{\pgfpoint{0pt}{5pt}}\pgfpathlineto{\pgfpoint{8pt}{0pt}}%
    \pgfpathlineto{\pgfpoint{0pt}{0pt}}\pgfpathclose%
    \pgfusepathqfill%
  \endpgfscope%
  \pgfpathmoveto{\pgfpoint{0pt}{5pt}}\pgfpathlineto{\pgfpoint{8pt}{0pt}}%
  \pgfpathlineto{\pgfpoint{0pt}{-5pt}}\pgfpathclose%
  \pgfusepathqstroke%
}%
\animationexample{my path}{path}{
  \pgfsysanimkeytipmarkers{\mymarker}{\mymarker}
  \pgfsysanimkeybase
  \pgfsysanimvalpath{\pgfsys@moveto{1cm}{0cm}%
                     \pgfsys@lineto{1cm}{1cm}%
                     \pgfsys@lineto{2cm}{0cm}}
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalpath{\pgfsys@moveto{1cm}{0cm}%
                     \pgfsys@lineto{1cm}{1cm}%
                     \pgfsys@lineto{2cm}{0cm}}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalpath{\pgfsys@moveto{1cm}{1cm}%
                     \pgfsys@lineto{2cm}{1cm}%
                     \pgfsys@lineto{1cm}{0cm}}
  \pgfsysanimate{path}
  \filldraw [ultra thick,draw=blue,fill=blue!20, name=my path];
  \path (1,0) (2,1);}
\end{codeexample}
    \end{command}
\end{sysanimateattribute}

\begin{sysanimateattribute}{linewidth}
    Adds an animation of the line width.

    Specify values with |\pgfsysanimvaldimension|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaldimension{1pt}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaldimension{10pt}
  \pgfsysanimate{linewidth}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{dash}
    Adds an animation of the dash phase and pattern (like |\pgfsys@setdash|).

    Specify values with |\pgfsysanimvaldash|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaldash{1pt,10pt}{0pt}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaldash{10pt,3pt}{0pt}
  \pgfsysanimate{dash}
}
\end{codeexample}
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaldash{1cm,1pt}{0pt}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaldash{1cm,1pt}{1cm}
  \pgfsysanimate{dash}
}
\end{codeexample}
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaldash{3pt,1pt}{0pt}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaldash{1pt,3pt}{10pt}
  \pgfsysanimate{dash}
}
\end{codeexample}
    %
\end{sysanimateattribute}


\subsection{Commands for Animating an Attribute: Transformations  and Views}

The commands in this section allow you to animate the canvas transformation
matrix of a scope. However, there is one command that needs to be explained
first.

\begin{command}{\pgfsysanimkeycanvastransform\marg{pre}\marg{post}}
\end{command}
%
\begin{command}{\pgfsys@animation@canvas@transform\marg{pre}\marg{post}}
    In order to animate the canvas, you specify that, for instance, the canvas
    should be shifted over, say, one second by 2cm from left to right. In order
    to specify this, you specify that an additional shift should be added to
    the canvas transformation matrix that starts out as $(0,0)$ and ends at
    $(2\,\mathrm{cm},0)$. However, it is not immediately clear what ``to the
    right'' or $(2\,\mathrm{cm},0)$ actually means: ``Right'' relative to the
    paper? ``Right'' relative to the coordinate system at the point when the
    animation is created? ``Right'' relative to the object's local coordinate
    system?

    Using this command you can specify the coordinate system relative to which
    all canvas animations are specified. In detail, when you add an animation
    $a$ of the canvas of an object foo, the following happens:
    %
    \begin{enumerate}
        \item We start with the canvas transformation matrix that is installed
            when the object starts. More precisely, this is the canvas
            transformation matrix that is in force when the command
            |\pgfsys@begin@idscope| is called for the object. The canvas
            transformation matrix that is in force when the animation is
            created (which is typically ``way before'' the object is created
            and may even be in a totally different graphics scope) is
            irrelevant for the animation.
        \item Now, when the object is created, the code \meta{pre} is executed.
            It should call |\pgfsys@transformcm| at most once. This canvas
            transformation is added to the object's canvas transformation.
        \item Now, the animation $a$ of the canvas is relative to the resulting
            canvas transformation. That means, when the animation shifts the
            object ``to the right'' the animation will actually be along the
            current direction of ``right'' in the canvas transformation
            resulting from the two transformations above.
        \item Finally, at the point of creation of the to-be-animation object
            the code \meta{post} is executed. Again, the code should call
            |\pgfsys@transformcm| at most once. The resulting transformation is
            also added to the object's canvas transformation, but does
            \emph{not} influence the animation.
    \end{enumerate}

    The net effect of the above is that, normally, you use the \meta{pre} code
    to setup a transformation matrix relative to which you wish to perform your
    animation and, normally, you use \meta{post} to undo this transformation
    (using the inverted matrix) to ensure that when no animation is in force,
    the object is placed at the same position as if no animation were used.

    Let us now have a look at some examples. We use the following macro, which
    takes a pre and a post code and animates a red ball over 1cm to the right
    in two seconds and rotates the blue ball over 90$^\circ$ around the origin.
    The ball is placed at $(1,0)$.
    %
\begin{codeexample}[code only]
\def\animationcanvasexample#1#2{%
  \animationexample{ball}{}{%
    \pgfsysanimkeycanvastransform{#1}{#2}%
    \pgfsysanimkeytime{0}{1}{1}{0}{0}
    \pgfsysanimvaltranslate{0cm}{0cm}%
    \pgfsysanimkeytime{2}{1}{1}{0}{0}
    \pgfsysanimvaltranslate{1cm}{0cm}%
    \pgfsysanimate{translate}
    \fill [ball color=red,name=ball] (1,0) circle [radius=3mm]; }
  \animationexample{ball}{}{%
    \pgfsysanimkeycanvastransform{#1}{#2}%
    \pgfsysanimkeytime{0}{1}{1}{0}{0}
    \pgfsysanimvalscalar{0}%
    \pgfsysanimkeytime{2}{1}{1}{0}{0}
    \pgfsysanimvalscalar{90}%
    \pgfsysanimate{rotate}
    \fill [ball color=blue,name=ball] (1,0) circle [radius=3mm]; } }
\end{codeexample}
    %
\def\animationcanvasexample#1#2{%
  \animationexample{ball}{}{%
    \pgfsysanimkeycanvastransform{#1}{#2}%
    \pgfsysanimkeytime{0}{1}{1}{0}{0}
    \pgfsysanimvaltranslate{0cm}{0cm}%
    \pgfsysanimkeytime{2}{1}{1}{0}{0}
    \pgfsysanimvaltranslate{1cm}{0cm}%
    \pgfsysanimate{translate}
    \fill [ball color=red,name=ball] (1,0) circle [radius=3mm]; }
  \animationexample{ball}{}{%
    \pgfsysanimkeycanvastransform{#1}{#2}%
    \pgfsysanimkeytime{0}{1}{1}{0}{0}
    \pgfsysanimvalscalar{0}%
    \pgfsysanimkeytime{2}{1}{1}{0}{0}
    \pgfsysanimvalscalar{90}%
    \pgfsysanimate{rotate}
    \fill [ball color=blue,name=ball] (1,0) circle [radius=3mm]; } }

\begin{codeexample}[width=9.9cm,animation list={0.5,1,1.5,2}]
\animationcanvasexample
{}
{}
\end{codeexample}
    %
\begin{codeexample}[width=9.9cm,animation list={0.5,1,1.5,2}]
\animationcanvasexample
{\pgfsys@transformshift{10mm}{0mm}}
{\pgfsys@transformshift{-10mm}{0mm}}
\end{codeexample}
    %
\begin{codeexample}[width=9.9cm,animation list={0.5,1,1.5,2}]
\animationcanvasexample
{\pgfsys@transformcm{0.5}{0.5}{-0.5}{0.5}
                    {0pt}{0pt}}
{}
\end{codeexample}
    %
\begin{codeexample}[width=9.9cm,animation list={0.5,1,1.5,2}]
\animationcanvasexample
{\pgfsys@transformcm{0.5}{0.5}{-0.5}{0.5}
                    {0pt}{0pt}}
{\pgfsys@transformcm{1}{-1}{1}{1}
                    {0pt}{0pt}}
\end{codeexample}
    %
\end{command}

\begin{sysanimateattribute}{translate}
    Adds an (additional) translate animation. Effectively, this causes the
    group to be shifted to different positions.

    Specify values with |\pgfsysanimvaltranslate|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{5mm}{-1cm}
  \pgfsysanimate{translate}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{scale}
    Adds an animation of the scaling relative to the origin. This causes a
    scaling of the canvas, including fonts and line widths.

    Specify values with |\pgfsysanimvalscale|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscale{1}{1}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscale{0.5}{2}
  \pgfsysanimate{scale}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{rotate}
    Adds a rotation animation around the origin.

    Specify values with |\pgfsysanimvalscalar|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{90}
  \pgfsysanimate{rotate}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{skewx}
    Adds an animation of a skewing of the canvas along the $x$-axis. Unlike the
    |slant| options of \tikzname, the skew is given in degrees.

    Specify values with |\pgfsysanimvalscalar|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2}]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{45}
  \pgfsysanimate{skewx}
}
\end{codeexample}
    %
\end{sysanimateattribute}

\begin{sysanimateattribute}{skewy}
    Adds an animation of a skewing of the canvas along the $y$-axis.

    Specify values with |\pgfsysanimvalscalar|.
\end{sysanimateattribute}

\begin{sysanimateattribute}{motion}
    Works a bit like |\pgfsysanimvaltranslate|: It also adds an animated shift
    transformation of the canvas. However, instead of specifying some shift
    coordinates as values, you now specify a whole path (which may include
    curves). The effect is that an animated translate transformation for the
    different points on this path gets installed. Furthermore, if you use
    |\pgfsysanimkeyrotatealong|, an additional adaptive rotation transformation
    will be added so that the animated graphic scope ``points along'' the path.

    You specify the path along which you wish to move objects along using
    |\pgfsysanimkeymovealong|. You use the timeline to specify how far the
    object gets moved along this path using scalar values where |0| is the
    beginning of the path and |1| is the end. Thus, setting the timeline to the
    scalar value of |0| at time $t_0$ and to |1| at time $t_1$ will cause the
    object o move along the complete path between times $t_0$ and $t_1$.

    Specify values with |\pgfsysanimvalscalar|.

    \begin{command}{\pgfsysanimkeymovealong\marg{path}}
    \end{command}
    %
    \begin{command}{\pgfsys@animation@movealong\marg{path}}
        Defines the \meta{path} along which the motion will occur. It will
        simply be executed and must call |\pgfsys@lineto| and similar
        path-construction commands, but should not call other commands.
        %
\begin{codeexample}[animation list={0.5,1,1.5,2},render instead={
\animationexample{node}{}{
  \pgfsysanimkeymovealong{
    \pgfsyssoftpath@movetotoken{0pt}{0pt}
    \pgfsyssoftpath@linetotoken{0pt}{-5mm}
    \pgfsyssoftpath@curvetosupportatoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetosupportbtoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetotoken{-5mm}{-1cm} }
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimate{motion}
}
  }]
\animationexample{node}{}{
  \pgfsysanimkeymovealong{
    \pgfsyssoftpath@movetotoken{0pt}{0pt}
    \pgfsyssoftpath@linetotoken{0pt}{-5mm}
    \pgfsyssoftpath@curvetosupportatoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetosupportbtoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetotoken{-5mm}{-1cm} }
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimate{motion}
}
\end{codeexample}
    \end{command}

    \begin{command}{\pgfsysanimkeynorotatealong}
    \end{command}
    %
    \begin{command}{\pgfsys@animation@norotatealong}
        Indicates that no additional rotation should be added during the
        movement. This is the default.
    \end{command}

    \begin{command}{\pgfsysanimkeyrotatealong}
    \end{command}
    %
    \begin{command}{\pgfsys@animation@rotatealong}
        Indicates that the to-be-animated group should be rotated automatically
        so that it points along the path as time progresses. This option is
        only applicable to motion animations.
        %
\begin{codeexample}[animation list={0.5,1,1.5,2},render instead={
\animationexample{node}{}{
  \pgfsysanimkeyrotatealong
  \pgfsysanimkeymovealong{
    \pgfsyssoftpath@movetotoken{0pt}{0pt}
    \pgfsyssoftpath@linetotoken{0pt}{-5mm}
    \pgfsyssoftpath@curvetosupportatoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetosupportbtoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetotoken{-5mm}{-1cm} }
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimate{motion}
}}]
\animationexample{node}{}{
  \pgfsysanimkeyrotatealong
  \pgfsysanimkeymovealong{%
    \pgfsyssoftpath@movetotoken{0pt}{0pt}%
    \pgfsyssoftpath@linetotoken{0pt}{-5mm}%
    \pgfsyssoftpath@curvetosupportatoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetosupportbtoken{0pt}{-1cm}%
    \pgfsyssoftpath@curvetotoken{-5mm}{-1cm}}
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalscalar{0}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalscalar{1}
  \pgfsysanimate{motion}
}
\end{codeexample}
    \end{command}
\end{sysanimateattribute}

\begin{sysanimateattribute}{viewbox}
    Adds an animation of the view box. The graphic scope to which this
    animation is added must have been created using |\pgfsys@viewboxmeet| or
    |\pgfsys@viewboxslice|; adding it to other scopes has no effect. Note that
    this command does \emph{not} change or animate the scope's transformation
    matrix -- it only animates the ``what we see through the view box''.

    Specify values with |\pgfsysanimvalviewbox|.
    %
\begin{codeexample}[animation list={0.5,1,1.5,2},width=5cm,animation
  bb={(0.9,-2.1) rectangle (3.1,2.1)}]
\animationexample{my view}{view}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvalviewbox{-10mm}{-20mm}{10mm}{20mm}%
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvalviewbox{15mm}{-15mm}{27mm}{8mm}%
  \pgfsysanimate{viewbox}
  \scoped [xshift=2cm] {
    \draw [red] (-1,-2) rectangle (1,2) node [font=\scriptsize,
               below left, align=right] {original\\ view\\ box};
    \scoped [meet={(-1,-2) (1,2)}, name=my view]  {
      \draw (-5mm,-15mm) rectangle (7mm,8mm)
        node [font=\scriptsize, align=right, below left]
          {target\\ view\\ box};  ;
      \filldraw (0,0) circle [radius=3mm];
} } }
\end{codeexample}
    %
\end{sysanimateattribute}


\subsection{Commands for Specifying the Target Object}

\begin{command}{\pgfsysanimkeywhom\marg{id}\marg{type}}
\end{command}
%
\begin{command}{\pgfsys@animation@whom\marg{id}\marg{type}}
    Sets the target of the animation. The \marg{id} must previously have been
    created using |\pgfsys@new@id|, \marg{type} must be a type (the empty type
    is also allowed). See Section~\ref{section-sys-id} for details on ids and
    types.
\end{command}


\subsection{Commands for Specifying Timelines: Specifying Times}

Animations are specified using \emph{timelines}, which are functions mapping
times to values for these times. The functions are cubic splines, which are
specified using time--value pairs plus control points.

In order to specify a time--value pair, you first use the command
|\pgfsysanimkeytime| to specify a time. Next, you use |\pgfsysanimval...| to
specify a value, which adds the time--value pair to the timeline. Note that the
times must be given in non-decreasing order. Between time--value pairs, the
values are interpolated using a spline.

The first and last times of the timeline are a bit special: The timeline starts
on the first time and the duration of the timeline is the difference between
the first and last time. ``Starting'' on the start time actually means that any
beginnings (see the commands for specifying beginnings and endings) get as
offset the start time; similarly end times are offset by this value.

\begin{command}{\pgfsysanimkeytime\marg{time}\marg{entry spline
      control x}\marg{entry spline  control y}\marg{exit spline
      control x}\marg{exit spline control y}%
}
\end{command}
\begin{command}{\pgfsys@animation@time\marg{time}\marg{entry spline
      control x}\marg{entry spline  control y}\marg{exit spline
      control x}\marg{exit spline control y}%
}
    The \meta{time} is a number representing seconds (so |0.5| means 500\,ms).

    The spline between a time--value pair and the next is specified using the
    four parameters following the time. The first two of these specify the
    second control point of the interval preceding the time--value pair (called
    the ``entry'' control point), the last two parameters specify the first
    control point of the interval following the pair (called the ``exit''
    control point). Consider for instance, the following calls:
    %
\begin{codeexample}[code only]
\pgfsysanimkeytime{10}{0.1}{0.2}{0.3}{0.4}
\pgfsysanimvalscalar{100}
\pgfsysanimkeytime{15}{0.5}{0.6}{0.7}{0.8}
\pgfsysanimvalscalar{200}
\end{codeexample}
    %
    This will create (at least) the time interval $[10\,\mathrm s,15\,\mathrm
    s]$ and the control points for this interval will be $(0.3,0.4)$ and
    $(0.5,0.6)$.

    Control points are specified in a different ``coordinate'' system from the
    time--value pairs themselves: While the time--value pairs are specified
    using a number representing seconds and a value using some special
    commands, the control points are specified as numbers between $0$ and $1$,
    each time representing a fraction of the time interval or the value
    interval. In the example, the time interval is $[10\,\mathrm s,15\,\mathrm
    s]$ and the value interval is $[100,200]$. This means that a control point
    of $(0.3,0.4)$ actually refers to the time--value $(11.5\,\mathrm s,140)$.
    The ``time--value curve'' in the interval thus ``\texttt{(10s,100) ..
    controls (11.5s,140) and (12.5s,160) .. (15s,200)}''.

    Note that by setting the control points always to $(1,1)$ and $(0,0)$ you
    get a linear interpolation between time--value pairs.

    Two special cases are the following: When the two last parameters, the exit
    spline, take the special values |stay| and |0|, the attribute's value
    ``stays'' until the next value for the next time (it then ``jumps'' to the
    next value then). This corresponds, roughly, to an ``infinite'' \meta{exit
    spline control x}. Similarly, when the entry spline parameters take the
    special values |jump| and |1|, the value immediately jumps from the
    previous value to the next value when the previous value was specified.
\end{command}

\begin{command}{\pgfsysanimkeybase}
\end{command}
%
\begin{command}{\pgfsys@animation@base}
    This command can be used in any place where |\pgfsys@animation@time| is
    usually used. The effect is that the next value does not become part of the
    timeline, but will become the value used for the attribute when no
    animation is active. (Normally, when the animation is not active, no value
    is set at all and the value is inherited from the surrounding scope.)
\end{command}

It may happen that there is more than one timeline active that is ``trying to
modify'' a given attribute. In this case, the following rules are used to
determine, which timeline ``wins'':
%
\begin{enumerate}
    \item If no animation is active at the current time (all animation either
        have not yet started or they have already ended), then the base value
        given in the animation encountered last in the code is used. (If there
        are no base values, the attribute is taken from the surrounding scope.)
    \item If there are several active animations, the one that has started last
        is used and the its value is used.
    \item If there are several active animations that have started at the same
        time, the one that comes last in the code is used.
\end{enumerate}

Note that these rules do not apply to transformations of the canvas since these
are always additive (or, phrased differently, they are always all active and
the effects accumulate).


\subsection{Commands for Specifying Timelines: Specifying Values}

The following commands are used to specify the values of a timeline. Each use
of one of the following commands adds one time--value pair to the timeline.
Which of the commands must be used depends on the type of the to-be-animated
attribute (see the |\pgfsysanimate| command instances, which list the command
that must be used).

\begin{command}{\pgfsysanimvalcurrent}
\end{command}
\begin{command}{\pgfsys@animation@val@current}
    Creates a time--value pairs where the value is the current value that the
    attribute has. This command can only be used in conjunction with ``real''
    animations, when you use it with a snapshot an error is raised.
\end{command}

\begin{command}{\pgfsysanimvaltext\marg{text}}
\end{command}
\begin{command}{\pgfsys@animation@val@text\marg{text}}
    Creates a time--value pairs where the value is some text. Which texts are
    permissible depends on the to-be-animated attribute.
\end{command}

\begin{command}{\pgfsysanimvalscalar\marg{number}}
\end{command}
\begin{command}{\pgfsys@animation@val@scalar\marg{number}}
    Creates a time--value pairs where the value is a number like |0.5| or
    |-2.25|.
\end{command}

\begin{command}{\pgfsysanimvaldimension\marg{dimension}}
\end{command}
\begin{command}{\pgfsys@animation@val@dimension\marg{dimension}}
    Creates a time--value pairs where the value is a \TeX\ dimension like
    |0.5pt| or |-2in|.
\end{command}

\begin{command}{\pgfsysanimvalcolorrgb\marg{red}\marg{green}\marg{blue}}
\end{command}
\begin{command}{\pgfsys@animation@val@color@rgb\marg{red}\marg{green}\marg{blue}}
    Creates a time--value pairs where the value is color specified by three
    fractional values between 0 and 1 for the red, the green, and the blue
    part.
\end{command}

\begin{command}{\pgfsysanimvalcolorcmyk\marg{cyan}\marg{magenta}\marg{yellow}\marg{black}}
\end{command}
\begin{command}{\pgfsys@animation@val@color@cmyk\marg{cyan}\marg{magenta}\marg{yellow}\marg{black}}
    Creates a time--value pairs where the value is color specified by four
    fractional values between 0 and 1 for the cyan, magenta, yellow, and black
    part.
\end{command}

\begin{command}{\pgfsysanimvalcolorcmy\marg{cyan}\marg{magenta}\marg{yellow}}
\end{command}
\begin{command}{\pgfsys@animation@val@color@cmy\marg{cyan}\marg{magenta}\marg{yellow}}
    Like the |\pgfsysanimvalcolorcmyk| only without the black part.
\end{command}

\begin{command}{\pgfsysanimvalcolorgray\marg{gray value}}
\end{command}
\begin{command}{\pgfsys@animation@val@color@gray\marg{gray value}}
    Creates a time--value pairs where the value is gray value (a
    fraction between 0 and 1).
\end{command}

\begin{command}{\pgfsysanimvalpath\marg{low-level path construction commands}}
\end{command}
\begin{command}{\pgfsys@animation@val@path\marg{low-level path construction command}}
    Creates a time--value pairs where the value is path. The \meta{low-level
    commands} must consist of a sequence of path construction commands like
    |\pgfsys@lineto| or |\pgfsyssoftpath@linetotoken| (more precisely, the
    commands must form a list of \TeX\ tokens and dimensions surrounded by
    braces). For each call of this command, the sequence of tokens and numbers
    must be the some. During the animation, only and exactly the numbers will
    be interpolated.
\end{command}

\begin{command}{\pgfsysanimvaltranslate\marg{x dimension}\marg{y dimension}}
\end{command}
\begin{command}{\pgfsys@animation@val@translate\marg{x dimension}\marg{y dimension}}
    Creates a time--value pairs where the value is a coordinate. The dimensions
    must be \TeX\ dimensions.
\end{command}

\begin{command}{\pgfsysanimvalscale\marg{x scale}\marg{y scale}}
\end{command}
\begin{command}{\pgfsys@animation@val@scale\marg{x scale}\marg{y scale}}
    Creates a time--value pairs where the value is pair of scalar values.
\end{command}

\begin{command}{\pgfsysanimvalviewbox\marg{$x_1$}\marg{$y_1$}\marg{$x_2$}\marg{$y_2$}}
\end{command}
\begin{command}{\pgfsys@animation@val@viewbox\marg{$x_1$}\marg{$y_1$}\marg{$x_2$}\marg{$y_2$}}
    Creates a time--value pairs where the value is view box. The lower left
    corner is given by $(x_1,y_1)$, consisting of two \TeX\ dimensions, and the
    upper right corner is $(x_2,y_2)$.
\end{command}

\begin{command}{\pgfsysanimvaldash\marg{pattern}\marg{phase}}
\end{command}
\begin{command}{\pgfsys@animation@val@dash\marg{pattern}\marg{phase}}
    Creates a time--value pairs where the value is dash pattern and phase with
    the same syntax as |\pgfsys@setdash|.
\end{command}


\subsection{Commands for Specifying Timing: Repeats}

\begin{command}{\pgfsysanimkeyrepeat{number of times}}
\end{command}
\begin{command}{\pgfsys@animation@repeat\marg{number of times}}
    Specifies that the animation should repeat the specified \meta{number of
    times}, which may be a fractional number.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrepeat{2.5}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyrepeatindefinite}
\end{command}
\begin{command}{\pgfsys@animation@repeat@indefinite}
    Specifies that the animation should repeat indefinitely.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrepeatindefinite
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyrepeatdur\meta{seconds}}
\end{command}
\begin{command}{\pgfsys@animation@repeat@dur\meta{seconds}}
    Specifies that the animation should repeat until \meta{seconds} have
    elapsed.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrepeatdur{5}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}


\subsection{Commands for Specifying Timing: Beginning and Ending}

Normally, animations start when a graphic is displayed. Using the following
commands, you can change this behavior: For instance, you can specify that the
animation should start when, say, some button has been pressed or a key has
been hit. Similarly, you can also use the commands to specify that the
animation should stop early, for instance when a button is pressed.

Note that all of the commands for specifying a nonstandard begin (or end) of an
animation's timeline refer to when the time $0\,\mathrm s$ of the timeline
should actually be. If the first time--value point for a timeline is at, say,
2\,s and you specify that the begin of the animation is one second after the
click of a button, the attribute will attain the value specified by the
time--value point three seconds after the button has been pressed.

All of the following commands take either the text |begin| or |end| as their
last argument.

You can call the commands several times. This will result in several different
possible beginnings (or endings).

\begin{command}{\pgfsysanimkeyoffset\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@offset\marg{time offset}\marg{begin or end}}
    Specifies that (in addition to any other beginnings or endings) the
    animation's timeline should begin (or end) \meta{time offset} many seconds
    after the graphic is shown. For instance, in the next example the animation
    will start automatically after 5\,s \emph{or} when then button is pressed.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm,render
  instead={
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyoffset{5}{begin}
  \pgfsysanimkeysnapshotstart{5}
  \pgfsysanimate{translate} }
    }]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyoffset{5}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeysyncbegin\marg{sync base id}\marg{type}\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@syncbegin\marg{sync base id}\marg{type}\marg{time offset}\marg{begin or end}}
    Specifies that the animation should begin \meta{time offset} many seconds
    after the \meta{sync base id} with the given \meta{type} has begun. Here,
    the \meta{sync base id} must have been obtained using |\pgfsys@new@id|.

    The idea behind a sync base is that you setup an animation and name it,
    other animations can start alongside this animation. An animation whose
    sole purpose is to orchestrate other animations in this way is called a
    \emph{sync base}.
\end{command}

\begin{command}{\pgfsysanimkeysyncend\marg{sync base id}\marg{type}\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@syncend\marg{sync base id}\marg{type}\marg{time offset}\marg{begin or end}}
    Works like |\pgfsysanimkeysyncbegin| only the animation begin (or ends)
    when the sync base ends.
\end{command}

\begin{command}{\pgfsysanimkeyevent\marg{id}\marg{type}\marg{event name}\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@event\marg{id}\marg{type}\marg{event name}\marg{time offset}\marg{begin or end}}
    Specifies that the animation should begin (or end) \meta{time offset} many
    seconds after a certain \emph{event} has occurred. Which events are
    possible depends on the specific output language, here are the events
    currently supported in \textsc{svg}:
    %
    \begin{itemize}
        \item |click| occurs when the object with the given \meta{id} and
            \meta{type} has been clicked.
        \item |focusin| and |focusout| occur when the focus enters or leaves
            the object.
        \item |mouseup|, |mousedown|, |mouseover|, |mousemove|, and |mouseout|
            occur when the mouse is pressed up or down on the object, moved
            onto the object, moved over the object, or moved off the object.
    \end{itemize}
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyevent{\nodeid}{}{mouseup}{}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyevent{\nodeid}{}{mousedown}{}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyevent{\nodeid}{}{mouseover}{}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyevent{\nodeid}{}{mousemove}{}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyevent{\nodeid}{}{mouseout}{}{begin}
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyrepeatevent\marg{id}\marg{type}\marg{repeat count}\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@repeat@event\marg{id}\marg{type}\marg{repeat count}\marg{time offset}\marg{begin or end}}
    The animation begins (or end) with a certain offset when another animation
    has reached a certain repeat count.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-5mm}
  \pgfsysanimkeyrepeatdur{5}
  \pgfsys@new@id{\animationid}
  \pgfsys@use@id{\animationid}
  \pgfsysanimate{translate}
  \global\let\animationid\animationid }
\tikz {
  \pgfidrefnextuse{\objid}{other}
  \pgfsysanimkeyrepeatevent{\animationid}{}{2}{0}{begin}
  \pgfsysanimkeysnapshotstart{4}
  \pgfsysanimkeywhom{\objid}{}
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-5mm}
  \pgfsysanimate{translate}
  \node [fill=red, text=white, circle] (other) {Other}; }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyaccesskey\marg{character}\marg{time offset}\marg{begin or end}}
\end{command}
\begin{command}{\pgfsys@animation@accesskey\marg{character}\marg{time offset}\marg{begin or end}}
    Begin or end the animation when a certain key is pressed. Note that this
    event may not be supported by some browsers for security reasons (prevent
    key loggers).
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyaccesskey{s}{}{begin}
  \pgfsysanimate{translate}
}
\end{codeexample}
    %
\end{command}


\subsection{Commands for Specifying Timing: Restart Behaviour}

\begin{command}{\pgfsysanimkeyrestartalways}
\end{command}
\begin{command}{\pgfsys@animation@restart@always}
    Defines that the animation can be restarted at any time. This is the
    default.
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrestartalways
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyrestartnever}
\end{command}
\begin{command}{\pgfsys@animation@restart@never}
    Defines that the animation cannot be restarted once it has run.
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrestartnever
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyrestartwhennotactive}
\end{command}
\begin{command}{\pgfsys@animation@restart@whennotactive}
    Defines that the animation cannot be restarted while it is running.
    %
\begin{codeexample}[width=2cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyrestartwhennotactive
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyfreezeatend}
\end{command}
\begin{command}{\pgfsys@animation@freezeatend}
    When an animation ends, the question is whether the ``effect'' of the
    animation (like changing a color or translating the coordinate system)
    should disappear or ``remain in force''. Using this key, you specify that
    at the end of the animation the last value of the attributes stays in
    effect.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyfreezeatend
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeyremoveatend}
\end{command}
\begin{command}{\pgfsys@animation@removeatend{}}
    The opposite of |\pgfsysanimkeyfreezeatend|. This is the default.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-1cm}
  \pgfsysanimkeyremoveatend
  \pgfsysanimate{translate} }
\end{codeexample}
    %
\end{command}


\subsection{Commands for Specifying Accumulation}

Animations specify how an attribute of an object changes over time. When more
than one animation changes the same value at the same time, the last value
given for the attribute ``wins'', except for animations of the canvas, which
always accumulate. Additionally, when a repeat is specified for an attribute,
during each repeat the values can add up:

\begin{command}{\pgfsysanimkeyaccumulate{}}
\end{command}
\begin{command}{\pgfsys@animation@accumulate{}}
    Specifies that each repeat of an animation works as if the last values
    attained during previous repeats are added to the current value.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-5mm}
  \pgfsysanimkeyaccumulate
  \pgfsysanimkeyrepeatdur{5}
  \pgfsysanimate{translate}  }
\end{codeexample}
    %
\end{command}

\begin{command}{\pgfsysanimkeynoaccumulate{}}
\end{command}
\begin{command}{\pgfsys@animation@noaccumulate{}}
    Specifies that each repeat resets the to-be-animated value. This is the
    default.
    %
\begin{codeexample}[animation list={1,2,3,4,5,6,7,8},width=6cm]
\animationexample{node}{}{
  \pgfsysanimkeytime{0}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{0cm}
  \pgfsysanimkeytime{2}{1}{1}{0}{0}
  \pgfsysanimvaltranslate{0cm}{-5mm}
  \pgfsysanimkeynoaccumulate
  \pgfsysanimkeyrepeatdur{5}
  \pgfsysanimate{translate}  }
\end{codeexample}
    %
\end{command}


%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pgfmanual"
%%% End:
