Flex Sliding Drawer Mask and Move Effect

Published on May 2nd, 2010 by DannyT. Filed under Flex

I’ve just been trying to create a simple Sliding Drawer effect in Flex 3 and came across a load of weird and wonderful glitches that made something which should take 20 minutes leave me banging my head against the table for a couple of hours.

Here’s the end result:

This movie requires Flash Player 9

However, this is the sort of behaviour that was giving me grief:

This movie requires Flash Player 9

Nice eh? The components disappear randomly, the mask doesn’t stay still, the label isn’t viewable on the rotated button and it’s generally a bit of a pig.

Here’s the few things I learned to eliminate this glitchy behavior:

  1. In order to rotate a button, you need to embed the font.
  2. When you rotate a button the width property actually reports the height of the rotated button (which makes sense but is a bit odd at first), this also confuses any containers the button is in
  3. A mask needs to have cacheAsBitmap=true
  4. Sprite seems to be the best class to use for masks but you’ll need to add it to rawChildren when adding it to the displaylist as it isn’t a DisplayObject

Most of this is demonstrated in the source for the above:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	backgroundColor="#ffffff"
	layout="vertical" 
	creationComplete="cc()"
	>
 
	<mx:Style>
		/* need to embed font to allow rotated buttons */
		@font-face {
		    src: local("Arial");
		    fontFamily: ArialEmbedded;
		    fontWeight: normal;
		}
 
		@font-face {
		    src: local("Arial");
		    fontFamily: ArialEmbedded;
		    fontWeight: bold;
		}
 
		Button {
			font-family: ArialEmbedded;
		}
	</mx:Style>
 
	<mx:Script>
	<![CDATA[
 
		private function cc(): void
		{
			// create mask
			var drawerMask : Sprite = new  Sprite();
			drawerMask.graphics.beginFill(0xffffff);
			drawerMask.graphics.drawRect(0, 0, drawer.width + 20, 300);
			drawerMask.graphics.endFill();
			drawerMask.x = tabs.x;
			// eliminate glitchiness
			drawerMask.cacheAsBitmap = true;
			this.rawChildren.addChild(drawerMask);
			// assign mask 
			this.drawer.mask = drawerMask;
		}
 
		private function slide() : void
		{
			if(openBtn.label == "Open")
			{
				drawerPusher.width =  drawer.width + 20;
				openBtn.label = "Close";
			}
			else
			{
				drawerPusher.width = 0
				openBtn.label = "Open";
			}
		}
	]]>
</mx:Script>
	<mx:HBox width="100%" horizontalScrollPolicy="off" verticalScrollPolicy="off">
		<mx:Spacer id="drawerPusher" width="0" />
		<mx:VBox id="drawer" moveEffect="Move" backgroundColor="#cccccc">
			<mx:Label text="I'm in a drawer" />
			<mx:Button label="Button1" />
			<mx:Button label="Button2" />
			<mx:Button label="Button3" />
		</mx:VBox>
 
		<mx:Spacer id="tabSpacer" width="8" />
		<mx:HBox id="tabs" rotation="90" moveEffect="Move">
			<mx:Button id="openBtn" label="Open" click="slide()" />	
		</mx:HBox>
	</mx:HBox>
</mx:Application>

Hopefully this can save someone else the headaches I had.
Props to @andytrice for the cacheAsBitmap tip in his insideria article on masking.

One Response to “Flex Sliding Drawer Mask and Move Effect”

  1. Bill

    May 2nd, 2010 at 5:54 pm

    I did something similar with a masked sliding drawer here: http://www.billdwhite.com/wordpress/?p=44

    It uses degrafa, but the concept is the same. Hope that helps.

    Reply

Leave a Reply

About DannyT

The blog: danny-t.co.uk - General geek talk focusing on Rich Internet Applications, Microsoft and Adobe technologies and the web in general. The business: Moov2.com - RIA development agency Dan Thomas has been an Internet geek since circa 1994. He has been running Moov2 since 2003 and prior to that worked as a Flash developer for one of europes largest E-learning providers.

Copyright © 2010 Danny-T.co.uk

CSS Template By RamblingSoul | WordPress Theme by Theme Lab and Best Hosting.