Function Repository Resource:

EvolutionViewFunction

Source Notebook

Generate a function that displays graphical objects at successive times

Contributed by: Jaroslav Kysela

ResourceFunction["EvolutionViewFunction"][imgs]

generates a function representing a time-evolving succession of graphical objects imgs.

ResourceFunction["EvolutionViewFunction"][imgs,mode]

shows successive objects according to mode.

ResourceFunction["EvolutionViewFunction"][imgs,mode,times]

shows objects at times specified by times.

ResourceFunction["EvolutionViewFunction"][imgs,mode,times,pos]

places the origin of the sequence of objects at pos.

Details and Options

ResourceFunction["EvolutionViewFunction"] takes a sequence of graphical objects and returns a function that shows a particular object depending on a numeric time parameter. This function can be directly used inside an Animate or Manipulate command. Such a function can be used to represent simple animations, time evolution diagrams or dynamic labeling.
The function returned by ResourceFunction["EvolutionViewFunction"] is a Piecewise function wrapped in Function. This function itself consists of many Piecewise sub-cases, each representing a single step of the evolution. Three different groups of steps can be identified:
first stageat first, an initial subsequence of objects is shown, whose form is determined by mode
mid-stagesa sequence of stages that implement the actual time evolution, each of which consists of six sub-stages
last stageat last, the final subsequence of objects is shown, whose form is determined by mode
Each mid-stage consists of the following sub-stages:
emergenew elements appear in the subsequence currently shown
wait1after the emerge phase is finished, the elements are kept fixed
fadeawaythen some of the older elements fade away
wait2after the fadeaway phase is finished, the remaining elements are kept fixed
movethe remaining elements are moved aside to make space for new elements that are to emerge in the next sub-stage
wait3after the move phase is finished, the remaining elements are kept fixed
For each sub-stage of each mid-stage as well as for the first and last stages different duration specifications can be given.
Objects accepted as imgs can be either lists of vector graphics primitives accepted by Graphics, or they can be objects with heads Image, Graphics, or Graphics3D.
Possible settings for mode include:
"Increase"increase successively the number of elements shown until their number reaches the maximum default value; then update elements but keep their number constant (default)
"Decrease"start with the sequence of the maximum number of elements and then decrease their number until a single element remains
"IncreaseDecrease"at first increase the number of elements; then keep their number constant; at the end decrease their number to a single element
"Continue"like "IncreaseDecrease" but the decreasing stage of the sequence is aligned to the opposite side
"Constant"keep the number of elements shown constant
"OneByOne"show only a single element at a time
{mode,maxnum}specify mode as well as the maximum number maxnum of elements shown (set to 2 by default); when maxnum is set to 1, the mode is automatically switched to "OneByOne"
Possible settings for times include:
Automaticeach sub-stage lasts 1 unit of time (default)
dureach sub-stage lasts dur units of time
{durem,durw1,durfade,durw2,durmove,durw3}specify duration of each sub-stage
{{durem1,},{durem2,},}specify duration of each sub-stage for each mid-stage separately
{dursmid,{durfirst,durlast}}specify durations dursmid for mid-stages using the above-mentioned formats and also separately set the duration of the first stage dursfirst and the last stage durlast
{dursmid,dursfirstlast,timestamps}specify also absolute timestamps for the start of each mid-stage as well as the last stage
{Automatic,Automatic,timestamps}specify only the timestamps
Value of pos is a 2D vector (set to {0,0} by default).
The following options can be given:
AlignmentRightalignment of the sequence with respect to the pos
DirectionLeftdirection of movement of elements
DividersAutomaticgraphical object inserted between each two successive elements
ItemSize0.5size of each graphical object
RotateLabel{True,π}whether to rotate graphical objects depending on Direction
Spacings1spacing between the centers of each two successive elements
VerboseFalsewhether to return the summary Association
"EmergeFunction"Automaticfunction applied to new elements
"FadeFunction"Automaticfunction applied to old elements
"NormalizeTimes"Falsewhether to normalize the total duration of the sequence
Possible settings for Alignment include:
Rightsequence aligned to the right (default)
Leftsequence aligned to the left
Centersequence aligned to the center
Topsequence aligned vertically to the top
Bottomsequence aligned vertically to the bottom
Noneno alignment applied
{hor,ver}horizontal alignment hor, which can be set to Right,Left or Center, and vertical alignment ver, which can be set to Top,Bottom or Center
{hor,ver,rel}specify also the relative alignment of elements within the sequence, possible values are Right,Left and Center
When Alignment is set to Center, the mode "Continue" behaves the same way as "IncreaseDecrease".
Possible settings for Direction include:
Leftmove elements to the left (default)
Rightmove elements to the right
Upmove elements upward
Downmove elements downward
angmove elements along a line that subtends an angle ang with respect to the positive x-axis
{x,y}move elements along a vector {x,y}
The object supplied to Dividers may be of the same form as those supplied to the first argument imgs. Only one object is expected. By default, a black thin Arrow is shown.
The value of ItemSize is used only when the head of a given graphical element is Image, Graphics, or Graphics3D. In that case, the element is wrapped up into an Inset construct and its size is set to ItemSize.
Possible settings for RotateLabel include:
Truerotate both the elements and the dividers based on the setting of Direction
Falsedo not rotate anything
{rotelems,rotdivs}whether to rotate elements and dividers is specified by rotelems and rotdivs, respectively
{rot,addang}rotate both elements and dividers and add a constant angle offset of addang (default is {True,π})
{{rot,addang}}the same as above
{{rotelems,addangelems},{rotdivs,addangdivs}}specify the rotation and the constant angle offset for elements and dividers separately
The value of Spacings is taken as the distance between the centers of two successive elements of the sequence, where the possible Dividers are ignored.
When Verbose is set to True, ResourceFunction["EvolutionViewFunction"] returns an Association that contains information about many parameters of the time evolution. Especially relevant are timestamps and (unnormalized) durations of each stage of the evolution.
Possible settings for "EmergeFunction" include:
Automaticnew objects slowly emerge (default)
Nonenew objects appear immediately
funfunction fun is applied to each new object
{funfirst,funrest}function funfirst is applied to the sequence of elements at the very beginning of the evolution and then function funrest is applied to each new object
Possible settings for "FadeFunction" include:
Automaticnew objects slowly fade away (default)
Nonenew objects disappear immediately
funfunction fun is applied to each object that is to be disposed of
{funmost,funlast}function funmost is applied to old elements in the course of the evolution and then function funlast is applied to the remaining sequence of objects
Each of the functions supplied to "EmergeFunction" and "FadeFunction" is expected to be of the form fun[gr_,t_], where gr is a graphical object and t is a time parameter, which is always expected to run from zero to one.
When "NormalizeTimes" is set to True (default), the duration of each stage is modified such that the total duration of the time evolution is equal to one.

Examples

Basic Examples (3) 

Create a simple animation where one colored image follows another:

In[1]:=
images = ResourceFunction["EvolutionViewFunction"][{\!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{1., 0., 0.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{0., 1., 0.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{0., 0., 1.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{0., 1., 1.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{1., 0., 1.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{0.}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->GrayLevel],
BoxForm`ImageTag[
       "Real32", ColorSpace -> "Grayscale", Interleaving -> None],
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\)}, "Constant"]
Animate[Graphics[images[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> 0.1]
Out[2]=

Represent a sequence of plots in time:

In[3]:=
spirals = ParametricPlot[\[Theta] {Cos[\[Theta]], Sin[\[Theta]]}, {\[Theta], 0, #}, Axes -> False, PlotRange -> 5 \[Pi]] & /@ Range[\[Pi]/4, 5 \[Pi], \[Pi]/4];
spiralFun = ResourceFunction["EvolutionViewFunction"][
   spirals, {"IncreaseDecrease", 4}, ItemSize -> 1, Spacings -> 1.3];
Animate[Graphics[spiralFun[t], PlotRange -> {{-4.5, 0.5}, 0.5 {-1, 1}}], {t, 0, 1}, AnimationRate -> 0.05]
Out[4]=

Create a Tetris-like effect:

In[5]:=
squares = Table[{Blue, Rectangle[-0.2 {1, 1}, 0.2 {1, 1}]}, 8];
tetris = ResourceFunction["EvolutionViewFunction"][
   squares, {"IncreaseDecrease", 3}, Spacings -> 0.5, Direction -> Down, Alignment -> {Center, Bottom}, Dividers -> None];
Animate[Graphics[tetris[t], PlotRange -> {{-0.5, 0.5}, {-0.5, 1.5}}], {t, 0, 1}, AnimationRate -> 0.2]
Out[78]=

Scope (20) 

Graphical objects (3) 

The graphical objects may be images:

In[79]:=
imgs = ConstantImage[#, {1, 1}] & /@ {Red, Green, Blue, Cyan, Magenta,
     Black};
images = ResourceFunction["EvolutionViewFunction"][imgs, Spacings -> 1.2];
Animate[Graphics[images[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[81]=

They may also be Graphics objects:

In[82]:=
imgs = Graphics[{#, Disk[{0, 0}, 0.2]}] & /@ {Red, Green, Blue, Cyan, Magenta, Black};
graphics = ResourceFunction["EvolutionViewFunction"][imgs];
Animate[Graphics[graphics[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[83]=

The head Graphics may be omitted:

In[84]:=
imgs = {#, Disk[{0, 0}, 0.2]} & /@ {Red, Green, Blue, Cyan, Magenta, Black};
primitives = ResourceFunction["EvolutionViewFunction"][imgs];
Animate[Graphics[primitives[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[86]=

Modes (10) 

The default mode:

In[87]:=
default = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[1, 0, 1], 
Disk[{0, 0}, 0.2]}, {
GrayLevel[0], 
Disk[{0, 0}, 0.2]}}];
Animate[Graphics[default[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[88]=

Use mode "Increase" with at most four images shown at a time:

In[89]:=
increasefour = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[1, 0, 1], 
Disk[{0, 0}, 0.2]}, {
GrayLevel[0], 
Disk[{0, 0}, 0.2]}}, {"Increase", 4}];
Animate[Graphics[increasefour[t], PlotRange -> {{-3.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[90]=

Do not restrict the maximum number of images shown:

In[91]:=
increaseinf = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[1, 0, 1], 
Disk[{0, 0}, 0.2]}, {
GrayLevel[0], 
Disk[{0, 0}, 0.2]}}, {"Increase", Infinity}];
Animate[Graphics[increaseinf[t], PlotRange -> {{-5.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[92]=

Use the default number:

In[93]:=
increasedef = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[1, 0, 1], 
Disk[{0, 0}, 0.2]}, {
GrayLevel[0], 
Disk[{0, 0}, 0.2]}}, "Increase"];
Animate[Graphics[increasedef[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[94]=

Mode "Increase" increases the number of shown images from one to a given maximum number:

In[95]:=
increase = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Increase", 3}];
Column[Framed@
    Graphics[increase[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.4, 0.55,
    0.8, 0.95}]
Out[96]=

Mode "IncreaseDecrease" increases the number of shown images from one to a given maximum number and then decreases it again to one:

In[97]:=
increaseDecrease = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"IncreaseDecrease", 3}];
Column[Framed@
    Graphics[increaseDecrease[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.4, 0.55,
    0.8, 0.95}]
Out[98]=

When the maximum specified number is too large, it is automatically adjusted:

In[99]:=
increaseDecreaseLim = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"IncreaseDecrease", 10}];
Column[Framed@
    Graphics[increaseDecreaseLim[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.4, 0.55,
    0.8, 0.95}]
Out[100]=

Mode "Continue" works similar to "IncreaseDecrease" but the images in the decreasing part are aligned to the opposite side:

In[101]:=
continue = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Continue", 3}];
Column[Framed@
    Graphics[continue[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.215, 0.55, 0.8, 0.95}]
Out[102]=

Mode "Decrease" works similar to "Increase" but the number of images decreases:

In[103]:=
decrease = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Decrease", 3}];
Column[Framed@
    Graphics[decrease[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.4, 0.55,
    0.8, 0.95}]
Out[104]=

Mode "Constant" keeps the number of images constant:

In[105]:=
constant = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}];
Column[Framed@
    Graphics[constant[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.2, 0.4, 0.55,
    0.8, 0.95}]
Out[106]=

Mode "OneByOne" shows always only a single image at a time:

In[107]:=
oneByOne = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, "OneByOne"];
Column[Framed@
    Graphics[oneByOne[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.1, 0.15, 0.55, 0.8, 0.95}]
Out[108]=

This mode is used automatically whenever the maximum specified number is set to 1 for any of the other modes:

In[109]:=
continueOne = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Continue", 1}];
Column[Framed@
    Graphics[continueOne[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[#, {3, 3}]]] & /@ {0.1, 0.15, 0.55, 0.8, 0.95}]
Out[110]=

Durations (6) 

Specify the time duration of each step of the animation:

In[111]:=
time = 0.2;
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
givenDurs = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", time];
Framed@Graphics[givenDurs[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}},
     PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 1, 5]
Out[112]=

By default, the total time duration is set to 1; turn the normalization off:

In[113]:=
givenDursNonNorm = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", time, "NormalizeTimes" -> False];
Framed@Graphics[givenDursNonNorm[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 6.4, 5]
Out[114]=

Total duration can be read out by setting Verbose to True:

In[115]:=
ResourceFunction["EvolutionViewFunction"][imgs, "Constant", time, "NormalizeTimes" -> False, Verbose -> True]["Times", "Total duration"]
Out[115]=

Set different durations for each sub-stage:

In[116]:=
times = {5, 1, 5, 1, 5, 1};
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
givenSubDurs = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", times];

Get corresponding timestamps:

In[117]:=
timesummary = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", times, Verbose -> True]["Times"];
{time1, time2} = timesummary["Timestamps for mid stages"][[{2, 3}]];
durmid = First@
   ReleaseHold@timesummary["Individual durations for mid substages"];
midstage = time1 + Normalize[Accumulate[Prepend[durmid, 0]], Max] (time2 - time1) // N
Out[118]=

Show the evolution and timestamps:

In[119]:=
MapThread[
 Framed@Graphics[givenSubDurs[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[#] <> " \[LongDash] " <> ToString[#2]] &, {midstage, {"Start", "Emerging finished", "Waiting 1 finished", "Fading away finished", "Waiting 2 finished",
    "Movement finished", "Waiting 3 finished"}}]
Out[119]=

Durations can be specified for each mid-stage independently:

In[120]:=
times = {{5, 1, 5, 1, 5, 1}, {5, 1, 1, 1, 1, 1}, {5, 5, 4, 3, 2, 1}, {5, 1, 1, 1, 1, 1}, {5, 2, 5, 1, 5, 3}};
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
eachStage = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", times];

The number of mid-stages is given in "Number of mid stages" field of the summary Association:

In[121]:=
ResourceFunction["EvolutionViewFunction"][imgs, "Constant", times, Verbose -> True]["Numbers", "Number of mid stages"]
Out[121]=

This number is calculated automatically and can be read out also when no explicit time specification is given:

In[122]:=
ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Verbose -> True]["Numbers", "Number of mid stages"]
Out[122]=

Durations of the very first and very last stage of the animation can be set separately from the rest:

In[123]:=
durfirst = 0.2;
durlast = 0.6;
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
Dataset[ResourceFunction["EvolutionViewFunction"][imgs, "Constant", {Automatic, {durfirst, durlast}}, "NormalizeTimes" -> False, Verbose -> True]]["Times"]
Out[124]=

By default, the total duration is normalized to one and so the final durations might be different from the input values:

In[125]:=
Dataset[ResourceFunction["EvolutionViewFunction"][imgs, "Constant", {Automatic, {durfirst, durlast}}, "NormalizeTimes" -> True, Verbose -> True]]["Times"]
Out[125]=

Set explicit timestamps that specify the beginning of each mid-stage:

In[126]:=
durfirst = 0.2;
durlast = 0.6;
timestamps = {1, 2, 3, 6, 7, 8};
evolTimestamps = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, "Constant", {Automatic, {durfirst, durlast}, timestamps}, "EmergeFunction" -> None];
Framed@Graphics[evolTimestamps[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ timestamps
Out[127]=

The beginning of the animation is determined from the duration of the first stage:

In[128]:=
starttime = First[timestamps] - durfirst;
Framed@Graphics[evolTimestamps[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] &@starttime
Out[129]=

The end of the animation is determined from the duration of the last stage:

In[130]:=
stoptime = Last[timestamps] + durlast;
Framed@Graphics[evolTimestamps[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] &@stoptime
Out[131]=

When absolute timestamps are used, the durations of individual sub-stages are rescaled to fit:

In[132]:=
durmid = {5, 1, 5, 1, 5, 1};
durfirst = 0.2;
durlast = 0.6;
timestamps = {1, 2, 3, 6};
midstage = timestamps[[2]] + Normalize[Accumulate[Prepend[durmid, 0]], Max] (timestamps[[3]] - timestamps[[2]]) // N
Out[133]=
In[134]:=
evolRescaled = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True]}, "Constant", {durmid, {durfirst, durlast}, timestamps}];
MapThread[
 Framed@Graphics[evolRescaled[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[NumberForm[N@#, 3]] <> " \[LongDash] " <> ToString[#2]] &, {midstage, {"Start", "Emerging finished", "Waiting 1 finished", "Fading away finished", "Waiting 2 finished",
    "Movement finished", "Waiting 3 finished"}}]
Out[135]=

Compare with the animation itself:

In[136]:=
Animate[Graphics[evolRescaled[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, timestamps[[2]], timestamps[[3]], Appearance -> "Labeled"}, AnimationRate -> .1]
Out[136]=

Position (1) 

Place the origin of the emerging images at a given point:

In[137]:=
custompos = {0.3, 0.55};
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
evolfunDefault = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Automatic];
evolfunCustom = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Automatic, custompos];
Graphics[{evolfunDefault[0.1], evolfunCustom[0.1], Text[Style[{0, 0}, 20], {0, 0}, {0, 1}], Text[Style[custompos, 20], custompos, {0, 1}], PointSize[0.02], Point[{{0, 0}, custompos}]}, PlotRange -> {{-1.5, 0.8}, {-0.5, 1.2}}]
Out[138]=

Options (27) 

EmergeFunction (3) 

Turn off the slow-emerge effect for new images:

In[139]:=
noEmerge = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "EmergeFunction" -> None];
Animate[Graphics[noEmerge[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[140]=

Specify a custom function:

In[141]:=
emfun[gr_, t_?NumericQ] := Scale[gr, t]
scaleUp = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "EmergeFunction" -> emfun];
Animate[Graphics[scaleUp[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[142]=

Specify different "EmergeFunction" for the very first stage and the rest:

In[143]:=
emfunFirst[gr_, t_?NumericQ] := Scale[gr, t]
emfunRest[gr_, t_?NumericQ] := gr /. col_?ColorQ :> Blend[{Transparent, col}, t]
scaleUpEm = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "EmergeFunction" -> {emfunFirst, emfunRest}];
Animate[Graphics[scaleUpEm[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[144]=

FadeFunction (3) 

Turn off the slow-fade-away effect for old images:

In[145]:=
noFadeAway = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "FadeFunction" -> None];
Animate[Graphics[noFadeAway[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[146]=

Specify a custom function:

In[147]:=
fadefun[gr_, t_?NumericQ] := Scale[gr, t]
scaleDown = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "FadeFunction" -> fadefun];
Animate[Graphics[scaleDown[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[148]=

Specify different "FadeFunction" for the very last stage and the rest:

In[149]:=
fadefunMost[gr_, t_?NumericQ] := Scale[gr, t]
fadefunLast[gr_, t_?NumericQ] := gr /. col_?ColorQ :> Blend[{Black, col}, t]
scaleDownFade = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, "FadeFunction" -> {fadefunMost, fadefunLast}];
Animate[Graphics[scaleDownFade[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[150]=

NormalizeTimes (2) 

By default, the time intervals are normalized such that the total duration of animation is 1:

In[151]:=
timeint = 0.2;
imgs = {{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}};
normTimes = ResourceFunction["EvolutionViewFunction"][imgs, {"Constant", 3}, timeint];
Framed@Graphics[normTimes[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}},
     PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[5]
Out[152]=

Set "NormalizeTimes" to False to turn off the normalization:

In[153]:=
notNormTimes = ResourceFunction["EvolutionViewFunction"][imgs, {"Constant", 3}, timeint, "NormalizeTimes" -> False];
Framed@Graphics[notNormTimes[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 2.8, 5]
Out[154]=

The total duration of the animation can be obtained by setting Verbose to True:

In[155]:=
ResourceFunction["EvolutionViewFunction"][imgs, {"Constant", 3}, timeint, "NormalizeTimes" -> False, Verbose -> True]["Times", "Total duration"]
Out[155]=

When explicit timestamps are used, the value of "NormalizeTimes" is ignored:

In[156]:=
explicitTimestamps = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, {Automatic, Automatic, {1, 2, 3}}, "NormalizeTimes" -> True];
Framed@Graphics[explicitTimestamps[#], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 4, 5]
Out[157]=

The total duration:

In[158]:=
ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, {Automatic, Automatic, {1, 2, 3}}, "NormalizeTimes" -> False, Verbose -> True]["Times", "Total duration"]
Out[158]=

Verbose (4) 

Summary of different internal parameters can be displayed by setting Verbose to True:

In[159]:=
imgs = {\!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{1., 0., 0.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{0., 1., 0.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\), \!\(\*
GraphicsBox[
TagBox[RasterBox[RawArray["Real32",{{{0., 0., 1.}}}], {{0, 1}, {1, 0}}, {0., 1.},
ColorFunction->RGBColor],
BoxForm`ImageTag["Real32", ColorSpace -> "RGB", Interleaving -> True],
       
Selectable->False],
DefaultBaseStyle->"ImageGraphics",
ImageSizeRaw->{1, 1},
PlotRange->{{0, 1}, {0, 1}}]\)};
summary = ResourceFunction["EvolutionViewFunction"][imgs, Verbose -> True];
Dataset[summary]
Out[160]=

For precise synchronization with other animated elements, "Timestamps for mid stages" and "Time specification" are especially relevant:

In[161]:=
summary["Times", "Timestamps for mid stages"]
Out[161]=
In[162]:=
summary["Times", "Time specification"]
Out[162]=
In[163]:=
Last[summary["Times", "Time specification"]] == summary["Times", "Timestamps for mid stages"]
Out[163]=

The latter can be plugged back into EvolutionViewFunction as the time specification and then manually modified:

In[164]:=
evolfunOld = ResourceFunction["EvolutionViewFunction"][imgs, Automatic, summary["Times", "Time specification"], Spacings -> 1.2];
newtimes = summary["Times", "Time specification"];
newtimes[[2, 2]] = 3;
evolfunNew = ResourceFunction["EvolutionViewFunction"][imgs, Automatic, newtimes,
    Spacings -> 1.2];

The new function has the last fade-away stage a little longer:

In[165]:=
{Framed@Graphics[evolfunOld[0.99], PlotLabel -> Column[{Style["evolfun", Bold], "t = 0.99"}, Alignment -> Center]], Framed@Graphics[evolfunNew[0.99], PlotLabel -> Column[{Style["evolfunNew", Bold], "t = 0.99"}, Alignment -> Center]]}
Out[165]=

Dividers (2) 

Turn off the default dividers:

In[166]:=
noDividers = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, Dividers -> None];
Animate[Graphics[noDividers[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[167]=

Use custom dividers:

In[168]:=
div = Graphics[{Gray, Polygon[{{0, -0.5}, {1, 0}, {0, 0.5}}]}];
triangles = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 1], 
Disk[{0, 0}, 0.2]}, {
RGBColor[1, 0, 1], 
Disk[{0, 0}, 0.2]}}, {"Constant", 3}, Dividers -> div];
Animate[Graphics[triangles[t], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[169]=

RotateLabel (1) 

By default, images as well as dividers are rotated according to the direction of movement:

In[170]:=
imgs = {
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[1, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[2, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[3, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[4, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[5, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[6, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[7, 50, Bold, 
GrayLevel[0]], {0, 0}]}], 
Graphics[{
RGBColor[0, 1, 0], 
Rectangle[{-0.2, -0.2}, {0.2, 0.2}], 
Text[
Style[8, 50, Bold, 
GrayLevel[0]], {0, 0}]}]};
evolfunRot = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Direction -> 80 Degree];
evolfunNoRot = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Direction -> 80 Degree, RotateLabel -> False];
{
 Framed@Graphics[evolfunRot[0.2], PlotRange -> {{-0.5, 0.5}, {-1., 1.}}, PlotLabel -> "RotateLabel\[Rule]True"],
 Framed@Graphics[evolfunNoRot[0.2], PlotRange -> {{-0.5, 0.5}, {-1., 1.}}, PlotLabel -> "RotateLabel\[Rule]False"]
 }
Out[171]=

Spacings (2) 

Set the spacings between the centers of graphical objects:

In[172]:=
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
evolfunNarrow = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Spacings -> 1];
evolfunWide = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Spacings -> 2];
{
 Framed@Graphics[evolfunNarrow[0.0975], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "Spacings\[Rule]1"],
 Framed@Graphics[evolfunWide[0.0975], PlotRange -> {{-2.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "Spacings\[Rule]2"]
 }
Out[173]=

The Spacings value always refers to the spacing in the direction specified by Direction:

In[174]:=
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
evolfunNarrow = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Spacings -> 1, Direction -> 80 Degree, Alignment -> {Left, Bottom}];
evolfunWide = ResourceFunction["EvolutionViewFunction"][imgs, "Constant", Spacings -> 2, Direction -> 80 Degree, Alignment -> {Left, Bottom}];
{
 Framed@Graphics[evolfunNarrow[0.0975], PlotRange -> {{-0.5, 1}, {-0.5, 2.5}}, PlotLabel -> "Spacings\[Rule]1"],
 Framed@Graphics[evolfunWide[0.0975], PlotRange -> {{-0.5, 1}, {-0.5, 2.5}}, PlotLabel -> "Spacings\[Rule]2"]
 }
Out[175]=

ItemSize (3) 

Adjust the size of images:

In[176]:=
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
evolfunDefImgs = ResourceFunction["EvolutionViewFunction"][imgs];
Graphics[evolfunDefImgs[0.22], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}]
Out[177]=
In[178]:=
evolfunSmallImgs = ResourceFunction["EvolutionViewFunction"][imgs, ItemSize -> 0.2];
Graphics[evolfunSmallImgs[0.22], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}]
Out[179]=

The value of ItemSize is used only when the images are specified as explicit Image, Graphics, or Graphics3D objects:

In[180]:=
prims = {#, Rectangle[-0.3 {1, 1}, 0.3 {1, 1}]} & /@ {Red, Green, Blue, Cyan, Magenta, Black};
graphs = Graphics[{#, Rectangle[-0.3 {1, 1}, 0.3 {1, 1}]}] & /@ {Red, Green, Blue, Cyan, Magenta, Black};
imgs = ConstantImage[#, {1, 1}] & /@ {Red, Green, Blue, Cyan, Magenta,
     Black};
Head[imgs[[1]]]
Out[181]=
In[182]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/a1d4c70d-0652-4a4a-a828-19bcc3533875"]
Out[183]=

The same holds true for dividers:

In[184]:=
imgs = {
Image[
   NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]};
divPrims = {Black, Disk[{0, 0}, .3]};
divGraphics = Graphics[{Black, Disk[{0, 0}, .3]}];
divImage = Rasterize[Graphics[{Black, Disk[{0, 0}, .3]}]];
Head[divImage]
Out[185]=
In[186]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/489ebb5b-e05f-40b2-981a-41c420798acc"]
Out[187]=

Alignment (4) 

Specify the horizontal alignment:

In[188]:=
evolfun = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Alignment -> Left, Direction -> Left];
Framed@Graphics[{{Dashed, InfiniteLine[{0, 0}, {1, 0}], InfiniteLine[{0, 0}, {0, 1}]}, evolfun[#]}, PlotRange -> 1.5, PlotLabel -> "t = " <> ToString[#]] & /@ {0.02, 0.25, 0.48, 0.70}
Out[189]=

Specify the vertical alignment:

In[190]:=
evolfun = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Alignment -> Top, Direction -> Up];
Framed@Graphics[{{Dashed, InfiniteLine[{0, 0}, {1, 0}], InfiniteLine[{0, 0}, {0, 1}]}, evolfun[#]}, PlotRange -> 1.5, PlotLabel -> "t = " <> ToString[#]] & /@ {0.02, 0.25, 0.48, 0.70}
Out[191]=

Specify both the horizontal and vertical alignment:

In[192]:=
evolfun = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Alignment -> {Left, Top}, Direction -> 30 Degree];
Framed@Graphics[{{Dashed, InfiniteLine[{0, 0}, {1, 0}], InfiniteLine[{0, 0}, {0, 1}]}, evolfun[#]}, PlotRange -> 1.5, PlotLabel -> "t = " <> ToString[#]] & /@ {0.02, 0.25, 0.48, 0.70}
Out[193]=

Center the objects:

In[194]:=
evolfun = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Alignment -> {Center, Center}, Direction -> 30 Degree];
Framed@Graphics[{{Dashed, InfiniteLine[{0, 0}, {1, 0}], InfiniteLine[{0, 0}, {0, 1}]}, evolfun[#]}, PlotRange -> 1.5, PlotLabel -> "t = " <> ToString[#]] & /@ {0.02, 0.25, 0.48, 0.70}
Out[195]=

Direction (3) 

Specify the horizontal direction in which the sliding objects move:

In[196]:=
dirs = {Right, Left};
evolfunsDir = ResourceFunction[
     "EvolutionViewFunction"][{
Image[
      NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Direction -> #] & /@ dirs;
gr[f_, times_] := Framed@Graphics[f[#], PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}}, PlotLabel -> "t = " <> ToString[NumberForm[N@#, {3, 3}]]] & /@ times
Grid[{Style[#, 20, Bold] & /@ dirs}~Join~
  Transpose@
   MapThread[gr, {evolfunsDir, {{0.02, 0.2475}, {0.02, 0.2475}}}], Dividers -> {All, False}]
Out[197]=

Specify the vertical direction:

In[198]:=
dirs = {Up, Down};
evolfunsDir = ResourceFunction[
     "EvolutionViewFunction"][{
Image[
      NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Direction -> #] & /@ dirs;
gr[f_, times_] := Framed@Graphics[f[#], PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}}, PlotLabel -> "t = " <> ToString[NumberForm[N@#, {3, 3}]]] & /@ times
Grid[{Style[#, 20, Bold] & /@ dirs}~Join~
  Transpose@
   MapThread[gr, {evolfunsDir, {{0.02, 0.2475}, {0.02, 0.2475}}}], Dividers -> {All, False}]
Out[199]=

An arbitrary direction can be given:

In[200]:=
evolfunsDir = ResourceFunction[
   "EvolutionViewFunction"][{
Image[
    NumericArray[{{{1., 0., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 0.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{0., 1., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{{1., 0., 1.}}},"Real32"], "Real32", ColorSpace -> "RGB", Interleaving -> True], 
Image[NumericArray[{{0.}},"Real32"], "Real32", ColorSpace -> "Grayscale", Interleaving -> None]}, Direction -> 30 Degree];
Grid[Transpose@{{Style["30\[Degree]", 20, Bold]}~
    Join~(Framed@
        Graphics[evolfunsDir[#], PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}}, PlotLabel -> "t = " <> ToString[#]] & /@ {0.02, 0.248})}, Dividers -> {All, False}]
Out[201]=

Applications (3) 

Create a progress indicator:

In[202]:=
progressIndicator = ResourceFunction["EvolutionViewFunction"][
   Table[{Gray, Disk[{0, 0}, 0.5]}, 20], {"Constant", 5}, Spacings -> 1.2, Alignment -> Center, "EmergeFunction" -> (Scale[#1, #2] &), "FadeFunction" -> (Scale[#1, #2] &), Dividers -> None];
Animate[Graphics[progressIndicator[t], PlotRange -> {{-5, 5}, {-0.5, 0.5}}], {t, 0, 1}, AnimationRate -> .1]
Out[203]=

Create a graphical representation of a countdown:

In[204]:=
nums = Reverse@
   Table[Text[Style[i, 80, Bold, Black], {0, 0}], {i, 9}];
countDown = ResourceFunction["EvolutionViewFunction"][nums, "OneByOne", RotateLabel -> False];
Animate[Graphics[countDown[t]], {t, 0, 1}, AnimationRate -> 0.1]
Out[205]=

Annotate individual stages of a drawing process:

In[206]:=
times = {
Rational[1, 26], 
Rational[2, 13], 
Rational[7, 26], 
Rational[5, 13], 
Rational[1, 2], 
Rational[8, 13], 
Rational[19, 26], 
Rational[11, 13], 
Rational[25, 26]};
drawinglines = {{
Line[{{0.314, 0.547}, {0.595, 0.831}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}], 
Line[{{0.375, 0.536}, {0.364, 0.214}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}], 
Line[{{0.375, 0.536}, {0.364, 0.214}}], 
Line[{{0.383, 0.211}, {0.814, 0.214}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}], 
Line[{{0.375, 0.536}, {0.364, 0.214}}], 
Line[{{0.383, 0.211}, {0.814, 0.214}}], 
Line[{{0.825, 0.228}, {0.808, 0.528}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}], 
Line[{{0.375, 0.536}, {0.364, 0.214}}], 
Line[{{0.383, 0.211}, {0.814, 0.214}}], 
Line[{{0.825, 0.228}, {0.808, 0.528}}], 
Line[{{0.783, 0.531}, {0.395, 0.214}}]}, { Line[{{0.314, 0.547}, {0.595, 0.831}}], 
Line[{{0.606, 0.82}, {0.875, 0.517}}], 
Line[{{0.825, 0.547}, {0.358, 0.564}}], 
Line[{{0.375, 0.536}, {0.364, 0.214}}], 
Line[{{0.383, 0.211}, {0.814, 0.214}}], 
Line[{{0.825, 0.228}, {0.808, 0.528}}], 
Line[{{0.783, 0.531}, {0.395, 0.214}}], 
Line[{{0.392, 0.539}, {0.831, 0.197}}]}};
drawing[t_] := Piecewise[
  Evaluate[Prepend[
    Table[{{Thick, drawinglines[[idx]]}, t < times[[idx + 1]]}, {idx, Length[drawinglines]}], {{}, t < First[times]}]], {Thick, drawinglines[[-1]]}]
nums = Table[Text[Style[i, 50, Bold, Black], {0, 0}], {i, 8}]
Out[207]=
In[208]:=
numbering = ResourceFunction["EvolutionViewFunction"][
   nums, {"IncreaseDecrease", 2}, {{Table[1, 6]}, First[times] {1, 1},
     times}, {0.6, 1.0}, Spacings -> .2, Alignment -> Right, "NormalizeTimes" -> True, Dividers -> {Black, Thick, Arrow[0.05 {{-1, 0}, {1, 0}}]}];
Animate[Graphics[{numbering[t], drawing[t]}, PlotRange -> {{0.2, 1}, {0, 1.2}}], {t, 0, 1}, AnimationRate -> .1]
Out[209]=

Properties and Relations (1) 

Use SlideView to view each image one by one:

In[210]:=
SlideView[imgs]
Out[210]=

Possible Issues (7) 

When no explicit PlotRange for Graphics is specified, unexpected behavior occurs:

In[211]:=
imgs = {#, Disk[{0, 0}, 0.2]} & /@ {Red, Green, Blue, Cyan, Magenta, Black};
evolf = ResourceFunction["EvolutionViewFunction"][imgs];
Animate[Graphics[evolf[t]], {t, 0, 1}]
Out[212]=

Specify PlotRange explicitly:

In[213]:=
Animate[Graphics[evolf[t], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}], {t, 0, 1}]
Out[213]=

When no color setting is given, the default fade and emerge functions do not work:

In[214]:=
evolfunDefCol = ResourceFunction["EvolutionViewFunction"][
   Table[Disk[{0, 0}, 0.2], 4]];
Framed@Graphics[evolfunDefCol[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[#]] & /@ Subdivide[0, 0.03, 3]
Out[215]=

Specify color explicitly:

In[216]:=
evolFunBlack = ResourceFunction["EvolutionViewFunction"][
   Table[{Black, Disk[{0, 0}, 0.2]}, 4]];
Framed@Graphics[evolFunBlack[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[#]] & /@ Subdivide[0, 0.03, 3]
Out[217]=

When explicit timestamps are used, the option "NormalizeTimes" is ignored:

In[218]:=
imgs = {{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}};
evolfunExplicit = ResourceFunction["EvolutionViewFunction"][imgs, Automatic, {Table[1, 6], {1, 1}, {1, 2, 3, 4}}, "NormalizeTimes" -> True];
Framed@Graphics[evolfunExplicit[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[5]
Out[219]=

The time span of the latter function is 5 in this case:

In[220]:=
Framed@Graphics[evolfunExplicit[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 5, 5]
Out[220]=

Compare with the default setting:

In[221]:=
evolfunNotExpl = ResourceFunction["EvolutionViewFunction"][imgs, Automatic, {Table[1, 6], {1, 1}}, "NormalizeTimes" -> True];
Framed@Graphics[evolfunNotExpl[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[5]
Out[222]=

When the option Verbose is set to True, the output is not a function but an Association containing a parameter summary:

In[223]:=
imgs = {{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}};
out = ResourceFunction["EvolutionViewFunction"][imgs, Verbose -> False];
Head[out]
Out[224]=
In[225]:=
out = ResourceFunction["EvolutionViewFunction"][imgs, Verbose -> True];
Head[out]
Out[226]=
In[227]:=
Dataset[out]
Out[227]=

To improve formatting, some parameters in the summary Association are wrapped in HoldForm:

In[228]:=
summ = ResourceFunction["EvolutionViewFunction"][{{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}}, Verbose -> True];
durs = summ["Times", "Individual durations for mid substages"]
Out[229]=
In[230]:=
durs[[1, 2]]
Out[230]=

Use ReleaseHold to get the actual values:

In[231]:=
ReleaseHold[durs][[1, 2]]
Out[231]=

For some cases, the second argument for functions in "EmergeFunction" and "FadeFunction" should be conditioned by NumericQ:

In[232]:=
emfun1[gr_, t_] := gr /. col_?ColorQ :> Blend[{col, Blue}, t]
emfun2[gr_, t_?NumericQ] := gr /. col_?ColorQ :> Blend[{col, Blue}, t]
imgs = {{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}};
evolfunNoCond = ResourceFunction["EvolutionViewFunction"][imgs, "EmergeFunction" -> emfun1];
In[233]:=
evolfunCond = ResourceFunction["EvolutionViewFunction"][imgs, "EmergeFunction" -> emfun2];

The second argument for functions in "FadeFunction" is automatically reversed and so the same functions can be supplied to "EmergeFunction" as well as "FadeFunction":

In[234]:=
fun[gr_, t_?NumericQ] := Scale[gr, t]
imgs = {{
RGBColor[1, 0, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 1, 0], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0, 0, 1], 
Disk[{0, 0}, 0.2]}};
evolfunEmerge = ResourceFunction["EvolutionViewFunction"][imgs, "OneByOne", "EmergeFunction" -> fun, "FadeFunction" -> None];
Framed@Graphics[evolfunEmerge[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0, 0.05, 5]
Out[235]=
In[236]:=
evolfunFade = ResourceFunction["EvolutionViewFunction"][imgs, "OneByOne", "EmergeFunction" -> None, "FadeFunction" -> fun];
Framed@Graphics[evolfunFade[#], PlotRange -> {{-1.5, 0.5}, {-0.5, 0.5}}, PlotLabel -> "t = " <> ToString[N@#]] & /@ Subdivide[0.1, 0.25, 5]
Out[237]=

Neat Examples (8) 

Simple animation (4) 

Define Translate instead of fade-away-like functions for emergence and fading:

In[238]:=
translateEm[gr_, t_?NumericQ] := Translate[gr, {0, 0.5} + t {0, -0.5}]
translateFa[gr_, t_?NumericQ] := Translate[gr, BezierFunction[{{0, 0}, {1, 0}, {1, -2}}][1 - t]]

Get the time evolution as well as timing information:

In[239]:=
animation =
  ResourceFunction["EvolutionViewFunction"][
   Table[Graphics3D[{
Cube[]}, Boxed -> False, ViewProjection -> "Orthographic", SphericalRegion -> True, ViewPoint -> {3.0444, -2.4564, 1.0872}], 15], {"Increase", 4}, {{3, 1, 10, 1, 2, 1}}, {-.5, 0}, "EmergeFunction" -> translateEm, "FadeFunction" -> {translateFa, None}, Dividers -> None, Direction -> 12 Degree, Spacings -> .5, RotateLabel -> False, Alignment -> {Left, Bottom, Right}];
{mids, timestamps} =
  Values@ResourceFunction["EvolutionViewFunction"][
     Table[1, 15], {"Increase", 4}, {{3, 1, 10, 1, 2, 1}}, Verbose -> True][[
    "Times", {"Durations of mid stages", "Timestamps for mid stages"}]];

Synchronize different parts of the scene:

In[240]:=
cylfun[t_] := Inset[Graphics3D[{
EdgeForm[], 
Cylinder[{{0, 0, -1}, {0, 0, 1}}]}, Boxed -> False, ViewProjection -> "Orthographic", SphericalRegion -> True, ViewPoint -> {-1.703, -1.513, 3.361}, ViewVertical -> {-0.892, 0.446, 0.073}], {0.5, 0.5} + Piecewise[{{0, t < timestamps[[4]]}, {Sin[(2 \[Pi])/
         Last@Differences[timestamps] (t + Accumulate[mids][[-2]])], t < timestamps[[-2]]}}] ({.75, 0.39} - {0.5, 0.5}), ImageScaled[{1, 1}/2], .6]

Play the animation:

In[241]:=
Animate[Graphics[{Inset[Graphics3D[{
GrayLevel[0.5], 
EdgeForm[], 
Translate[
Cylinder[{{-0.5, 0, 0}, {0.5, 0, 0}}, 0.1], {{0, 0, 0}, {0, 3, 0}}], 
Cuboid[{-0.5, 0, -0.1}, {0.5, 3, 0.1}]}, Boxed -> False, ViewProjection -> "Orthographic", SphericalRegion -> True, ViewPoint -> {3.0444, -2.4564, 1.0872}, ViewAngle -> 0.017453292519943295`, Lighting -> "Neutral"], {0.25, -.1}, ImageScaled[{1, 1}/2], 2.8],
    cylfun[t], animation[t], Inset[Graphics3D[{
EdgeForm[], 
Cylinder[{{0, 0, -1}, {0, 0, 1}}]}, Boxed -> False, ViewProjection -> "Orthographic", SphericalRegion -> True, ViewPoint -> {3.0444, -2.4564, 1.0872}], {-0.53, 0.7448`}, ImageScaled[{1, 1}/2], 1.1]}, PlotRange -> {{-1.3, 2.5}, {-1, 1}}], {{t, 0.4}, 0, 1, Appearance -> "Labeled"}, AnimationRate -> .02]
Out[241]=

Rolling beads on custom-made lines (4) 

Specify lines (create additional nodes by click):

In[242]:=
lines = {};
initnumpts = 10;
Manipulate[
 Graphics[lines = Partition[pt, 2, 1]; Line[pt], PlotRange -> 2], {{pt, CirclePoints[1.5, initnumpts] + RandomReal[0.3 {-1, 1}, {initnumpts, 2}]}, Locator, LocatorAutoCreate -> True}]
Out[243]=

Get evolution functions:

In[244]:=
getFun[pos_, dir_, spac_] := ResourceFunction[
  "EvolutionViewFunction"][{{
RGBColor[1., 0.472465, 0.0357061], 
Disk[{0, 0}, 0.2]}, {
RGBColor[
    0.925926, 0.4378416666666667, 0.04721706666666667], 
Disk[{0, 0}, 0.2]}, {
RGBColor[
    0.8518519999999999, 0.40321833333333335`, 0.05872803333333333], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0.777778, 0.368595, 0.070239], 
Disk[{0, 0}, 0.2]}, {
RGBColor[
    0.5185186666666666, 0.24741358, 0.11052733333333334`], 
Disk[{0, 0}, 0.2]}, {
RGBColor[
    0.2592593333333333, 0.12623216, 0.15081566666666668`], 
Disk[{0, 0}, 0.2]}, {
RGBColor[0., 0.00505074, 0.191104], 
Disk[{0, 0}, 0.2]}}, {"Continue", 3}, {{1, 1, 1, 1, 1, 1}, {0.05, 0}},
   pos, "EmergeFunction" -> {Automatic, None}, "FadeFunction" -> {None, None}, Dividers -> None, Direction -> dir, Spacings -> spac/(3 - 1), Alignment -> None]
getPars[line_] := Module[{ang},
  ang = VectorAngle[{1, 0}, line[[2]] - line[[1]]];
  If[Negative@
    Last[Cross[{1, 0, 0}, Append[line[[2]] - line[[1]], 0]]], ang *= -1];
  {line[[1]], ang, Norm[line[[2]] - line[[1]]]}
  ]
funs = getFun @@ getPars[#] & /@ lines;

Get times:

In[245]:=
timestamps = ResourceFunction["EvolutionViewFunction"][
    Table[1, 6], {"Continue", 3}, {{1, 1, 1, 1, 1, 1}, {0.05, 0}}, Verbose -> True]["Times", "Timestamps for mid stages"];
times = Range[0, 2 Length[funs], timestamps[[3]]][[;; Length[funs]]];

Play the animation:

In[246]:=
globfun[t_] := Reverse@MapThread[#1[
     Piecewise[{{0, t < #2}, {Rescale[t, {#2, #3}, {0, 1}], t < #3}}, 1]] &, {funs, times, times + 1}]
Animate[Graphics[{Line[lines], globfun[t]}, PlotRange -> 2], {t, 0, Last[times] + 1}, AnimationRate -> .5]
Out[247]=

Publisher

Jaroslav Kysela

Version History

  • 1.0.0 – 22 March 2022

Related Resources

License Information