diff options
Diffstat (limited to 'graphics/pgf/base/doc/pgfmanual-en-base-animations.tex')
-rw-r--r-- | graphics/pgf/base/doc/pgfmanual-en-base-animations.tex | 1492 |
1 files changed, 1492 insertions, 0 deletions
diff --git a/graphics/pgf/base/doc/pgfmanual-en-base-animations.tex b/graphics/pgf/base/doc/pgfmanual-en-base-animations.tex new file mode 100644 index 0000000000..f3ae0cc3cc --- /dev/null +++ b/graphics/pgf/base/doc/pgfmanual-en-base-animations.tex @@ -0,0 +1,1492 @@ +% Copyright 2019 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{Animations} +\label{section-base-animations} + +\begin{pgfmodule}{animations} + This module contains the basic layer support of animations, which is + documented in the following. +\end{pgfmodule} + +This section described the basic layer support of animations, the \tikzname\ +support is described in Section~\ref{section-tikz-animations}. As always, +\tikzname\ mainly converts syntactic constructs (like the special colon or +quote syntax) to appropriate basic layer commands, which are documented here. +Note, however, that while many attributes and options are the same on both +layers, some things are handled differently on the basic layer. + + +\subsection{Overview} + +An \emph{animation} changes the way some part of a graphic looks like over +time. The archetypical animation is, of course, a \emph{movement} of node, but +a change of, say, the opacity of a path is also an animation. \pgfname\ allows +you to specify such animations using a set of commands and keys that are +documented in the following. +% +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{opacity}{ + whom = node, begin on = {click}, entry = {0s}{1}, entry = {2s}{0} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + +Differently from other packages, the animations created by \pgfname\ are not +precomputed sequences of pictures that are displayed in rapid succession. +Rather, an animation created by \pgfname\ consists mainly of an annotation in +the output that a certain attribute of a certain object should change over time +in some specific way when the object is displayed. It is the job of the +document viewer application to actually compute and display the animation. +Interestingly, this means that animations neither increase the size of the +output files noticeably nor does it put a special burden on \TeX. The hard and +complicated calculations are done by the viewer application, not by \TeX\ and +\pgfname. + +Only few viewer applications and formats are currently ``up to the job'' of +displaying animations. In particular, the popular \textsc{pdf} format does +\emph{not} allow one to specify animations in this way (one can partly ``fake'' +animations at the high price of including a great number of precomputed +pictures and using JavaScript in special viewers, but this is really not the +same thing as what \pgfname\ does). Indeed, currently only the \textsc{svg} +format allows one to specify animations in a sensible way. Thus, \pgfname's +animations will only be displayed when \textsc{svg} is used as output format. + +Because of the shortcomings of the other formats and, also, for purposes of +printing and depicting animations in a sequential manner, \pgfname\ also allows +you to create ``snapshots'' of animations. As an example, the following code +shows how the same drawing is shown at different ``time snapshots'': +% +\begin{codeexample}[ + width=3.9cm, + preamble={\usetikzlibrary{animations} +\def\pgfname{\textsc{pgf}} +}] +\tikz [make snapshot of=0.5s] \scoped :rotate = { 0s = "0", 2s = "90" } + \node [draw=blue, very thick] {\pgfname}; +\tikz [make snapshot of=1s] \scoped :rotate = { 0s = "0", 2s = "90" } + \node [draw=blue, very thick] {\pgfname}; +\tikz [make snapshot of=1.5s] \scoped :rotate = { 0s = "0", 2s = "90" } + \node [draw=blue, very thick] {\pgfname}; +\tikz [make snapshot of=2s] \scoped :rotate = { 0s = "0", 2s = "90" } + \node [draw=blue, very thick] {\pgfname}; +\end{codeexample} + + +\subsection{Animating an Attribute} + +\subsubsection{The Main Command} + +Creating an animation is done using the command |\pgfanimateattribute|, which +takes a to-be-animated attribute and options specifying the timeline: + +\begin{command}{\pgfanimateattribute\marg{attribute}\marg{options}} + Adds an animation of the \meta{attribute} of a future \emph{object} to the + current graphic. Attributes are things like the ``fill opacity'' or the + transformation matrix or the line width. + + The \meta{options} are keys that configure how the attribute changes over + time. Using the |entry| key multiple times, you specify which value the + chosen attribute should have at different points in time. Unless special + keys are used, ``outside'' the specified timeline the animation has no + effect: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2,2.5}, +] +\tikz { + \pgfanimateattribute{opacity}{ + whom = node, begin on = {click}, entry = {0s}{1}, entry = {2s}{0} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + + Other keys, like |repeats|, allow you to specify how the animation behaves + ``as a whole''. These keys are documented later in this section. + + + \medskip + \textbf{The Attributes} + + In detail, the |\pgfanimateattribute| command opens a \TeX-scope, looks up + the \emph{type} values of the specified \meta{attribute} have (if you wish + to animate the |opacity| of an object, the type is ``scalar'' meaning that + entries must be scalar numbers; when you animate the |fill| attribute, the + type is ``color'' and values must be colors, and so on), and then executes + the \meta{options} with the path prefix |/pgf/animation|. Finally, an + appropriate system layer command |\pgfsysanimate...| is called to create + the actual animation and the scope is closed. + + The following \meta{attributes} are permissible: + + \begin{tabular}{ll} + \emph{Attribute} & \emph{Type} \\ + |draw|, |fill| & color \\ + |line width| & dimension \\ + |motion| & scalar \\ + |opacity|, |fill opacity|, |draw opacity| & scalar \\ + |path| & path \\ + |rotate| & scalar \\ + |scale| & scaling \\ + |softpath| & softpath \\ + |translate| & point \\ + |view| & viewbox \\ + |visible| & boolean \\ + |stage| & boolean \\ + |xskew|, |yskew| & scalar \\ + \end{tabular} + + These attributes are detailed in Sections + \ref{section-base-animation-painting} + to~\ref{section-base-animation-views}, but here is a quick overview: + % + \begin{itemize} + \item |draw| and |fill| refer to the color used to draw (stroke) and + fill paths in an object, respectively. Typical values for this + attribute are |red| or |black!10|. + \item |line width| is, of course, the line width used in an object. + Typical values are |0.4pt| or |1mm|. Note that you (currently) + cannot use keys like |thin| or |thick| here, but this may change in + the future. + \item |motion| is a slightly special attribute: It allows you to + specify a path along which the object should be moved (using the + |along| key). The values given to the |entry| key for this + attribute refer to a \emph{fraction of the distance along the + path}. See the |along| key for details. + \item |opacity| and the variants |fill opacity| and |draw opacity| + animate the opacity of an object. Allowed values range between 0 + and 1. + \item |path| allows you to animate a path (it will morph). The + ``values'' are now paths themselves. See + Section~\ref{section-base-animation-paths} for details. + \item |rotate| refers to a rotation of the object. Values for the + |entry| key are the rotation angles like |0| or |90|. + \item |scale| refers to the scaling of the object. Values are either + single scalars values (like |1| or |1.5|) or two numbers separated + by a comma (like |1,1.5| or |0.5,2|), referring to the $x$-scaling + and $y$-scaling. + \item |softpath| is a special case of the |path| attribute, see + Section~\ref{section-base-animation-paths} once more. + \item |translate| shifts the object by a certain vector. Values are + points like |\pgfpoint{1cm}{2cm}|. + \item |view| allows you to animate the view box of a view, see + Section~\ref{section-base-animation-views} for details. + \item |visible| refers to the visibility of an object. Allowed values + are |true| and |false|. + \item |stage| is identical to |visible|, but when the object is not + animated, it will be hidden by default. + \item |xskew| and |yskew| skew the object. Attributes are angles like + |0| or |45| or even |90|. + \end{itemize} + + + \medskip + \textbf{The Target Object} + + As stated earlier, the \meta{options} are used to specify the object whose + attribute for which an animation should be added to the picture. Indeed, + you \emph{must} specify the object explicitly using the |whom| key and you + must do so \emph{before} the object is created. Note that, in contrast, in + \textsc{svg} you can specify an animation more or less anywhere and then + use hyper-references to link the animation to the to-be-animated object; + \pgfname\ insists that you specify the animation before the object. This is + a bit of a bother in some situations, but it is the only way to ensure that + \pgfname\ has a fighting chance to attach some additional code to the + object (which is necessary for almost all animations of the transformation + matrix). + + \begin{key}{/pgf/animation/whom=\meta{id}\opt{|.|\meta{type}}} + You \emph{must} use this key once which each call of the + |\pgfanimateattribute| command. The \meta{id} and the optional + \meta{type} (which is whatever follows the first dot) will be passed to + |\pgfidrefnextuse|, see that command for details. + \end{key} + + As explained in the introduction of this chapter, an ``animation'' is just + a bit of special text in the output document asking a viewer application to + animate the object at some later time. The |\pgfanimateattribute| command + inserts this special text immediately, even though it refers to an object + created only later on. Normally, this is not a problem, but the special + text should be on the same page as the to-be-animated object. To ensure + this, it suffices to call |\pgfanimateattribute| no earlier than the + beginning of the |pgfpicture| containing the object. + + + \medskip + \textbf{Naming the Animation} + + You can assign a name to an animation for later (or early) reference. In + particular, it is possible to begin \emph{another} animation relative to + the beginning or end of this animation and for referencing this animation + must be assigned a name. See the |of| and |of next| keys for details. + + \begin{key}{/pgf/animation/name=\meta{name}} + Assigns a name to the animation by which it can be referenced using the + |of| and |of next| keys in another animation. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {end, of next = my move animation, delay = 1s}, + entry = {0s}{0}, entry = {2s}{90}, begin snapshot = 3s, } + \pgfanimateattribute{translate}{ + name = my move animation, whom = node, begin on = {click}, + entry = {0s}{\pgfpointorigin}, entry = {2s}{\pgfpoint{0cm}{-5mm}} } + \node (node) [fill = blue!20, draw = blue, circle] {Here!}; +} +\end{codeexample} + \end{key} +\end{command} + +\begin{command}{\pgfanimateattributecode\marg{attribute}\marg{code}} + The command works like |\pgfanimateattribute|, only instead of + \meta{options} you specify some \meta{code} whose job is to setup the + options. +\end{command} + + +\subsubsection{Specifying the Timeline} + +The core key for specifying how an attribute varies over time is the |entry| +key: +% +\begin{key}{/pgf/animation/entry=\marg{time}\marg{value}} + You use this key repeatedly to specify the different values that the + \meta{attribute} should have over time. At the \meta{time} specified, the + \meta{attribute} will have the value specified as \meta{value}: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, + entry = {0s}{0}, entry = {1s}{90}, entry = {1.1s}{45}, entry = {2s}{90} + } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + + You need to call |entry| once for each time in the timeline for which you + want to specify a \meta{value} explicitly. Between these times, the values + get interpolated (see below for details). You need to specify the + \meta{time}s in non-decreasing order (it is permissible and sometimes also + necessary to specify the same time twice, namely to create a ``jump'' of + the value of some attribute). + + The \meta{time} is parsed using the command |\pgfparsetime| described + later. + + + \medskip + \textbf{Start and end of the timeline.} + 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 |begin| and |end| keys) get offset by + the start time; similarly end times are offset by this value. + + + \medskip + \textbf{Syntax of the values.} + The syntax of the \meta{value} varies according to the type of the + \meta{attribute}. In detail, these are: + + \begin{tabular}{lp{12cm}} + \emph{Type} & \emph{Syntax} \\ + color & Standard color syntax like |red| or |black!10| \\ + scalar & A value parsed using |\pgfmathparse| \\ + dimension & A dimension parsed using |\pgfmathparse| \\ + path & A sequence of path construction commands \\ + softpath & A sequence of soft path construction commands \\ + scaling & A scalar value or a pair of scalar values separated by a comma \\ + point & A \pgfname-point like |\pgfpoint{1cm}{5mm}| \\ + viewbox & Two \pgfname-points \\ + boolean & |true| or |false| \\ + \end{tabular} + + + \medskip + \textbf{Interpolation between key times.} + You use the |entry| key repeatedly, namely once for each ``key time'', + which is a time point for which you specify the value of the attribute + explicitly. Between these key times, the attribute's value is interpolated. + Normally, this is just a linear interpolation, but you can influence this + using the following keys, see Section~\ref{section-anim-smooth} for + details. + + \begin{key}{/pgf/animations/exit control=\marg{time fraction}\marg{value fraction}} + Same as |/tikz/animate/options/exit control|. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.333/\frac{1}{3},0.666/\frac{2}{3},1,1.333/1\frac{1}{3},1.666/1\frac{2}{3}}, +] +\tikz { + \foreach \i in {0,0.125,...,1} \draw (-0.9,.9-\i) -- ++(1.8,0); + \pgfanimateattribute{translate}{ + whom = node, begin on = {click}, + exit control={1}{0}, + entry = {0s}{\pgfpointorigin}, + linear, % revert to default + entry = {1s}{\pgfpoint{0cm}{-5mm}}, + entry control={0}{1}, + entry = {2s}{\pgfpoint{0cm}{-10mm}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + \end{key} + + \begin{key}{/pgf/animations/entry control=\marg{time fraction}\marg{value fraction}} + Works like |exit control|. + \end{key} + + \begin{key}{/pgf/animations/linear} + A shorthand for |exit control={0}{0}, entry control={1}{1}|. This will + (re)install a linear curve. + \end{key} + + \begin{key}{/pgf/animations/stay} + Same as |/tikz/animate/options/stay|. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2,2.5}, +] +\tikz { + \foreach \i in {0,0.125,...,1} \draw (-0.9,.9-\i) -- ++(1.8,0); + \pgfanimateattribute{translate}{ + whom = node, begin on = {click}, + entry = {0s}{\pgfpointorigin}, + stay, + entry = {1s}{\pgfpoint{0cm}{-5mm}}, + linear, + entry = {2s}{\pgfpoint{0cm}{-10mm}}, + entry = {3s}{\pgfpoint{0cm}{-15mm}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + \end{key} + + \begin{key}{/pgf/animations/jump} + Same as |/tikz/animate/options/jump|. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \foreach \i in {0,0.125,...,1} \draw (-0.9,.9-\i) -- ++(1.8,0); + \pgfanimateattribute{translate}{ + whom = node, begin on = {click}, + entry = {0s}{\pgfpointorigin}, + jump, + entry = {1s}{\pgfpoint{0cm}{-1cm}}, + linear, + entry = {2s}{\pgfpoint{0cm}{-2cm}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + \end{key} +\end{key} + +When the time of an animation lies outside the timeline specified by the +|entry| keys, no animation is present. This means that the value of the +attribute is the object's scope is used instead. Using the following key, you +can set this value directly: + +\begin{key}{/tikz/animations/base=\meta{value}} + The syntax of the \meta{value} is the same as for the |entry| key. The + \meta{value} is installed as the value of the object's attribute whenever + the timeline is not active. This makes it easy to specify the value of an + attribute when the animation is ``not running''. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={-1,0,1,2,3}, +] +\tikz { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, + entry = {0s}{90}, entry = {2s}{180}, + base = 45 + } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % +\end{key} + +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). + +\begin{command}{\pgfparsetime\marg{time}} + This command works like |\pgfmathparse| (indeed, it calls is internally), + but returns the result in the macro |\pgftimeresult| rather than + |\pgfmathresult|. Furthermore, the following changes are installed: + % + \begin{itemize} + \item The postfix operator |s| is added, which has no effect. + \item The postfix operator |ms| is added, which divides a number by + 1000, so |2ms| equals 0.002s. + \item The postfix operator |min| is added, which multiplies a number by + 60. + \item The postfix operator |h| is added, which multiplies a number by + 3600. + \item The infix operator |:| is redefined, so that it multiplies its + first argument by 60 and adds the second. This implies that |1:20| + equals 80s and |01:00:00| equals 3600s. + \item The parsing of octal numbers is switched off to allow things like + |01:08| for 68s. + \end{itemize} +\end{command} + + +\subsubsection{``Anti-Animations'': Snapshots} + +There are a number of situations in which you want the ``opposite'' of an +animation to happen: You want to create a ``still image''. For instance, when +you want to print an animation you will typically wish to show one or more +``temporal snapshots'' of the animation. Also, you may wish to specify a value +for an object when it is \emph{not} being animated. + +Let us start with creating a snapshot: + +\begin{command}{\pgfsnapshot\marg{time}} + When this command is used inside a \TeX\ scope, the behavior of + |\pgfanimateattribute| changes: Instead of adding an animation to the + object and the attribute, the object's attribute is set to value it would + have during the animation at time \meta{time}. Note that when this command + is used in a \TeX\ scope, no animation is created and no support by the + driver is needed (so, it works with \textsc{pdf}). + % +\begin{codeexample}[preamble={\usetikzlibrary{animations}}] +\tikz [make snapshot of=1s, + animate = { myself: = { + :rotate = { 0s = "0", 2s = "90" }, + :color = { 0s = "red", 2s = "green" }, + :line width = { 0s = "0mm", 4s = "4mm" } + }}] + \node [fill=black!20, draw] { Node }; +\end{codeexample} + + + \medskip\textbf{Timing and Events.} + The timeline of an animation normally starts at a ``moment |0s|'' and the + \meta{time} is considered relative to this time. For instance, if a + timeline contains, say, the settings |entry={2s}{0}| and |entry={3s}{10}| + and \marg{time} is set to |2.5s|, then the value the attribute will get is + 5. + + It is, however, also possible to specify that animations begin and end at + certain times relative to events like a |click| event. \emph{These events + are not relevant with respect to snapshots.} However, there is one key that + allows you to specify the beginning of the snapshot timeline: + % + \begin{key}{/tikz/animations/begin snapshot=\meta{begin time}} + When this key is used inside the options of |\pgfanimateattribute|, + with respect to snapshots, the timeline begins at \meta{begin time}. + This means that, if the snapshot time is set to \meta{time} and the + beginning of the snapshot's timeline is set to \meta{begin time}, the + attribute is set to the value of the timeline at time $\meta{time} - + \meta{begin time}$. + + The idea is that when you make a snapshot of several animations and all + of them have started at different times because of different events, + you use |begin snapshot| with each object and attribute to directly + specify when these different events have happened. + \end{key} + + Note that the |end| keys have no effect with snapshots, that is, with a + snapshot all animations always run till the end of the timeline (which may + or may not be ``forever''). + + + \medskip\textbf{Limitations.} + For snapshots, the value an animation has at time \meta{time} must be + computed by \TeX. While in many cases this is easy to achieve, in some + cases this is not trivial such as a timeline for a path with repeats plus + smoothing via splines. An additional complication is the fact that an + animation may be specified at a place far removed from the actual + to-be-animated object. For these reasons, certain limitations apply to + snapshots: + % + \begin{itemize} + \item The |begin| and |begin on| keys have no effect (but + |begin snapshot| has one. + \item The |end| and |end on| keys have no effect. + \item The |current value| may not be used in a timeline (since + \pgfname\ cannot really determine this value). + \item The |accumulating| specification may not be used with paths, + views, or motions. + \item Since the timing computations are done using \TeX\ code, they are + not necessarily stable. For instance, when a time interval is very + small and there are many repeats or when a spline is very + complicated, the calculated values may not be fully accurate. + \end{itemize} +\end{command} + +\begin{command}{\pgfsnapshotafter\marg{time}} + This command works exactly like |\pgfsnapshot| 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: + % +\begin{codeexample}[preamble={\usepgfmodule{animations}}] +\foreach \t in {0,1,2,3,4} { + \pgfsnapshot{\t} + \tikz :rotate = { 0s = "0", 2s = "90", 2s = "180", 4s = "270" } + \node [draw=blue, very thick] {f}; } +\end{codeexample} + % +\begin{codeexample}[preamble={\usepgfmodule{animations}}] +\foreach \t in {0,1,2,3,4} { + \pgfsnapshotafter{\t} + \tikz :rotate = { 0s = "0", 2s = "90", 2s = "180", 4s = "270" } + \node [draw=blue, very thick] {f}; } +\end{codeexample} + % +\end{command} + + +\subsection{Animating Color, Opacity, Visibility, and Staging} +\label{section-base-animation-painting} + +\begin{animateattribute}{fill} + You can animate the color of the target object of an animation using the + attributes |fill| or |draw|, which animate the fill color and the drawing + (stroking) color, respectively. To animate both the fill and draw color, + you need to create two animations, one for each. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{fill}{ + whom = node.background, begin on = {click}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % +\end{animateattribute} + +\begin{animateattribute}{draw} +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{draw}{ + whom = node.background, begin on = {click}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} +\end{animateattribute} + +When the target of a color animation is a scope, you animate the color ``used +in this scope'' for filling or stroking. However, when an object inside the +scope has its color set explicitly, this color overrules the color of the +scope: +% +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, + animation bb={(1.5,-0.75) rectangle (3,0.75)}, +] +\tikz { + \pgfanimateattribute{fill}{ + whom = example, begin on = {click, of next=node}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \begin{scope}[name = example] + \fill (1.5,-0.75) rectangle ++ (1,1); + \fill [blue] (2,-0.25) rectangle ++ (1,1); + \end{scope} +} +\end{codeexample} + +Note that in certain cases, a graphic scope may contain graphic objects with +their colors set explicitly ``in places where you do not expect it'': In +particular, a node normally consists at least of a background path and a text. +For both the text and for the background path, colors will be set for the text +and also for the path explicitly. This means that when you pick the fill +attribute of a node as the target of an animation, you will \emph{not} animate +the color of the background path in case this color has been set explicitly. +Instead, you must choose the background path of the node as the target of the +animation. Fortunately, this is easy to achieve since when the background path +of a node is created, the identifier type is set to |background|, which in turn +allows you to access it as \meta{node}|.background| through the |whom| key. + +The text of a node also gets it color set explicitly, which means that a change +of the node's scope's color has no effect on the text color. Instead, you must +choose \meta{name}|.text| as the target (or, if the node has more parts, use +the name of the part as the identifier type instead of |text|). +% +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, + animation bb={(1.1,-0.9) rectangle (2.9,0.9)}, +] +\tikz { + \pgfanimateattribute{fill}{ + whom = example, begin on = {click, of next=node}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \node at (2,0) (example) [fill = blue!20, circle] {No effect}; } +\end{codeexample} + +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, + animation bb={(1.1,-0.9) rectangle (2.9,0.9)}, +] +\tikz { + \pgfanimateattribute{fill}{ + whom = example.background, begin on = {click, of next=node}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \node at (2,0) (example) [fill = blue!20, circle] {Effect}; } +\end{codeexample} + +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, + animation bb={(1.1,-0.9) rectangle (2.9,0.9)}, +] +\tikz { + \pgfanimateattribute{fill}{ + whom = example.text, begin on = {click, of next=node}, + entry = {0s}{white}, entry = {2s}{red} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \node at (2,0) (example) [fill = blue!20, circle, font=\huge] {Text}; } +\end{codeexample} + +Similarly to the color, you can also set the opacity used for filling and for +drawing. You specify the opacity using a number between 0 (transparent) and 1 +(opaque). + +\begin{animateattribute}{fill opacity} +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{fill opacity}{ + whom = node, begin on = {click}, entry = {0s}{1}, entry = {2s}{0} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} +\end{animateattribute} + +\begin{animateattribute}{draw opacity} +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{draw opacity}{ + whom = node, begin on = {click}, entry = {0s}{1}, entry = {2s}{0} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} +\end{animateattribute} + +\begin{animateattribute}{opacity} + Unlike colors, where there is no joint attribute for filling and stroking, + there is a single |opacity| attribute in addition to the above two + attributes. If supported by the driver, it treats the graphic object to + which it is applied as a transparency group. In essence, ``this attribute + does what you want'' at least in most situations. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{opacity}{ + whom = node, begin on = {click}, entry = {0s}{1}, entry = {2s}{0} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % +\end{animateattribute} + +\begin{animateattribute}{visible} + The difference between the |visible| attribute and an opacity of |0| is + that an invisible object cannot be clicked and does not need to be + rendered. The (only) two possible values for this attribute are |false| and + |true|. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4}, +] +\tikz { + \pgfanimateattribute{visible}{ + whom = node, begin on = {click}, entry = {0s}{false}, entry = {2s}{false} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % +\end{animateattribute} + +\begin{animateattribute}{stage} + This attribute is the same as the |visible| attribute, only |base=false| is + set by default. This means that the object is \emph{only} visible when you + explicitly during the time the entries are set to |true|. The idea behind + the name ``stage'' is that the object is normally ``off stage'' and when + you explicitly set the ``stage attribute'' to |true| the object ``enters'' + the stage and ``leaves'' once more when it is no longer ``on stage''. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={-1,0,1,2,3}, + animation bb={(1.3,-0.7) rectangle (2.7,0.7)}, +] +\tikz { + \pgfanimateattribute{stage}{ + whom = example, begin on = {click, of next=node}, + entry = {0s}{true}, entry = {2s}{true} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \node at (2,0) (example) [fill = blue!20, circle] {Effect}; } +\end{codeexample} + % +\end{animateattribute} + + +\subsection{Animating Paths and their Rendering} +\label{section-base-animation-paths} + +You can animate the appearance of a path in the following ways: + +\begin{animateattribute}{line width} +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{line width}{ + whom = node, begin on = {click}, entry = {0s}{1pt}, entry = {2s}{5mm} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % + The possible values passed to the |entry| key are, of course, dimensions. +\end{animateattribute} + +\begin{animateattribute}{dash} +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{dash}{ + whom = node, begin on = {click}, entry = {0s}{{{10pt}{1pt}}{0pt}}, + entry = {2s}{{{1pt}{10pt}}{0pt}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{dash}{ + whom = node, begin on = {click}, entry = {0s}{{{1cm}{1pt}}{0pt}}, + entry = {2s}{{{1cm}{1pt}}{1cm}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % + To specify the dash pattern, you specify a sequence of ``on and off'' + dimensions; see |\pgfsetdash| for details. Note that you \emph{must} + specify the same number of elements in all patterns of a timeline: You + cannot specify that the dash pattern for |1s| is |{1pt}{2pt}| and for |2s| + is |{1pt}{3pt}{2pt}| since the number of elements would differ. In + particular, you cannot (sensibly) use |current value| for the first entry + since this corresponds to an empty dash pattern (even when you have + specified a dash pattern for the target object: this pattern will not be + attached to the to-be-animated scope or object but to a surrounding scope + and, thus, the to-be-animated scope will not have any dash pattern + installed). +\end{animateattribute} + +\begin{animateattribute}{path} + You can animate the path itself: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz { + \pgfanimateattribute{path}{ + whom = node.background.path, begin on = {click, of next=node}, + entry = {0s}{\pgfpathellipse{\pgfpointorigin} + {\pgfpointxy{1}{0}}{\pgfpointxy{0}{1.5}}}, + entry = {2s}{\pgfpathellipse{\pgfpointxy{.5}{0}} + {\pgfpointxy{.5}{.5}}{\pgfpointxy{0.25}{.25}}}} + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; +} +\end{codeexample} + % + The path is specified by giving path construction commands as in the above + example. They will be executed in a special protected scope to ensure that + they have only little side effects. + + As for the dash pattern, you must ensure that all paths in the timeline + have the same structure (same sequence of path construction commands); only + the coordinates may differ. In particular, you cannot say that the path at + |1s| is a rectangle using |\pgfpathrectangle| and at |2s| is a circle using + |\pgfpathcircle|. Instead, you would have to ensure that at both times that + path consists of appropriate Bézier curves. + + Unlike the dash pattern, the to-be-animated object is, indeed, the path + itself and not some special scope. This means that you can use the + |current value| for the start path. However, this also means that you + really must pick \emph{the path object} as the target of the animation. In + conjunction with \tikzname, this will be an object of type |path| as in the + above example. + + When a path is animated, it cannot have ``normal'' arrows attached to it + since due to the way \pgfname\ adds arrow tips to paths, these would not + ``move along'' with the path (you get an error message if you try). + However, it still \emph{is} possible to add arrow tips to an animated path, + only you need to use the |arrows| key described next. + + Concerning the bounding box computation of the path, a bounding box for all + paths mentioned for any time point is used as the overall bounding box. +\end{animateattribute} + +\begin{key}{/pgf/animation/arrows=\meta{start tip spec}|-|\meta{end tip spec}} + This key specifies arrow tips during the animation of the path. The syntax + for the arrow tips is the same syntax as the |\pgfsetarrow| command or + \tikzname's |arrows| key. The specified start and end arrow tips are + rendered as ``markers'', which are added to the path \emph{only} during the + animation. The markers are rotated along with the path in exactly the same + way as normal arrow tips would be. To be precise, the rules used for the + computation of where arrow tips go and in which direction they head is not + always the same for ``static'' arrow tips (arrow tips added to a normal + path) and the ``dynamic'' arrow tips based on markers; namely when the + paths are very short or closed. For this reason, you should add arrow tips + to animated paths only when the paths are ``nice and simple'' in the sense + that they consist of a single segment whose ends are reasonably long. + + In addition to adding the arrow tips to the path during the animation, the + path gets shortened as necessary to compensate for the extend of the arrow + tips. However, for this to work, the arrow tips have to be specified before + path values are specified (since the shortening is done immediately when a + path value is parsed). + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0,1,2,3,4}, + animation bb={(0.9,-0.1)rectangle(2.1,1.1)}, +] +\tikz { + \pgfanimateattribute{path}{ + whom = p.path, begin on = {click, of next=node}, arrows = ->, + entry = {1s}{\pgfpathmoveto{\pgfpoint{1cm}{0cm}} + \pgfpathlineto{\pgfpoint{2cm}{1cm}}}, + entry = {3s}{\pgfpathmoveto{\pgfpoint{1cm}{1cm}} + \pgfpathlineto{\pgfpoint{2cm}{5mm}}}} + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \draw [very thick, blue, name=p] (1,0.5) -- (2,0.5); +} +\end{codeexample} + + Note that the markers that visualize the arrow tips are rendered only once + per animation. In consequence, ``bending'' arrow tips cannot be rendered + correctly: As a path ``morphs'' a bend arrow tip needs not only to rotate + along, but must actually ``bend along'', which is not supported (neither by + \pgfname\ nor by \textsc{svg}). + + As pointed out earlier, an animated path cannot have ``static'' arrow tips. + However, when you specify a |base| value, which is the path used whenever + there is no active animation, \emph{will} use the arrow tips. As a result, + you can use this to animate a path with an arrow tip: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0,1,2,3,4}, + animation bb={(0.9,-0.1)rectangle(2.1,1.1)}, +] +\tikz { + \pgfanimateattribute{path}{ + whom = p.path, begin on = {click, of next=node}, arrows = ->, + base = {\pgfpathmoveto{\pgfpoint{1cm}{5mm}} + \pgfpathlineto{\pgfpoint{2cm}{5mm}}}, + entry = {1s}{\pgfpathmoveto{\pgfpoint{1cm}{0cm}} + \pgfpathlineto{\pgfpoint{2cm}{1cm}}}, + entry = {3s}{\pgfpathmoveto{\pgfpoint{1cm}{1cm}} + \pgfpathlineto{\pgfpoint{2cm}{5mm}}}} + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \draw [very thick, blue, name=p]; +} +\end{codeexample} + % +\end{key} + +\begin{key}{/pgf/animation/shorten >=\meta{dimension}} + Just like the normal \tikzname\ key |shorten >|, this key specifies an + extra shortening of to-be-animated paths. Whenever a path is parsed as a + value for a path animation, it gets shortened at the end by the + \meta{dimension} (and, additionally, by the length of the attached arrow + tip). Just like the |arrows| key, this key must be given before the path + entries are specified. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0,1,2,3,4}, + animation bb={(0.9,-0.1)rectangle(2.1,1.1)}, +] +\tikz { + \pgfanimateattribute{path}{ + whom = p.path, begin on = {click, of next=node}, arrows = ->, + shorten > = 2mm, + base = {\pgfpathmoveto{\pgfpoint{1cm}{5mm}} + \pgfpathlineto{\pgfpoint{2cm}{5mm}}}, + entry = {1s}{\pgfpathmoveto{\pgfpoint{1cm}{0cm}} + \pgfpathlineto{\pgfpoint{2cm}{1cm}}}, + entry = {3s}{\pgfpathmoveto{\pgfpoint{1cm}{1cm}} + \pgfpathlineto{\pgfpoint{2cm}{5mm}}}} + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + \draw (0.9,-0.1) grid (2.1,1.1); + \draw [help lines] (0.9,-0.1) grid[step=1mm] (2.1,1.1); + \draw [very thick, blue, name=p]; +} +\end{codeexample} + % +\end{key} + +\begin{key}{/pgf/animation/shorten <=\meta{dimension}} + Works like |shorten >|. +\end{key} + + +\subsection{Animating Transformations and Views} +\label{section-base-animation-views} + +In order to animate the canvas transformation matrix, you do not animate an +attribute called ``|transform|'' (or something similar). Rather, there are +several keys that all manipulate the canvas transformation matrix in different +ways. These keys, taken in appropriate combination, allow you to achieve any +particular canvas transformation matrix. All keys that animate the +transformation matrix \emph{always} accumulate. + +Some, but not all, of these keys also have an effect on the bounding box +computation: The |translate| and |motion| attribute change the computation of +the bounding box in such a way that it is chosen large enough as to include the +whole picture during all stages of the animation (however, if there are +multiple transformations active at the same time, the computation may not be +correct). In contrast, |scale|, |rotate| and |skew| animations change the +canvas transformation, but are ignored for the bounding box computation. When +in doubt, please set the bounding box explicitly. + +Let us start with the basic keys that allow you to change the canvas +transformation matrix directly: + +\begin{animateattribute}{scale} + The |scale| attribute adds an animation of the scaling: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{scale}{ + whom = node, begin on = {click}, + entry = {0s}{0.5}, entry = {2s}{0.75,1.5} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % + The values passed to the |entry| key must either be single scalar values or + a pair of such numbers separated by a comma (which then refer to the $x$- + and $y$-scaling). +\end{animateattribute} + +\begin{animateattribute}{rotate} + The |rotate| key adds an animation of the rotation: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, + entry = {0s}{45}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % + The values are scalar values representing a rotation in degrees. +\end{animateattribute} + +\begin{animateattribute}{xskew} + The |xskew| and |yskew| keys (and also |skew x| and |skew y|, which are + aliases) add an animation of the skew (given in degrees, not as a slant): + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{xskew}{ + whom = node, begin on = {click}, entry = {0s}{0}, entry = {2s}{45} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % + The values are scalar values. +\end{animateattribute} + +\begin{animateattribute}{yskew} + See |xskew|. +\end{animateattribute} + +\begin{animateattribute}{skew x} + An alias of |xskew|. +\end{animateattribute} + +\begin{animateattribute}{skew y} + An alias of |yskew|. +\end{animateattribute} + +\begin{animateattribute}{translate} + The |translate| key adds an animation of the translation (shift): + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{translate}{ + whom = node, begin on = {click}, + entry = {0s}{\pgfpointorigin}, entry = {2s}{\pgfpoint{5mm}{-5mm}} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % + The values are \pgfname-points. + + Unlike for the previous canvas transformations, for this key the bounding + box computation is changed: All points in the to-be-animated scope do not + only contribute to the normal bounding box, but they also contribute + shifted by all points in the entry list. The effect is that a bounding box + is computed that encompasses the animated scope at all stages. +\end{animateattribute} + +For all of these attributes, the following key is of importance: +% +\begin{key}{/pgf/animation/origin=\meta{pgf point}} + An animation of the canvas transformation is added to all other + transformations from surrounding or interior scopes. This means that, in + particular, the origin of a canvas transformation is, by default, the + origin of the canvas of the scope surrounding the transformation object. + + For some canvas animations, like a rotation or a scaling, you will + typically wish to use a different origin (like the center of an object that + is to be rotated or scaled). You can achieve this effect by surrounding the + object by a scope that shifts the canvas to the desired origin, followed by + a scope whose transformation matrix you animate, followed by a scope that + shifts back the canvas. + + The |origin| key simplifies this process by allowing you to specify the + origin of the transformation directly. Internally, however, all this key + does is to create the above-mentioned scopes with the necessary shifts. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, + origin = \pgfpoint{-5mm}{0mm}, entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; +} +\end{codeexample} + % +\end{key} + +\begin{animateattribute}{motion} + A second way of changing the canvas transformation matrix is to use the + |motion| attribute: + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{motion}{ + whom = node, begin on = {click}, + along = \pgfpathcircle{\pgfpointorigin}{5mm}, + entry = {0s}{.25}, entry = {2s}{.5} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + + Just like the |translate| attribute, this key also changes the bounding box + computation. + % + \begin{key}{/pgf/animation/along=\meta{path}} + This key must be used with |motion| attribute to specify a path along + which the transformation matrix will be ``moved'' (that is, a shift + transformation will be added to the different points on the path). + + The values passed to the |entry| key specify fractions of the distance + along the \meta{path}. That means, when you provide a value of |0|, you + reference the start point of the path, a value of |1| references the + end of the path and |0.5| referenced the point halfway along the path. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.25,0.5,0.75,1,1.25,1.5,1.75,2,2.25,2.5}, +] +\tikz [very thick] { + \pgfanimateattribute{motion}{ + whom = node, begin on = {click}, + along = \pgfpathmoveto{\pgfpointorigin} + \pgfpathlineto{\pgfpoint{0mm}{5mm}}, + entry = {0s}{0}, entry = {1s}{0.5}, entry = {2s}{0.25}, entry={3s}{1} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + \end{key} + + \begin{key}{/pgf/animation/rotate along=\meta{Boolean} (default true)} + When set to |true|, the |along| key additionally adds a rotation that + varies in such a way that a tangent to the path always points right. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0.5,1,1.5,2}, +] +\tikz [very thick] { + \pgfanimateattribute{motion}{ + whom = node, begin on = {click}, + rotate along = true, + along = \pgfpathmoveto {\pgfpointorigin} + \pgfpathcurveto{\pgfpoint{5mm}{0cm}}{\pgfpoint{5mm}{0cm}} + {\pgfpoint{5mm}{5mm}}, + entry = {0s}{0}, entry = {2s}{1} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + \end{key} +\end{animateattribute} + +The final method of changing the transformation matrix is to animate a +\emph{view.} + +\begin{animateattribute}{view} + A view is a canvas transformation that shifts and scales the canvas in such + a way that a certain rectangle ``matches'' another rectangle: The idea is + that you ``look through'' a ``window'' (the view) and ``see'' a certain + area of the canvas. View animation do not allow you to do anything that + cannot also be done using the |translate| and |scale| keys in combination, + but it often much more natural to animate which area of a graphic you wish + to see than to compute and animate a scaling and shift explicitly. + + In order to use a view, you first need to create a view, which is done + using a |{pgfviewboxscope}|, see Section~\ref{section-base-view}, which is + used by the |views| library internally. You can then animate the view using + the |view| attribute. The values passed to the |entry| key must be two + \pgfname-points, each surrounded by parentheses. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations} +\usetikzlibrary{views}}, + animation list={0.5,1,1.5,2}, + animation bb={(1.1,-0.9) rectangle (2.9,0.9)}, +] +\tikz [very thick] { + \pgfanimateattribute{view}{ + whom = me.view, begin on = {click, of next=node}, freeze at end, + entry = {0s}{{\pgfpoint{0mm}{0mm}}{\pgfpoint{20mm}{20mm}}}, + entry = {2s}{{\pgfpoint{10mm}{10mm}}{\pgfpoint{15mm}{15mm}}} } + \node (node) [fill = blue!20, draw = blue, very thick, circle] {Click me!}; + + \draw [green!50!black] (1.2,-0.8) rectangle (2.7,0.8); + \begin{scope}[name = me, view = {(0,0) (2,2) at (1.2,-0.8) (2.7,0.8)}] + \draw [red] (10mm,10mm) rectangle (15mm,15mm); + \node at (10mm,10mm) [circle, fill=red, text=white, font=\tiny] {red}; + \end{scope} +} +\end{codeexample} + +\begin{codeexample}[ + width=2cm, + preamble={\usepgfmodule{animations} +\usetikzlibrary{views}}, +] +\tikz [very thick] { + \pgfanimateattribute{view}{ + whom = me.view, begin on = {click, of next=n1}, freeze at end, + entry = {0s}{\pgfpoint{0mm}{0mm}}{\pgfpoint{2cm}{2cm}}, + entry = {2s}{{\pgfpoint{5mm}{5mm}}{\pgfpoint{15mm}{20mm}}} } + \pgfanimateattribute{view}{ + whom = me.view, begin on = {click, of next=n2}, freeze at end, + entry = {0s}{\pgfpoint{0mm}{0mm}}{\pgfpoint{2cm}{2cm}}, + entry = {2s}{{\pgfpoint{10mm}{10mm}}{\pgfpoint{15mm}{15mm}}} } + \node (n1) at (0,0) [fill = blue!20, draw = blue, circle] {Zoom blue}; + \node (n2) at (2,0) [fill = blue!20, draw = blue, circle] {Zoom red}; + + \draw [green!50!black] (4,0) rectangle (6,2); + \begin{scope}[name = me, view = {(0,0) (2,2) at (4,0) (6,2)}] + \draw [blue] (5mm,5mm) rectangle (15mm,20mm); + \node at (5mm,5mm) [circle, fill=blue, text=white] {blue}; + + \draw [red] (10mm,10mm) rectangle (15mm,15mm); + \node at (10mm,10mm) [circle, fill=red, text=white, font=\tiny] {red}; + \end{scope} +} +\end{codeexample} + % +\end{animateattribute} + + +\subsection{Commands for Specifying Timing: Beginnings and Endings} + +Using the |entry| key repeatedly, you specify a timeline: The \meta{time} used +with the first use of the |entry| key in a timeline is the start time and the +\meta{time} in the last |entry| key is the stop time. However, this leaves open +then question of when the whole timeline is to be started: The moment the +document is opened? When the page is displayed? When the user scrolls to the +to-be-animated object? When some other object is clicked? The key |begin|, and +also the key |end|, allow you to specify answers to these questions. + +\begin{key}{/pgf/animation/begin=\meta{time}} + This key specifies when the ``moment |0s|'' should be relative to the + moment when the current graphic is first displayed. You can use this key + multiple times, in this case the timeline is restarted for each of the + times specified (if it is already running, it will be reset). If no |begin| + key is given at all, the effect is the same as if |begin=0s| had been + specified. + + It is permissible to set \meta{time} to a negative value. +\end{key} + +\begin{key}{/pgf/animation/end=\meta{time}} + This key will truncate the timeline so that it ends \meta{time} after the + display of the graphic, provided the timeline begins before the specified + end time. For instance, if you specify a timeline starting at 2\,s and + ending at 5\,s and you set |begin| to 1\,s and |end| to 4\,s, the timeline + will run, relative to the moment when the graphic is displayed from 3\,s to + 4\,s. + % +\begin{codeexample}[preamble={\usepgfmodule{animations}},width=3cm] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin = 2s, end = 4s, + entry = {1s}{0}, entry = {2s}{90}, entry = {3s}{180}, entry = {4s}{270} } + \node (node) [fill = blue!20, draw = blue, circle] {Turn after 3s!}; } +\end{codeexample} + % +\end{key} + +It is not immediately clear what should happen with the attribute of an object +when an animation ends: Should it revert to its original value ``as if there +had never been an animation'' or should it ``stay at the last value''? The +following key governs what should happen: + +\begin{key}{/pgf/animation/freeze at end=\meta{true or false} (default true, initially false)} + When set to |true|, whenever a timeline ends (either because the last time + of timeline has been reached or because an |end| or |end of| key have ended + it prematurely), the last value the attribute had because of the animation + ``stays put''. When set to |false|, which is the initial value, once an + animation ends, its effect will be removed ``as if it never happened''. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0,1,2,3,4}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, freeze at end = false, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Here!}; } +\end{codeexample} + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={0,1,2,3,4}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, freeze at end, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Here!}; } +\end{codeexample} + % +\end{key} + +Instead of specifying the beginning of the timeline relative to the moment to +to-be-animated graphic is displayed, you can also set the ``moment |0s|'' to +the moment a specific \emph{event} happens using the following key: + +\begin{key}{/pgf/animation/begin on=\meta{options}} + Has the same effect as |/tikz/animate/option/begin on|, see + Section~\ref{section-anim-begin-end}. +\end{key} + +When you use |begin on| to start an animation when a certain event is +triggered, it is not clear what should happen when the event is triggered +\emph{again}. Should this be ignored completely? Should it only be ignored +while the animation is running? The following key allows you to specify when +should happen: + +\begin{key}{/pgf/animation/restart=\meta{choice} (default true)} + Has the same effect as |/tikz/animate/option/restart|, see + Section~\ref{section-anim-begin-end}. +\end{key} + +Just like |begin on| specifies when a timeline begins relative to some event, +the |end on| allows you to stop is early when some event happens: + +\begin{key}{/pgf/animation/end on=\meta{options}} + Works exactly like |begin on|, one possible end of the timeline is + specified using the \meta{options}. +\end{key} + + +\subsection{Commands for Specifying Timing: Repeats} + +Normally, a timeline is displayed once and then ends. You can, however, request +that the timeline should be repeated a certain number of times or indefinitely. + +\begin{key}{/pgf/animation/repeats=\meta{specification}} + Use this key to specify that the timeline animation should repeat at the + end. The \meta{specification} must consist of two parts, each of which may + be empty. The first part is one of the following: + % + \begin{itemize} + \item Empty, in which case the timeline repeats forever. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4,5}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, repeats, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + % + \item A \meta{number} (like |2| or |3.25|), in which case the timeline + repeats \meta{number} times. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4,5}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, repeats = 1.75, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + % + \item The text ``|for| \meta{time}'' (like |for 2s| or |for 300ms|), in + which case the timeline repeats however often necessary so that it + stops exactly after \meta{time}. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4,5}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, repeats = for 3.5s, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + \end{itemize} + % + The second part of the specification must be one of the following: + % + \begin{itemize} + \item Empty, in which case each time the timeline is restarted, the + attribute's value undergoes the same series of values it did + previously. + \item The text |accumulating|. This has the effect that each time the + timeline is restarted, the attribute values specified by the + timeline are \emph{added} to the value from the previous + iteration(s). A typical example is an animation that shifts a scope + by, say, 1\,cm over a time of 1\,s. Now, if you repeat this five + times, normally the scope will shift 1\,cm for 1\,s then ``jump + back'', shift again, jump back, and so on for five times. In + contrast, when the repeats are accumulating, the scope will move by + 5\,cm over 5\,s in total. + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4,5}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, repeats = accumulating, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + % +\begin{codeexample}[ + preamble={\usepgfmodule{animations}}, + animation list={1,2,3,4,5}, +] +\tikz [very thick] { + \pgfanimateattribute{rotate}{ + whom = node, begin on = {click}, repeats = 2 accumulating, + entry = {0s}{0}, entry = {2s}{90} } + \node (node) [fill = blue!20, draw = blue, circle] {Click me!}; } +\end{codeexample} + \end{itemize} +\end{key} + +\begin{key}{/pgf/animation/repeat=\meta{specification}} + This is an alias for |repeats|. +\end{key} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "pgfmanual" +%%% End: |