开发者

How to build efficient button skins with larger hitareas than visible area

What I'm trying to do: build a super simple button skin (say a small circle when in up state, slightly larger circle when in over / down states) that has a larger mouse hit area than visible area. In other words, I'd like the button to look like a 5x5 circle when in up state, but transition to over state when the mouse is in a 15x15 pixel area around such circle - in order to make clicking on the button easier.

What I've done in the past is to use a transparent ellipse behind开发者_开发问答 the the visible ellipse. This works nicely but seems like a waste of memory (not much, although if you start having a lot of these buttons it adds up) and rendering cycles (transparency). I thought I could avoid this by wrapping the ellipse in a group with a given size and listen to its mouse events, but somehow no mouse events seem to fire on such a group - not sure why.

I guess I'd love to know if anyone knows an efficient way to do this. Also would love to know why such a group won't fire mouse events, but I guess that's secondary. Simple code snippet below:

the application:

<?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" minWidth="955" minHeight="600">
    <s:Button x="100" y="100" skinClass="mySkin"/>
</s:Application>

the button skin:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009">

    <fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
    <fx:Script>
        <![CDATA[
            import mx.states.OverrideBase;


            protected function group1_rollOverHandler(event:MouseEvent):void
            {
                trace("roll over");
            }

        ]]>
    </fx:Script>
    <s:states>
        <s:State name="up"/>
        <s:State name="over"/>
        <s:State name="down"/>
        <s:State name="disabled"/>
    </s:states>
    <s:Group width="15" height="15" rollOver="group1_rollOverHandler(event)">
        <s:Ellipse height.up="5" height="12" width="12" width.up="5" 
                   x="0" y="0" x.up="3" y.up="3">
            <s:fill>
                <s:SolidColor color="0x222222"/>
            </s:fill>
        </s:Ellipse>
    </s:Group>
</s:SparkSkin>


I wouldn't worry about the memory of an Ellipse inside of a SparkSkin. If you are that concerned about memory, you would want to roll your own Button

However, there are a couple of very minor performance enhancements that won't effect the implementation:

  1. Use Skin instead of SparkSkin. it is lighter weight.
  2. Use Rect for the hitarea. It is lighter weight than Ellipse
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜