Flex 4 - Jerky animation issue - apache-flex

I have created my first animation effect in flex 4. Its a very simple animation within my custom component which moves a label component left to right to left 3-5 times and then fades out gradually.
Every thing works fine but the problem is that when I run the animation first time, it plays jerky animation and perfect smoother after wards. I dont know why.
Can some one tell whats wrong with this?
This is the full source code of my custom component. After adding it to the stage, calling the showProgressEffect() will play the animation.
Notice that I have made the label "cacheAsBitmap" to avoid flickers while moving the label and call to stop() before play() methods of each of the animations/effects.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="274" height="72"
click="onClick()" xmlns:components="ui.hud.components.*" cacheAsBitmap="true">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:Sequence id="tween" repeatCount="5" effectEnd="onEffectEnd()" >
<s:Move xBy="20" duration="500" />
<s:Move xBy="-20" duration="500" xFrom="50"/>
</s:Sequence>
<s:Fade id="fadeEffect" alphaTo="0" duration="2000" />
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var questId:int;
[Bindable]
public var questTitle:String;
[Bindable]
public var iconUrl:String;
private function onClick():void{
Globals.questCtr.showQuest(questId);
}
private function onEffectEnd():void{
fadeEffect.stop();
fadeEffect.play([lblStatus]);
}
public function showProgressEffect():void{
tween.stop();
lblStatus.alpha = 1;
tween.play([lblStatus]);
}
]]>
</fx:Script>
<mx:Image source="{iconUrl}" width="75" height="75"/>
<s:Group x="77" y="24" width="197">
<s:Label id="lblStatus" text="Task Complete" fontWeight="bold" fontSize="25" alpha="0" cacheAsBitmap="true" hideEffect="" mouseEnabled="false"/>
</s:Group>
</s:Group>

This happens because before animation start your label is in different position, than after it. I don't know what exactly you trying to achieve, but there are two choices:
You can change xFrom="50" to xFrom="20"in second move effect;
You can change lblStatus x coordinate to 30;

Related

How to change labels in a ButtonBar - simple test case and screenshot attached

In a Flex Mobile app I would like to have a ButtonBar at the bottom and I need to change the labels of its buttons:
(I don't want to use TabbedViewNavigatorApplication here, because all my logic is in a single View with an ActionBar at its top and ButtonBar at its bottom).
So I have prepared a very simple test case to demonstrate my problem.
Please just create a "blank" Flex mobile project in Flash Builder and put my 2 files (below) into it and you will see my problem - touching the buttons at the bottom doesn't change the label of the very right button).
TestAC.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationDPI="160">
<fx:Script>
<![CDATA[
import spark.events.IndexChangeEvent;
import spark.skins.mobile.TabbedViewNavigatorTabBarSkin;
private function handleTabs(event:IndexChangeEvent):void {
trace(_tabBar.selectedIndex);
_tabs[2].label = String(1 + _tabBar.selectedIndex);
}
]]>
</fx:Script>
<fx:Declarations>
<s:MultiDPIBitmapSource id="CHAT"
source160dpi="#Embed('chat.png')"
source240dpi="#Embed('chat.png')"
source320dpi="#Embed('chat.png')" />
<s:ArrayCollection id="_tabs">
<fx:Object label="One" />
<fx:Object label="Two" />
<fx:Object label="Three" icon="{CHAT}" />
</s:ArrayCollection>
</fx:Declarations>
<s:ButtonBar id="_tabBar"
requireSelection="true"
width="100%"
bottom="0"
skinClass="spark.skins.mobile.TabbedViewNavigatorTabBarSkin"
dataProvider="{_tabs}"
change="handleTabs(event)">
</s:ButtonBar>
</s:Application>
chat.png:
Allright, adding _tabs.refresh(); to handleTabs has helped.

Spark Tile layout - get renderer from point

is there an built in method in spark tile list to get an item from a given point?
Thanks
As #www.Flextras.com suggested, looking at the source code can be useful. TileLayout has a method named getElementNearestScrollPosition() that will give you the index of the element that is located closest to a Point that you specify. This method is hidden in Flex's mx_internal namespace, however, so it gets excluded from the ASDocs.
Here's a simple example that seems to be working. I'm not showing the itemRenderer.
Main.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.core.mx_internal;
use namespace mx_internal;
protected function list1_clickHandler(event:MouseEvent):void
{
var localPointInList:Point = list.globalToLocal(new Point(event.stageX, event.stageY));
trace(tileLayout.getElementNearestScrollPosition(localPointInList));
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="foo">
<fx:Object date="Jan 1, 2012"/>
<fx:Object date="Jan 1, 2013"/>
<fx:Object date="Jan 1, 2014"/>
</s:ArrayCollection>
</fx:Declarations>
<s:layout>
<s:HorizontalLayout />
</s:layout>
<s:Button label="I'm a button"/>
<s:List id="list" dataProvider="{foo}" itemRenderer="TestRenderer" click="list1_clickHandler(event)">
<s:layout>
<s:TileLayout id="tileLayout" requestedColumnCount="2" />
</s:layout>
</s:List>
</s:Application>
Note that I'm doing some conversion between local and global coordinates. You need to do this convert the global coordinates in the MouseEvent to the coordinate space of the List. I've also added a Button to the main app, solely to test this conversion ... the presence of the button makes it so the list's local coordinates do not match the global coordinates. If the list was placed at the origin (0,0) this conversion between coordinate spaces would not be necessary ... but that rarely happens in real world apps.

View transition at animation end

Here's the deal:
I have an image and a button on my mobile app's homeview.
I apply an animation to the image by pressing the button. That works great.
PROBLEM:
I want to add a view transition that pushes to the next view after the animation completes.
CODE:
AS:
protected function nextView()
{
navigator.pushView(View2);
}
MXML:
<s:Button id="Button" click="anim.play()"/> //anim.play() is in
//the declarations tag and is working as expected.
<s:Image id="img" source="#Embed('assets/image.png')"/>
I've Tried:
-Adding nextView() to the click method after the animation call
-Using effectEnd="nextView()" in Button properties
Thank you for any help and insight you can provide.
effectEnd appears to work for me:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<s:Move id="myEffect" xBy="100" target="{btn}" effectEnd="navigator.pushView(NextView)" />
</fx:Declarations>
<s:ViewNavigator id="navigator" width="100%" height="100%"/>
<s:Button id="btn" label="play" click="myEffect.play()" />
</s:Application>

Is there a Flex 4 Pause effect?

Is there a Flex 4 Spark version of the Pause effect?
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/effects/Pause.html
In a Sequence this effect pauses for a specific duration of time before going to the next effect. It also can pause until a specific event is dispatched on a target.
#Shaun,
I see. What threw me off was the mx.effects package it's part of and this comment in the TweenEffect class which Pause extends.
/**
* TweenEffect is the superclass for the animated effects in Flex 3. As of Flex 4, the
* Spark effects extend the spark.effects.Animate class instead of TweenEffect.
*/
[Alternative(replacement="spark.effects.Animate", since="4.0")]
Thank you!
It says here although it's not advised (likely due to the changes in the architecture to separate the layout and scroll bar etc.)
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf5fdc3-7fff.html
I would guess a Pause effect would work fine... actually tried it out it shows up in Spark in the 4.5 SDK
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
bc.visible=true;
}
protected function button2_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
bc.visible=false;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:Sequence id="sq">
<s:Rotate angleBy="45" autoCenterTransform="true"/>
<s:Pause duration="1000"/>
<s:Rotate angleBy="45" autoCenterTransform="true"/>
</s:Sequence>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:BorderContainer id="bc" width="100" height="100" backgroundColor="blue" visible="false" showEffect="sq"/>
<s:Button click="button1_clickHandler(event)" label="show"/>
<s:Button click="button2_clickHandler(event)" label="hide"/>
</s:View>
Note this is a mobile application hence the s:View.

Wrong target when clicking on a <s:Group> with a Mask in Flex 4

I am having trouble handling a MouseEvent.MOUSE_DOWN on an component with a Image for a mask in Flex 4.
I have an application as follows:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()"
>
<fx:Script>
<![CDATA[
import spark.core.MaskType;
public function init():void {
manager.addEventListener( MouseEvent.MOUSE_DOWN, handleMouseDown );
}
public function handleMouseDown(e:MouseEvent):void {
trace( e.target )
}
]]>
</fx:Script>
<s:Group id="manager" width="500" height="500">
<s:Group id="layer" mouseChildren="false" x="220">
<s:Group id="content" maskType="{MaskType.ALPHA}" cacheAsBitmap="true">
<s:Rect width="338" height="162">
<s:fill>
<s:SolidColor color="0xDDAAAA" />
</s:fill>
</s:Rect>
<s:mask>
<s:Group>
<mx:Image
source="http://www.wpclipart.com/signs_symbol/alphabets_numbers/3D_text_T.png"
cacheAsBitmap="true"
/>
</s:Group>
</s:mask>
</s:Group>
</s:Group>
</s:Group>
</s:Application>
If you run this, you will notice that if you click on the left side of the image (on the "3"), the trace correctly indicates that "layer" got clicked. However, if you click on the right side of the image (on the "D") you'll see that "manager" got clicked instead of "layer", which is wrong. If you click anywhere on the "layer" that is past 338px (the mask size), the mouse event does not seem to make it to the layer object.
If I remove the "x" offset on "layer", the whole layer works as expected, but as soon as I offset, anything past the width of the mask (338px) seems to not be captured properly, like if the mask wasn't offset. The strange thing is that if you click to the left of the image once it has been offset, you do get "manager", which means that the layer (and mask) did get moved.
Here's what I mean, with no offset, clicking on the green area returns "layer", clicking on the blue area returns "manager", which is the expected behaviour. See image
If I offset the layer by 220, the areas behave like this image
Sorry I can't embed the images here, but I don't have enough reputation :(
Figured it out.
Apparently the problem is that the Image that is used as the mask needs to be added to the display list before it gets set as the mask or this erratic behaviour happens. This is what the code looks like now and it's working:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()"
>
<fx:Script>
<![CDATA[
import spark.core.MaskType;
public function init():void {
manager.addEventListener( MouseEvent.MOUSE_DOWN, handleMouseDown );
}
public function handleMouseDown(e:MouseEvent):void {
trace( e.target.id )
}
]]>
</fx:Script>
<s:Group id="manager" width="500" height="500">
<s:Group id="layer" mouseChildren="false" x="100" mouseEnabledWhereTransparent="false">
<s:Group id="content" mask="{maskImage}" maskType="{MaskType.ALPHA}" cacheAsBitmap="true">
<s:Rect width="338" height="162">
<s:fill>
<s:SolidColor color="0xDDAAAA" />
</s:fill>
</s:Rect>
</s:Group>
<mx:Image id="maskImage"
source="http://www.wpclipart.com/signs_symbol/alphabets_numbers/3D_text_T.png"
cacheAsBitmap="true"
/>
</s:Group>
</s:Group>
</s:Application>
Also of note is that the maskImage is a child of layer and not a child of content. Setting it as a child of the latter results in the same incorrect behaviour as before.

Resources