0

I have a component I created that works like a Viewstack but the next index component slides in from one of the four sides. I've got it working well enough that it's acceptable to use, but I want to make it more efficient.

Right now I'm using a Canvas as the base component, I create a snapshot of the current view using an ImageSnapshot (new Bitmap( ImageSnapshot.captureBitmapData( this ) )), and I slide the new index on top of that image on index change.

I'm basically looking for suggestions on how to do this a better way. By taking the Image after the component loads, and after the slide happens, I've gotten the initial jaded moves down to a minimum, but we normally use this for transitioning grids so it's almost always slow on the first or first couple slides.

Here's what some of it looks like so far:

private function creationComplete(e:Event):void
{
  tmpImage.source = new Bitmap( ImageSnapshot.captureBitmapData( this ) );
}

public function set selectedIndex(value:int):void
{
  if(_selectedIndex == value + 1)
    return;
  _selectedIndex = value+1;

  var obj:UIComponent;

  tmpImage.height = height;
  tmpImage.width = width;
  tmpImage.visible = true;
  tmpImage.x = 0;
  //tmpImage.includeInLayout = true;

  for (var i:int = 1; i < numChildren; i++)
  {
    obj = UIComponent(getChildAt(i));
    //obj.x = width;
    if(i == _selectedIndex){
      obj.visible = true;
      objDisplay = obj;
    }
    else
      obj.visible = false;
  }

  mv1.target = tmpImage;
  mv2.target = objDisplay;

  switch ( direction )
  {
    // X/Y sliding logic
  }
  parEfect.play();

  tmpImage.source = new Bitmap( ImageSnapshot.captureBitmapData( this ) );
}

If you're wondering, I'm using index 0 of the canvas for the image, and offset my custom selectedIndex by 1.

I'll post more of it if need be, but I want to keep the question down to a minimum and this pretty much sums it up.

Any help is greatly appreciated! I really want to get this component to perform better. Also, this has to be done using Flex 3

wajiw
  • 12,239
  • 17
  • 54
  • 73
  • 1
    Why try to re-invent the wheel? You could extend viewstack (wherein your selectedIndex would be an accurate value) and simply make your mv1 and mv2 be your showEffect and hideEffect. Here's an example (in Flex4) that adds easing functions to the Moves: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf5fdc3-7fe2.html – jeremy.mooer Nov 22 '10 at 22:26
  • This guy has a tutorial on a Swipe effect using ImageSnapshot, maybe it could be of some help: http://insideria.com/2009/12/flex-101-creating-an-swipeslid.html – Drenai Nov 23 '10 at 09:57
  • @jeremy I'm really not trying to re-invent the wheel, I just need to know what works best. I'll check out easing when I get back from my vaca. Post it as an answer if you want my points :-) @bishop I'll check that out too, thanks for the suggestion – wajiw Nov 23 '10 at 23:28
  • how are you implementing the actual animation? can you post that code here, or at least elaborate a little on that topic? – Lee Nov 28 '10 at 20:42
  • It's on the selectedIndex call. mv1 and mv2 are Move effects. Do you need the switch logic? It's just getting the math for placing the canvas outside of the visible area and moving it back. – wajiw Nov 28 '10 at 20:44

4 Answers4

2

What are mv1 and mv2? Are they Flex Effects? If so they are notoriously slow, I recommend using TweenLite. If you absolutely need to use them set suspendBackgroundProcessing = true on them. Last but not least, make sure you do not have a layout set on them. If you do you are causing a re-layout every frame which can easily bog down animation.

Greg
  • 600
  • 2
  • 5
1

You are probably getting some memory hits from all the components being created and then immediately being converted to an image. I would definitely try adding some intelligence at creation time. Try checking the memory usage and test against maximum mem load before creating the image:

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/system/System.html

However, I would need to look at what is being created in the object. I suspect that you are loading some pretty heavy objects in each of the views. And if you are loading data from the server for each object, there will be a lag, possibly.

Set up a priority queue for creating objects within the class that is being created . . . e.g., if you have a menu system that is hidden by default, load the front-end, then load the menu drop-down only when a user clicks on it, or after all other immediately visible objects have been created. You will also have the advantage of being able to take a snapshot when all the immediately visible objects are in place, and before the hidden objects are created.

Finally, add event listeners after object creation, if you can, and remember to remove listeners asap.

iND
  • 2,663
  • 1
  • 16
  • 36
  • Thanks for the suggestions, I'll check back on here after I try to do a new implementation. – wajiw Nov 23 '10 at 23:30
0

Do you use Flex 3 or Flex 4?

Because if you use Flex 4, I would recommand to use Animate Filter with Shader Filter. Shader Filters use Pixel Bender so you can build a shader in Pixel Bender that will do the transition between your 2 images.

See these 2 videos for more info :

http://tv.adobe.com/watch/codedependent/pixel-bender-shaders-and-flex-4/

http://tv.adobe.com/watch/codedependent/shader-transitions-in-flex-4

Florian F
  • 8,822
  • 4
  • 37
  • 50
0

It would be helpful to see how you're creating your Move effects, mv1 and mv2. It is possible to set combinations of the *From, *To, and/or *By attributes--or various manipulations of the properties that control the tween's speed/duration--that together can cause "jitter" or "jerkiness" in the resulting animation.

of course, it's also possible that you're hitting against a performance barrier of some sort, but I suspect it's something more insidious. Simple translation ("x/y sliding") of any clip should perform relatively well, as long as the clip hasn't been rotated, skewed, or scaled; and as long as the processor isn't completely maxed out with some other operation that's going on at the same time.

In most cases, when defining a Move effect, you want to set as little information as possible, and let Flex compute the optimum values for the other things. Usually, this means setting only xTo and yTo.

Also, be sure to call end() on your tweens before you start setting up the new values (just in case any previous sequence is still running).

Finally - make sure that you're not competing with the component's layout manager during the tween. While the tween is running, you should disable the layout completely (by setting autoLayout=false on your container component)--or you can change the layout (temporarily) to an absolute layout. Either way, the tween must be allowed to move things around while it's running, and the moving of stuff must not cause the layout manager to recompute things until after it's all over. Once it's finished, you can re-enable whatever layout manager you had originally.

Lee
  • 13,462
  • 1
  • 32
  • 45