Flex Move Effect Messes Up Mask Alignment

In creating some custom components in Flex 3 last week, I battled off and on all week with a bloody Move effect.  It kept screwing up the mask I used.  Basically, it’s a timeline that shows 24 hours in a horizontal timeline.  The parent masks 6 hours off.  When a new date is set, it zooms to show that span of time in the 24 hour range.  The “zoom to” is a Move effect applied to the child component.

The parent utilizes a mask so that the 4000 pixel timeline is shown zooming in a 700 pixel area.  Works great… sometimes.  I keep getting random results.  It all comes down to the fact that things like “masks” are extremely low-level, at least as far as the Flex SDK is concerned.  Unlike other Flash tweening engines such as TweenLite, the Flex 2 & 3 ones must contend with a significant amount of information about the objects they are tweening.  For example, you can’t just move a UIComponent across the screen and think everything is ok.  There are a multitude of things you need to do and handle.

You can attempt to temporarily cache the object in question as a bitmap to speed up the animation.  You must make the decision whether the parent should clip the content you are moving.  You need to reset the CSS margins to 0 and horizontal & vertical centering of the component to ensure it, and its parent, doesn’t unnecessarily redraw.  You may need to force clipping on the parent if you go beyond its boundary’s.  You need to ignore other move events, handle redraw events that could interupt the tween, and finally reset everything when you’re done as best you can.

If you’ve ever looked at the life cycle of a Flex component, it’s actually pretty simple to build upon, but quite complex to really understand all that goes on under the hood from a redraw perspective.  The multitude of redraw events, classes involved, and internal properties that super-cede built in ones (clipping content vs. mask/scrollRect and cacheAsBitmap for example) makes it extremely complicated to debug when you are doing low-level stuff that may not play nice in the Flex sandbox.  What works perfectly in a vanilla, Flash / pure AS3 environment could fail in a Flex one.  You just need to understand the Flex SDK.

I clearly don’t; my mask keeps screwing up.  If I turn it off, everything worked fine.  Every time the Move effect was done, the mask would be slightly off target.  After digging in the effect code, the only thing I can gather is that multiple calls to having the parent of the tweened component reset its scrollRect value somehow misaligned mask… or perhaps that in combination with a caching, and then subsequent un-caching, as bitmap.  Even though I’m compiling for Flash Player 9, I believe they upped the cacheAsBitmap limit from 2880×2880 pixels to over 9000 or something.  So, maybe it is in fact succeeding and thus this is what’s screwing up my mask.

Not sure, at this point and don’t care.  Solution?  When the tween is done, reset your mask.  If you’re paranoid, set it in invalidateDisplaylist although that’s pretty heavy handed… but hey, I can guarantee it works! 

6 Replies to “Flex Move Effect Messes Up Mask Alignment”

  1. Yep, Jesse you’re right. Adobe dropped the ball on masks in Flash 9 (mac version) and those bugs are now features in Flash 10. Basically it first showed up when building dynamic masks for me, and using stacked masks. One solution is to change the cacheAsBitmap on children (usually i set it to off in general, but it’s a weird combination that causes the bug to show up). Try not using cacheAsBitmap on the mask.

  2. I did some more investigation as the problem popped up again, and it’s attempting to set cacheAsBitmap to true inside the framework itself. Merely resetting the mask in actuality didn’t help. So, I ended up overriding UIComponent’s cacheAsBitmap setter to force it to be always false. That seemed to do the trick.

  3. I came across a similar problem myself when for some reason ivoking cacheAsBitmap on flexlibs DragScrollingCanvas (somebody else must have checked that code in…). Everything was hunky dory on a PC but on Mac the whole view got corrupted after the user had scrolled around for a bit.

    As it happens I was also working on an implementation of a timeline.

  4. Also, did you try UIComponent.cachePolicy = UIComponentCachePolicy.OFF since default is
    UIComponentCachePolicy.AUTO which basically means that the FlashPlayer will heuristically try and figure out whether you usually cacheAsBitmap. From what I can see in Flex 3, this may be what resulted in the default to cache = true in your case.

Comments are closed.