+1
Answered

Timed Actions

dbdesign 12 years ago updated by ajones 12 years ago 6
I am trying to make an animation to play at the launch of the app. I have two images (launchiphone-00000.png and launchiphone-00001.png) that I want to play using an "imagestrip." I have the "imagestrip" and the "playstrip" in place. I want the action to play the animation for 5 seconds.

So I have two problems:
1. My imagestrip images are not showing.
2. How do I make the action run for 5sec before fading to alpha="0"?


<panel name="launchcontainer" alias="LAUNCHCONTAINER" height="100%" width="100%" xpos="0" ypos="0" background="#a58d3c" alpha="1">
<platform device="iPhone"><imagestrip name="launchgraphic" alias="LAUNCHGRAPHIC" prefix="images/launchiphone-" fps="25"></imagestrip></platform>
<platform device="iPad"><imagestrip name="launchgraphic" alias="LAUNCHGRAPHIC" prefix="images/launchipad-" fps="25"></imagestrip></platform>
</panel>

<action name="launchgraphic" oninit="yes">
<playstrip target="LAUNCHGRAPHIC" loops="yes" time="5"/>
</action>

Answer

Answer
Answered
While image strip is a method provided within iOS to allow for burst of animated content, the conversion within iOS from image to sequenced video can be a little cumbersome and does not carry the best performance effort within iOS.

One trick I like to use within Wire when I need to animatie a sequence of images is a combination of load, conditional statements and an action that loops over itself to give me optimal control of my sequence.

First the finish action blocks of code we'll be using:



<main>
<image name="AnimatedSeq" alias="ANIMATED-SEQ" />
</main>

<action oninit="yes">
<assign property="var:frameCount" value="0" />
</action>

<action name="loop">
<if lhs="[var:frameCount]" operator="lte" rhs="26">
<sync delay="0">
<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>
<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />
<if lhs="[var:frameCount]" operator="lt" rhs="26">
<play action="loop"/>
</if>
<if lhs="[var:frameCount]" operator="=" rhs="26">
<alert message="I'm Done" />
</if>
</sync>
</if>
</action>


First let's look at the image we will be replacing in the sequence.


<image name="AnimatedSeq" alias="ANIMATED-SEQ" />


Nothing fancy here, we simply just place the first image in the sequence that we want the user to see.

Next we want to create a var that we can use to track the sequence and to use in showing the appropriate image. So we have a simple oninit action that sets the var:frameCount to 0 upon loading the app.

<assign property="var:frameCount" value="0" />

This var shows that we want to make sure that our images are sequenced and named appropriately. So instead of the image strip requirement of a prefix and 4 digit number, we can simplify this. We CAN optionally add a prefix, but it's not required, here I used 'mySeq' then just start you numbering at 0.

mySeq0.jpg, mySeq1.jpg mySeq2.jpg, mySeq3.jpg, etc...

In my example above you will see the number '26' in a few places, this is the total images my sequence requires.

Let's take a look at the action 'loop'.

I have a conditional statement that leads off the action and checks the var:frameCount value.

<if lhs="[var:frameCount]" operator="lte" rhs="26">

This will make sure that once we kick off this action to animate our sequence that we are within the bounds of our sequence numbering and then using that var: perform a load action on the source of the image.

<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>

Here, since we are starting the animation we will see mySeq0.jpg first be placed in the load. Then immediately following the load (remember we are in a sync) we increment the var:frameCount with an eval: statement:

<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />

Now we will create two sibling conditional statement to fork the action and decide if we are done with the animation or need to loop the action over itself and continue incrementing the sequence until we hit 26.

<if lhs="[var:frameCount]" operator="lt" rhs="26">

The first conditional checks to see if our var:frameCount is less than our last slide, 26. If so, we ask the action to start again. And in doing so the action will now go and load slide mySeq1.jpg and increment the var:frameCount to 2 and continue this pattern until it hits our other conditional statement:

<if lhs="[var:frameCount]" operator="=" rhs="26">

Once the var:frameCount hits our ceiling in the sequence, I have placed an alert to just verify the sequence has completed.

While this may initial seem like a complex solution to a control iOS provides, the control and sequencing makes the implementation very repeatable and reliable without losing performance on the device. This also gives a very nice introduction into the power of looped actions and conditional statements.

Please let me know if you have any questions.
Answer
Answered
While image strip is a method provided within iOS to allow for burst of animated content, the conversion within iOS from image to sequenced video can be a little cumbersome and does not carry the best performance effort within iOS.

One trick I like to use within Wire when I need to animatie a sequence of images is a combination of load, conditional statements and an action that loops over itself to give me optimal control of my sequence.

First the finish action blocks of code we'll be using:



<main>
<image name="AnimatedSeq" alias="ANIMATED-SEQ" />
</main>

<action oninit="yes">
<assign property="var:frameCount" value="0" />
</action>

<action name="loop">
<if lhs="[var:frameCount]" operator="lte" rhs="26">
<sync delay="0">
<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>
<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />
<if lhs="[var:frameCount]" operator="lt" rhs="26">
<play action="loop"/>
</if>
<if lhs="[var:frameCount]" operator="=" rhs="26">
<alert message="I'm Done" />
</if>
</sync>
</if>
</action>


First let's look at the image we will be replacing in the sequence.


<image name="AnimatedSeq" alias="ANIMATED-SEQ" />


Nothing fancy here, we simply just place the first image in the sequence that we want the user to see.

Next we want to create a var that we can use to track the sequence and to use in showing the appropriate image. So we have a simple oninit action that sets the var:frameCount to 0 upon loading the app.

<assign property="var:frameCount" value="0" />

This var shows that we want to make sure that our images are sequenced and named appropriately. So instead of the image strip requirement of a prefix and 4 digit number, we can simplify this. We CAN optionally add a prefix, but it's not required, here I used 'mySeq' then just start you numbering at 0.

mySeq0.jpg, mySeq1.jpg mySeq2.jpg, mySeq3.jpg, etc...

In my example above you will see the number '26' in a few places, this is the total images my sequence requires.

Let's take a look at the action 'loop'.

I have a conditional statement that leads off the action and checks the var:frameCount value.

<if lhs="[var:frameCount]" operator="lte" rhs="26">

This will make sure that once we kick off this action to animate our sequence that we are within the bounds of our sequence numbering and then using that var: perform a load action on the source of the image.

<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>

Here, since we are starting the animation we will see mySeq0.jpg first be placed in the load. Then immediately following the load (remember we are in a sync) we increment the var:frameCount with an eval: statement:

<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />

Now we will create two sibling conditional statement to fork the action and decide if we are done with the animation or need to loop the action over itself and continue incrementing the sequence until we hit 26.

<if lhs="[var:frameCount]" operator="lt" rhs="26">

The first conditional checks to see if our var:frameCount is less than our last slide, 26. If so, we ask the action to start again. And in doing so the action will now go and load slide mySeq1.jpg and increment the var:frameCount to 2 and continue this pattern until it hits our other conditional statement:

<if lhs="[var:frameCount]" operator="=" rhs="26">

Once the var:frameCount hits our ceiling in the sequence, I have placed an alert to just verify the sequence has completed.

While this may initial seem like a complex solution to a control iOS provides, the control and sequencing makes the implementation very repeatable and reliable without losing performance on the device. This also gives a very nice introduction into the power of looped actions and conditional statements.

Please let me know if you have any questions.
Looking at your example, you have 2 imagestrips defined with the same Alias. Alias must be unique globally, so this might be why you are not seeing the images.

You only seem to have images for iphone stored in your wire, so I would not count on your ipad images working until you have created image files for them.

Your prefix value should not contain the "images/" path. That being said, there is a chance that imagestrip images need to be stored at the root of the project. I will confirm this.

The "time" attribute is not available on the playstrip action at this time, but it can be used on the sync action. I would make your wire like this:


<panel name="launchcontainer" alias="LAUNCHCONTAINER" height="100%" width="100%" background="#a58d3c" alpha="1">
<platform device="iPhone"><imagestrip name="launchgraphic" alias="LAUNCHGRAPHIC" prefix="launchiphone-" fps="25"></imagestrip></platform>
</panel>

<action name="launchgraphic" oninit="yes">
<playstrip target="LAUNCHGRAPHIC" loops="yes"/>
<sync delay="5">
<alpha value="1" time="0" target="LAUNCHGRAPHIC" />
</sync>
</action>
The "sync" action worked great! It did exactly what I needed. I'm still not seeing my imagestrip images. I moved the images to the root folder as well. Here is my new code:


<panel name="launchcontainer" alias="LAUNCHCONTAINER" height="100%" width="100%" xpos="0" ypos="0" background="#000000" alpha="1">
<panel name="sponsor" height="100%" width="100%" xpos="0" ypos="0">
<image name="sponsorlogo" source="images/sponsorlogo.png" align="center" valign="center"></image>
</panel>
<imagestrip name="launchgraphic" alias="LAUNCHGRAPHIC" prefix="launchiphone-" fps="25"></imagestrip>
</panel>

<action name="launchgraphic" oninit="yes">
<playstrip target="LAUNCHGRAPHIC" loops="yes" />
<sync delay="5">
<alpha value="0" time=".5" target="LAUNCHGRAPHIC" />
</sync>
<sync delay="7">
<alpha value="0" time=".5" target="LAUNCHCONTAINER" />
</sync>
</action>
Let me run some tests and I will get back to you. Imagestrip isn't widely used, so I want to make sure it doesn't have a bug.
While image strip is a method provided within iOS to allow for burst of animated content, the conversion within iOS from image to sequenced video can be a little cumbersome and does not carry the best performance effort within iOS.

One trick I like to use within Wire when I need to animatie a sequence of images is a combination of load, conditional statements and an action that loops over itself to give me optimal control of my sequence.

First the finish action blocks of code we'll be using:



<main>
<image name="AnimatedSeq" alias="ANIMATED-SEQ" />
</main>

<action oninit="yes">
<assign property="var:frameCount" value="0" />
</action>

<action name="loop">
<if lhs="[var:frameCount]" operator="lte" rhs="26">
<sync delay="0">
<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>
<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />
<if lhs="[var:frameCount]" operator="lt" rhs="26">
<play action="loop"/>
</if>
<if lhs="[var:frameCount]" operator="=" rhs="26">
<alert message="I'm Done" />
</if>
</sync>
</if>
</action>


First let's look at the image we will be replacing in the sequence.


<image name="AnimatedSeq" alias="ANIMATED-SEQ" />


Nothing fancy here, we simply just place the first image in the sequence that we want the user to see.

Next we want to create a var that we can use to track the sequence and to use in showing the appropriate image. So we have a simple oninit action that sets the var:frameCount to 0 upon loading the app.

<assign property="var:frameCount" value="0" />

This var shows that we want to make sure that our images are sequenced and named appropriately. So instead of the image strip requirement of a prefix and 4 digit number, we can simplify this. We CAN optionally add a prefix, but it's not required, here I used 'mySeq' then just start you numbering at 0.

mySeq0.jpg, mySeq1.jpg mySeq2.jpg, mySeq3.jpg, etc...

In my example above you will see the number '26' in a few places, this is the total images my sequence requires.

Let's take a look at the action 'loop'.

I have a conditional statement that leads off the action and checks the var:frameCount value.

<if lhs="[var:frameCount]" operator="lte" rhs="26">

This will make sure that once we kick off this action to animate our sequence that we are within the bounds of our sequence numbering and then using that var: perform a load action on the source of the image.

<load source="graphics/mySeq[var:frameCount].jpg" target="ANIMATED-SEQ"/>

Here, since we are starting the animation we will see mySeq0.jpg first be placed in the load. Then immediately following the load (remember we are in a sync) we increment the var:frameCount with an eval: statement:

<assign property="var:frameCount" value="[eval: [var:frameCount] + 1]" />

Now we will create two sibling conditional statement to fork the action and decide if we are done with the animation or need to loop the action over itself and continue incrementing the sequence until we hit 26.

<if lhs="[var:frameCount]" operator="lt" rhs="26">

The first conditional checks to see if our var:frameCount is less than our last slide, 26. If so, we ask the action to start again. And in doing so the action will now go and load slide mySeq1.jpg and increment the var:frameCount to 2 and continue this pattern until it hits our other conditional statement:

<if lhs="[var:frameCount]" operator="=" rhs="26">

Once the var:frameCount hits our ceiling in the sequence, I have placed an alert to just verify the sequence has completed.

While this may initial seem like a complex solution to a control iOS provides, the control and sequencing makes the implementation very repeatable and reliable without losing performance on the device. This also gives a very nice introduction into the power of looped actions and conditional statements.

Please let me know if you have any questions.
This all makes great sense. Thank you for all the help. I have started to try to implement this but so far it is crashing fusebox every time. I'll keep working with it and see if I can't figure something out.
Remember that this example above might not be precisely copy and paste, you will have to add your own names and assets. If you are still having problems getting it to work, you can email me at community@rarewire.com.

Thanks