4 Pict Combiners
function | |||||||||
|
If a pict extends horizontally outside its bounding box, then the front-to-back order of picts can matter for the combined image. The order argument determines the order of each pict added to the right of the combined image.
If attach is #'paragraph instead of line, then each pict is positioned relative to the preceding pict’s paragraph-end bounds, if any, instead of relative to the preceding pict itself. See Pict.paragraph_end_bounds.
The picts are first made concurrent via concurrent, passing along duration_align and epoch_align.
If no picts are provided, the result is nothing.
> explain_anim(beside(square(~size: 32).sustain(),
> explain_anim(beside(square(~size: 32).sustain(),
~duration: #'pad))
function | ||||||||
|
If a pict extends vertically outside its bounding box, then the front-ot-back order of picts can matter for the combined image. The order argument determines the order of each pict added to the bottom of the combined image.
The picts are first made concurrent via concurrent, passing along duration_align and epoch_align.
If no picts are provided, the result is nothing.
> stack(~horiz: #'right, ~sep: 12, square(~size: 32), circle(~size: 16))
function | ||||||||||
|
The horiz_align argument determines how each pict is positioned horizontally relative to other picts, and the vert_align argument determines how each pict is positioned vertically relative to other picts. The resulting pict’s bounding box is computed as in beside to cover all of the input pict bounding boxes.
If dx or dy is provided, then each pict after the first one is shifted by dx or dy from the position where it would otherwise be placed relative to the first pict based on horiz_align and vert_align. The resulting pict’s bounding box is computed after this adjustment.
The picts are first made concurrent via concurrent, passing along duration_align and epoch_align.
If no picts are provided, the result is nothing.
circle(~size: 16, ~fill: "lightgreen"))
square(~size: 32),
circle(~size: 16, ~line: "red"))
function | |||||||||||
|
By default, the pinned pict is concurrent to the target on_pict. The picts are first made concurrent via concurrent, passing along duration_align and epoch_align. This mode is used unless time_align is #'insert.
The time_align argument determines a time box offset that is applied to pict, finder, and pinhole_finder before combining it with on_pict. If time_align is #'insert or ~sync, then finder is used both to find a graphical offset and a time box offset. If time_align is insert, then at the time box offset within on_pict, extra epochs are inserted that correspond to a snapshot of on_pict at the time box offset, and the number of inserted epochs is the duration of pict. When time_align When time_align is an integer, #'start, or #'end, then finder is not used to find a time offset, and instead time_align, 0, or Pict.duration(on_pict) is used, respectively.
If find_mode is #'always, then if finder fails to find a position at any time for on_pict, then an exception is thrown. If find_mode is #'maybe, then when finder fails to find a position, pict is not pinned.
> pin(~on: overlay(square(~size: 32, ~fill: "lightblue"), circ),
~at: Find.right(circ),
line(~dx: 10))
function | ||||||||||||||||||||||
|
If find_mode is #'always, then if form or to fails to find a position at any time for on_pict, then an exception is thrown. If find_mode is #'maybe, then when from or to fails to find a position, a line is not added.
Find.right(sq),
Find.left(circ),
~style: #'arrow,
~line: "red",
~arrow_size: 8)
function | |||||||||||||||||
|
[blank(), sq, circ],
~vert: #'top,
~vline: "black",
~pad: 5)
If join is #'splice, the the ending epoch or each pict is merged with the starting epoch of the next pict. The merged epoch’s extent is the sum of the original extends, and the switch from each earlier to latter pict happens at a point within the merged epoch corresponding to earlier epoch’s duration. Note that this merging normally makes sense only with non-0 extents. If splice is #'after or #false, then each switch boundary uses the latter pict, otherwise it uses the earlier pict.
If no picts are provided, the result is nothing.
> explain_anim(switch(circ, sq))
> explain_anim(rectangle(~around: switch(circ, sq), ~order: #'back))
> def circ1 = circ.epoch_set_extent(0, 1.0)
> def sq1 = sq.epoch_set_extent(0, 1.0)
> explain_anim(switch(circ1, sq1, ~splice: #'after),
~steps: 6)
> explain_anim(switch(circ1, sq1, ~splice: #'before),
~steps: 6)
function | |||||
|
If duration_align is #'pad, the time boxes are extended as needed in the “after” direction using Pict.pad. If duration_align is #'sustain, then Pict.sustain is used. Note that the default for duration_align is #'pad, but when concurrent is called by functions like beside, the default is #'sustain.
The epoch_align argument determines how animations are positioned within an extent when extents are made larger to synchronize with concurrent, non-0 extents.
Any nothing among the picts is preserved in the output list, but it does not otherwise participate in making the other picts concurrent.
> explain_anim(overlay(& concurrent(sq, circ)))
> explain_anim(overlay(& concurrent(sq.sustain(), circ)))
> explain_anim(overlay(& concurrent(sq.sustain(), circ,
~duration: #'sustain)))
function | ||||||
|
When join is #'splice, then the last epoch of each pict is aligned with the first epoch of the next pict, the synchronized epoch’s extent for each pict becomes the sum of the extents, the earlier pict’s animation within the epoch is mapped into the earlier part of the combined extent, and the later pict’s animation is within the epoch is mapped into the later part of the combined extent. When multiple adjacent picts each have a duration of 1, then the epoch of all of those picts is aligned with the last epoch of the pict before and first epoch of the pict after.
If to_concurrent is true, then after the picts are sequentialized, they are passed to #'concurrent. The duration_align argument is passed along in that case.
Any nothing among the picts is preserved in the output list, but it does not otherwise participate in making the other picts sequential.
> explain_anim(overlay(& sequential(sq, circ)))
> explain_anim(rectangle(~around: overlay(& sequential(sq, circ)),
~order: #'back))
> explain_anim(overlay(& sequential(sq, circ, ~duration: #'sustain)))
> explain_anim(overlay(& sequential(sq, circ,
// defer to `overlay` ~duration:
~concurrent: #false)))
> def circ_grow = animate(fun (n): circ.scale(1, 1 + n)).sustain()
> def sq_grow = animate(fun (n): sq.scale(1, 1 + n)).sustain()
> explain_anim(overlay(& sequential(sq_grow, circ_grow)),
~steps: 3)
> explain_anim(overlay(& sequential(sq_grow, circ_grow, ~join: #'splice)),
~steps: 3)
function | |
| |
| |
function | |
| |
| |
function | |
| |
| |
function | |
| |
| |
function | |
|
function | |
| |
| |
function | |
| |
| |
function | |
|
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
enumeration | ||||
enumeration | |||
enumeration | |||
enumeration | |||
enumeration | |||
enumeration | ||||