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 2016 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.
\section{Animation System Layer}
\label{section-pgfsys-anim}
\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:
|