Path is a Flex 4 drawing class that fills a shape using coordinates you provide. It’s very simple once you get the hang of it, and if you add some filters you can come up with a pretty nice looking image. In this post I’m going to show you a quick overview of how to draw a custom arrow using Path that can be used as a button as seen in this sample:
You can right-click the sample to view or download the source.
After creating a new Flex 4 Web Application project, I create a new MXML skin named NextButtonSkin based on spark.components.Button. While my button will use the states and functionality of a Spark button, it will use none of the look so I delete most of the default Button MXML. ( If you want more detail on button skinning you can take a look at my Create Your Own Image Buttons post. ) The remaining button skin code looks like this:
<?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" minWidth="48" minHeight="48" alpha.disabled="0.5"> <!-- host component --> <fx:Metadata> <![CDATA[ /* @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.Button")] ]]> </fx:Metadata> <!-- states --> <s:states> <s:State name="up" /> <s:State name="over" /> <s:State name="down" /> <s:State name="disabled" /> </s:states> <!--- Your arrow will start after this line ---> <!---- Your arrow will end above this line -----> </s:SparkSkin>
Notice that the code above doesn't even contain a button because I'm going to create my own graphic to use as a button. To start, I add a Graphic containing a Path and a fill. I don't draw my arrow first because, without a fill, I won't be able to see the arrow I'm going to draw. At this point my Graphic code looks like this:
<!--- Your arrow will start after this line ---> <s:Graphic> <s:Path data=""> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xfd1901" color.down="0xAF220D" /> <s:GradientEntry color="0xa70d12" color.down="0xAF220D" /> </s:LinearGradient> </s:fill> </s:Path> </s:Graphic> <!---- Your arrow will end above this line ----->
Now I can begin drawing my arrow. When creating a path, picture your image on grid paper. The lines you draw will run along the grid lines and the fill will color in the middle for you, something like this:
The arrow is defined inside the data property of the Graphic and each segment includes a segment type and x/y coordinates relative to the end point of the previous segment. I'm only going to use a few of the possible segment types, but if you want to see the full list you can check them out here.
Since I don't have an end point when I start off, the first command I put in there, "m 5 20", will tell the application that the segment I'm drawing will start 5 pixels in and 20 pixels down from the top of the Graphic area. If I were drawing the arrow on paper this would mean I was putting my pencil to paper 5 grid squares in and 20 down.
From there I want to draw a horizontal line 15 pixels long and extending to the right of my starting point. "h 15" accomplishes the task. If I wanted the line to extend to the left, I would enter "h -15". From that point I want to draw a line, slightly diagonal, that will be the beginning of the arrow head. There's no "d" for diagonal, so I have to tell it to draw a line to a certain point. In this case, I enter "l -3 -8" which draws a line from the end point of my horizontal line and extending 3 pixels to the left and 8 pixel up. Get the idea?
The finished arrow code looks like this:
<!--- Your arrow will start after this line ---> <s:Graphic> <s:Path data="m 5 20 h 15 l -3 -8 l 18 14 l -18 14 l 3 -8 h -18 v -12"> <s:fill> <s:LinearGradient rotation="90"> <s:GradientEntry color="0xfd1901" color.down="0xAF220D" /> <s:GradientEntry color="0xa70d12" color.down="0xAF220D" /> </s:LinearGradient> </s:fill> <s:stroke> <s:SolidColorStroke color="0xAF220D" weight="1" alpha=".8" alpha.disabled="0" alpha.up="0"/> </s:stroke> </s:Path> </s:Graphic> <!---- Your arrow will end above this line ----->
That's it! My "Next" arrow is done. I follow the same process for the Previous button. Then, I add them to my default page, which ends up looking like this:
<?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 skinClass="PrevButtonSkin" buttonMode="true" left="25" top="25" /> <s:Button skinClass="NextButtonSkin" buttonMode="true" left="100" top="25" /> </s:Application>
The skinClass attribute of the Buttons contains the name of the MXML skin files where I drew the buttons. That's all there is to it.
To view or download the complete source, right-click on the app at the top of this post and click "View Source".