One Flower, Four Flowers

In our last blog, we created a fun animation that animates a single flower. If you worked through this project, you may have thought to yourself: “All of this code for just one simple animation?” And. yes, depending on the animation, the code to animate objects for fixed layout EPub can get a little lengthy. Once you have a handy collection of handlers, however, you will find that there really is not all that much to putting a script together. Just cut and past, make a few changes, and voila! Your script is ready for testing.

When you get an animation working for a single object, you can expand your script to animate any number of objects. This was the challenge for the project: to expand the script to animate any number of flowers. You can start with a copy of the document you created for the One Flower animation.

The Document

Using layers in the document to identify the page items, simplifies this chore. Be aware, however, the leaves for the flower will need to be created in the same order as the flower parts. As long as they are created in the same order (for example: right to left), the following modification to the top of the script will animate the flowers from left to right. (Remember that stacking order places the last item created on the top of the stack, so it is the first item in the page item list.)

    To see how this works:
  • Start with your document having the single flower illustration.
  • Save the document using Save As to give it a new name.

Before you start to copy and paste the flower, you will want to remove the animation from its elements (as if you were starting with a new illustration). To remove animation from an element, the easiest way is to do this in the Animation panel (Window > Interactive > Animation). With the element selected, choose None from the animation presets list.

Removing animation using the Animation panel

    Next
  • Ungroup the blossom from the stem
  • Remove the animation from the blossom
  • Remove the animation from the leaves
  • Change the color, length of the stem, and size of the leaves as you want. Be creative.

Now regroup the blossoms and stems. Make sure you do this in the same order as the flowers were created to make sure the leaves are in the same order as the blossom groups.

Your Layers panel will now look similar to the screen capture below. Notice that all of the similar elements are named the same (all leaves are named “Leaf1”). If you are starting from a new illustration, the leaves will show up in the Layers list as <group>.

Layer structure after duplicating flower elements

Save your document.

Sample document with four flowers

The Script

Open the script you developed for the single flower animation. If you did not create the project, you can get the code from our previous blog. The top portion of the script will read as follows:

    tell application "Adobe InDesign CC 2014"
        set docRef to document 1
        set spreadRef to spread 1 of docRef
        set dTime to 2 --duration
        set doEase to no ease
        --for Leaves
        set tOffsets to {0.5, 1.0} --transform offset center bottom
        set scaleX to {{0, 100}, {47, 200}}
        set scaleY to {{0, 100}, {47, 200}}
        set opacArray to {{0, 0}, {47, 100}}
        tell docRef
            set leafElement to group 1 of layer "Leaves" 
            set name of leafElement to "Leaf1"
            my growAnimate(leafElement, dTime, tOffsets, opacArray, scaleX, scaleY, doEase)   
          --for Blossom and Stem group
          set groupRef to group 1 of layer "Flowers"
          set name of groupRef to "Group1"
          set flowerElement to group 1 of group "Group1" --note this will change depending on the page item used
          set name of flowerElement to "Flower1"
          set stemElement to rectangle 1 of group "Group1"
          set name of stemElement to "Stem1"
          set scaleX to {{0, 100}, {47, 110}}
          set scaleY to {{0, 100}, {47, 100}}
          set tOffsets to {0.5, 0.5} --transform offset center
          set mPath to {{0, {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}}, {47, {{1.0, -233.0}, {1.0, -233.0}, {1.0, -233.0}}}}
          my growPath(groupRef, dTime, tOffsets, opacArray, mPath, scaleX, scaleY, doEase)
          --for Blossom
          set scaleX to {{0, 15}, {47, 100}}
          set scaleY to {{0, 15}, {47, 100}}
          set tOffsets to {0.5, 0.5} --center   
          set objRef to page item "Flower1" of group "Group1" 
          my growAnimate(objRef, dTime, tOffsets, opacArray, scaleX, scaleY, doEase)
      end tell
      my createTimingGroups(spreadRef)
    end tell

Copy this code to the top of a new script. Then add the two handlers growPath and growAnimate. There will not be any changes made to these handlers, so you can copy and paste them at the bottom of your new script as is.

Lastly, you will need the createTimingGroups handler.There will be changes made to this handler, so its code is listed below:

    --Create Timing Groups
    on createTimingGroups(spreadRef)
        tell application "Adobe InDesign CC 2014"
            set spreadRef to spread 1 of document 1
            tell timing settings of spreadRef
                delete timing lists
                set tList to make timing list with properties {trigger event:on page click}
            end tell
            tell tList
                set g1 to make timing group with properties {dynamic target:group "Group1" of spreadRef, delay seconds:0.0}
                tell g1
                    make timing target with properties {dynamic target:page item "Leaf1" of spreadRef, delay seconds:0.0}
                    make timing target with properties {dynamic target:group "Flower1" of group "Group1" of spreadRef, delay seconds:0.5}
                end tell
            end tell
        end tell
    end createTimingGroups

Modifying the Script

Now that you have all of the pieces in place, changing the script from animating only one flower, to animating any number of flowers in your document is just a simple matter of adding a few repeats.

  • First, get a count of the elements in the layer
  • Next repeat with a counting variable (i) from 1 to the count of elements
  • Within the repeat loop, change the names of the elements using the value of the counting variable as in (“Leaf” & i)

The following details the steps for each part of the flower

Leaf portion

For the part of the script that animates the leaves the section can read as follows:

   --after tell docRef
    set groupCount to count of groups of layer "Leaves"
    repeat with i from 1 to groupCount
        set leafElement to group i of layer "Leaves"
        set name of leafElement to ("Leaf" & i)
        my growAnimate(leafElement, dTime, tOffsets, opacArray, scaleX, scaleY, doEase)
    end repeat 

Flower Group

It gets a little trickier when it comes to the groups on the “Flowers” layer. Each flower is a group that contains a single blossom and stem element. The script needs to rename this group and one of its child elements, the blossom. It can refer to the parent group (blossom and stem group) as group i of layer “Flowers”, but after naming this group to {“Group” & i) it will need to refer to the blossom as an element of the group, not the layer:

    group 1 of group ("Group" & i). 

The following is how this section can be rewritten.

    --for Blossom and Stem group
	set scaleX to {{0, 100}, {47, 110}}
	set scaleY to {{0, 100}, {47, 100}}
	set tOffsets to {0.5, 0.5} --transform offset center
	set mPath to {{0, {{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}}, {47, {{1.0, -233.0}, {1.0, -233.0}, {1.0, -233.0}}}}
        set groupCount to count of groups of layer "Flowers"
	repeat with i from 1 to groupCount
	    set groupRef to group i of layer "Flowers"
	    set name of groupRef to ("Group" & i)
            set flowerElement to group 1 of group ("Group" & i) --note this will change depending on the page item used
	    set name of flowerElement to ("Flower" & i)
	    set stemElement to rectangle 1 of group ("Group" & i)
	    set name of stemElement to ("Stem" & i)
	    my growPath(groupRef, dTime, tOffsets, opacArray, mPath, scaleX, scaleY, doEase)
	end repeat

Notice that setting the values for the flower group’s animation settings was moved as these values do not change within the repeat.

Blossom

You should be able to change the blossom portion of the top part of the script on your own, but just in case you are struggling, the code is listed below.

        --for Blossom
	set scaleX to {{0, 15}, {47, 100}}
	set scaleY to {{0, 15}, {47, 100}}
	set tOffsets to {0.5, 0.5} --center  
	repeat with i from 1 to groupCount
	    set objRef to page item ("Flower" & i) of group ("Group" & i)
	    my growAnimate(objRef, dTime, tOffsets, opacArray, scaleX, scaleY, doEase)
	end repeat

Now, all you need to change is the createTimingGroups handler and its call. Because the script named the elements to be animated using an incremented naming convention, doing this becomes a piece of cake.

First you need to pass the number of group elements to be animated to the createTimingGroups handler. This was defined in the variable groupCount. You will add this variable to the call to the handler as well as to the handler’s argument list:

    --For the handler call:
    my createTimingGroups(spreadRef, groupCount)
    --In the handler argument list:
    on createTimingGroups(spreadRef, groupCount)

Next, change the code inside the tell tList block in the handler to read as follows:

    tell tList
	repeat with i from 1 to groupCount
            set tGroup to make timing group with properties {dynamic target:group ("Group" & i) of spreadRef, delay seconds:0.0}
	    tell tGroup
		make timing target with properties {dynamic target:page item ("Leaf" & i) of spreadRef, delay seconds:0.0}
		make timing target with properties {dynamic target:group ("Flower" & i) of group ("Group" & i) of spreadRef, delay seconds:0.5}
	    end tell
	end repeat
    end tell

That’s it! And, you thought that it was going to be difficult.

Watch the Flowers Grow

Compile your script to make sure you haven’t forgotten something. Then, run it. Preview the animation in InDesign’s EPUB Interactivity panel. The flowers should animate in the order that you placed them on the page. Export the page to Epub (Fixed Layout) and view the animation in iBooks and/or Adobe Digital Editions. 

If you want to change the order in which the flowers animate, you can change the repeat loop in the createTimingGroups handler to read something like the following:

    --after tell tList
    set repeatList to {2, 1, 4, 3} --change the order you want here
    repeat with eachItem in repeatList
        set i to eachItem
       --all the rest of the code is the same

I hope this convinces you that once you have a number of handlers in place, using a script to create your InDesign EPub fixed layout animations is the only way to go. This is especially true when you start having a number of items to animate.

Challenge

Get creative! Think of other applications for using the growAnimate and growPath handlers? Here are some ideas:

  • Use a rectangle filled with the same color as the page background to gradually hide or reveal an image or illustration.
  • Change the size of an object as it moves to make it appear as if it is going away or coming closer
  • Animate the bars in a bar chart
  • Gradually change the size of a headline