1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654
|
% 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{Animation System Layer}
\label{section-pgfsys-anim}
\begin{codeexample}[setup code,hidden]
\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};
}%
}
\end{codeexample}
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}[
preamble={\usetikzlibrary{animations}},
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,preamble={\usetikzlibrary{animations}}]
\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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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,setup code]
\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}
%
% TODOsp: codeexamples: this definition is needed for the next 4 `codeexample`s
% but because of the hash sign it can't simply be added `pre`
\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,
preamble={\usetikzlibrary{animations}},
animation list={0.5,1,1.5,2},
]
\animationcanvasexample
{}
{}
\end{codeexample}
%
\begin{codeexample}[
width=9.9cm,
preamble={\usetikzlibrary{animations}},
animation list={0.5,1,1.5,2},
]
\animationcanvasexample
{\pgfsys@transformshift{10mm}{0mm}}
{\pgfsys@transformshift{-10mm}{0mm}}
\end{codeexample}
%
\begin{codeexample}[
width=9.9cm,
preamble={\usetikzlibrary{animations}},
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,
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
preamble={\usetikzlibrary{animations}},
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}[
width=5cm,
preamble={\usetikzlibrary{animations,views}},
animation list={0.5,1,1.5,2},
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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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,
preamble={\usetikzlibrary{animations}},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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}[
width=6cm,
preamble={\usetikzlibrary{animations}},
animation list={1,2,3,4,5,6,7,8},
]
\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:
|