Horizontal Scaled Canvas
Let’s say you have a Canvas containing several UI components. Depending on the screen size, some may be too large to display inside the canvas causing scroll bars to appear. Instead of having the user see scroll bars or a cropped version of your UI components, you can scale them so they fit perfectly. Here’s how I solved this problem.
At first I searched the web for someone who already came up with a solution. I came across a Scalable Canvas on Adobe’s Flex Cookbook site, but it didn’t handle my situation. I didn’t want to set the height of my Canvas but instead wanted to allow the height to stay dynamic based on the canvas contents. The width however I needed to be 100% of the parent container. When I tried this with the cookbook example it refused to return to the original scale after I resized my window a few times.
Using the ScaledCanvas as a starting point I developed what I call the HScaledCanvas. It only takes into account the horizontal width of child UI components in determining the appropriate scale. Rather than scale the entire canvas I opted to scale each child independently so smaller components wouldn’t be scaled until necessary.
First the constructor:
public function HScaledCanvas() { super(); /* disable scroll bars */ horizontalScrollPolicy = ScrollPolicy.OFF; verticalScrollPolicy = ScrollPolicy.OFF; }
Next I override updateDisplayList:
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth,unscaledHeight); /* run through each child of this Canvas */ for each (var child:UIComponent in this.getChildren()) { /* the original width of the child before any scaling is applied */ var childUnscaledWidth:Number = child.measuredWidth / child.scaleX; /* the appropriate scale to apply to the child for it to fill the canvas width */ var scale:Number = this.width / childUnscaledWidth; /* do not over-scale the object */ if (scale>1) scale = 1; /* set the new scale */ if (scale != child.scaleX) { child.scaleX = scale; child.scaleY = scale; } } }
Finally, Here is an example of it in use:
<view:HScaledCanvas width="100%"> <mx:VBox width="100%" horizontalAlign="center" verticalGap="0"> <mx:Label textAlign="center" text="{chart.topicSentence}" fontSize="22" includeInLayout="{chart.topicSentence!=null}"/> <mx:Text textAlign="center" text="{chart.title}" fontSize="14" selectable="false"/> </mx:VBox> </view:HScaledCanvas>