5 Pict Animators
function | |||||||||||||
|
The deps list determines the replaceable dependencies of animate’s result, while a snapshot result determines the findable children. The snapshot function is called with deps as an optional ~deps argument, except that each pict in deps is potentially adjusted through Pict.rebuild or Pict.replace before it is passed back to snapshot. The config argument similarly provides a map that can be passed back to snapshot as a ~config argument, possibly adjusted through Pict.rebuild or Pict.configure.
The resulting pict’s duration is 1, and the extent of that duration is determined by the extent argument. Before the pict’s time box, its drawing and bounding box are the same as Pict.ghost(proc(0, & children)); after its time box, they are the same as Pict.ghost(proc(1, & children)).
The bender function adjusts the argument that is passed to animate. If bender is the identity function, then the number passed to proc ranges from 0 to 1 linearly with animation time. The default bend.fast_middle keeps the argument in the range 0 to 1, but it causes the argument to proc change more slowly near 0 and 1 and more quickly around 0.5.
If sustain_edge is #'before, then Pict.sustain for the resulting pict will extend its time box by adding an epoch to the start with the static representation Pict.ghost(proc(0)). If sustain_edge is #'after, then Pict.sustain instead adds to the end of the time box with the static representation Pict.ghost(proc(1)).
> explain_anim(animate(bar))
> explain_anim(animate(bar).sustain())
> explain_anim(animate(bar, ~sustain_edge: #'before).sustain())
function | ||||||||||||||||||||
|
The picts in deps might be replaced via Pict.rebuild or Pict.replace on the result of animate_map, in which case the replacements are passed back to combine as the ~deps argument. The optional config similarly can be updated via Pict.rebuild or Pict.configure before it is passed back as the ~config argument to combine.
If all picts in deps satisfy StaticPict and nonsustain_combine is #false, then the result also satisfies StaticPict. In that case, combine is called with 0s as its epoch and time arguments. Picts in deps can be replaced with static or animated picts, and the rebuild result of animate_map is accordingly static or animated.
When deps does not contain only StaticPicts, the deps are made concurrent via concurrent, passing along duration_align and epoch_align. The result pict’s duration is the maximum of the durations of the deps.
The combine function is used for all epochs of the result from animate_map. If additional epochs are added to the result via Pict.sustain, those epochs also use combine. If nonsustain_combine is a function, and if non-sustain epochs are added to the result of animate_map, then nonsustain_combine is used for those epochs.
> explain_anim(
animate_map(~deps: [sq_grow],
~precision: 1))))
)
property | |
| |
method | |
1
> text("Hello").epoch_extent(0)
0
2
1
> p.epoch_extent(0)
0.5
> switch(text("Hello"), p).epoch_extent(1)
0.5
method | ||||
|
If rebuild_prompt is #false, then a rebuilding operation on the result pict via Pict.rebuild is propagated to the original pict, and a snapshot of the rebuilt pict is taken for the overall rebuild result. If rebuild_prompt is a true value, then then a rebuilding operation rebuilds in the initial snapshot, instead of taking a snapshot of a rebuilt pict.
The result snapshot’s identity is the same as the identity of pict if rebuild_prompt is #true. If rebuild_prompt is #false, the result identity is fresh and it depends on pict, but the snapshot is also findable as pict. See also Pict Findable and Replaceable Identity.
method | |||||
1
3
3
> def p = circle(~size: 20, ~fill: "lightgreen").nonsustaining()
3
method | ||||
> rectangle(~around: p.time_clip().snapshot(2, 0.0)) is_a NothingPict
#true
The result is the same as
Pict.time_clip(animate(fun (n): if n .= 0 | pict.snapshot() | nothing,
~extent: 0))
> p.instantaneous().snapshot(0, 0.1)
> p.instantaneous().snapshot(0, 0.1) is_a NothingPict
#true
When epoch is within pict’s time box—
> def q = p.time_insert(0, 3)
> p.epoch_extent(0)
0
> q.epoch_extent(0)
0.5
method | ||
| ||
method | ||
When picts are combined through operations like beside or overlay, the combination’s metadata is formed by merging metadata maps from the combined picts, and later picts in the combination take precedence.
function | |
| |
function | |
| |
function | |
| |
function | |
|
|
|
|
| ||||
|
|
|
|
| ||||
|
|
|
|
function | |||||||||||
|
If fit is #'none, from and to are unscaled for intermediate points in the fade, and they are positioned relative to the bounding box using overlay with horiz_align and vert_align. The order argument is also used as for overlay. If fit is #'scale, then from and to are scaled to fit the bounding box as they fade out and in.
The cross fade takes extent seconds. The bender argument maps time within the epoch to an interpolation point, the same as with animate.
When using cross_fade plus Pict.snapshot to compute an interpolation between two picts, then bender should normally be values so that the second argument to Pict.snapshot is the interpolation point.
> explain_anim(cross_fade(circle(~size: 15), square(~size: 25)))
> explain_anim(cross_fade(circle(~size: 15), square(~size: 25),
~fit: #'scale))
> explain_anim(cross_fade(circle(~size: 15), square(~size: 25),
~horiz: #'left))
function | |||||||||
|
If other is #'switch elements not common to from and to appear in the first or second half of the animation, depending on whether they are only in from or only in to. If other is #'fade, then non-common element fade out and in.
The move takes extent seconds, and the bender argument maps time the same as with animate.
> pre
> post
> explain_anim(magic_move(pre, post), ~steps: 7, ~end: 1)
> explain_anim(magic_move(pre, post, ~other: #'fade), ~steps: 7, ~end: 1)
enumeration | |||
function | |||||||||||
|
If show_timebox is a true value, then a box is drawn around points on the timeline that are within pict’s time box.
If pad_before or pad_after are not 0, then space is added to the left or right of the timeline, respectively, corresponding to pad_before or pad_after epochs. This padding can be useful for aligning timelines that have different starting or ending epochs.
> explain_anim(animate(fun (n): circle(~fill: "blue").alpha(1-n)),
~steps: 5)