Display Data With Funky Animated Needle Gauges
Creating appealing data visualization has always been one of Flash's key features. It allows you to achieve eye candy results with real dynamic data; be it in a preloader, a game, or an office presentation.
This simple tutorial will show you how to build a needle gauge meter. You'll learn how to apply a "gloss" effect, communicate with XML, and apply a tween engine to rotations.
Step 1: Folder Setup
Create three files: gauge.fla, gauge.xml, and Main.as.
Step 2: XML Structure
Open gauge.xml. This file will contain the data that populates the meters; edit them however you like based on the following structure:
1 |
|
2 |
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
3 |
<indicators>
|
4 |
<gauge>
|
5 |
<value>64</value> |
6 |
<description>Male</description> |
7 |
</gauge>
|
8 |
<gauge>
|
9 |
<value>26</value> |
10 |
<description>Female</description> |
11 |
</gauge>
|
12 |
</indicators>
|
Value is a percentage and so should be between 0 and 100. The description will be displayed on the corresponding gauge.
Step 3: Stage Settings
Open gauge.fla and change the settings as shown below.
Step 4: Create the Gauge Movie Clip
Create a new symbol, name it gauge_mc and set the Class to Gauge.
Step 5: Background Settings
Next, create a circle as shown below:
This will form the gauge's insides, so name this layer "background".
Step 6: Add a Surrounding Stroke
Add a stroke using the ink bottle tool (shortcut: S) with the following settings:
(Click on the background circle to apply the stroke.)
Step 7: Create a Frame with Gradient Effects
Switch to the Selection tool, click the stroke to select it, and press Modify > Shape > Convert Lines to Fills. Now, copy the fill and paste it in a new layer, created above the existing layer, called "frame". Add two new gradient strokes, each one pixel thick. One goes on the inside of the frame, the other goes on the outside.
Step 8: Draw the Pin
Create a new layer, name it "needle pin" and in the center make a small gray circle with a thick black outline:
Step 9: Draw the Needle
Create a new layer underneath the pin's and name it "needle". Draw a line, convert the line to a fill and convert this fill to a symbol (called needle_mc).
You need to move both the registration point and the rotation point of this new symbol to the center of the bottom of the line. To move the registration point, double-click the needle to edit, then drag the fill until the registration point is in the correct place. To move the rotation point, go back to editing the gauge_mc symbol, then use the Free Transform tool (shortcut: Q) to double-click the little circle. This will snap it to the registration point of the needle.
Step 10: Draw the Marker's Ring
Create a new layer beneath the needle's named "markers". Draw a circle, smaller than the frame, with a thick black stroke and no fill.
Step 11: Create a Star
On another new layer, select the PolyStar tool, and use it to create a ten-sided star, centered on the needle. We'll use this to create the little markers around the ring.
Step 12: Connect the Star's Points to the Center
On the markers layer, draw thin lines from the needle to each point of the star. This way, you know that they are evenly spaced.
Step 13: Create an Inner Circle for Cropping
Create a circle even smaller than the marker ring, then select the lines inside this circle and press delete to erase them all.
Step 14: Further Crops
Erase the inner circle, the outer markers and the bottom section of the marker ring, as highlighted below:
Step 15: Label the Markers
Label the markers: the first as 0, the middle one as 50, and the last as 100.
Step 16: Make the Glassy and Glossy Effects
Create a new layer on top of all the others named "glass" and another one above that named "gloss".
In the glass layer, draw a white circle the size of the background. Click Window > Color and give it a radial gradient fill, where both colors are white but one has a 20% alpha and the other has a 5% alpha.
In the gloss layer, create two white circles with gradient alphas that go from 70% to 30%. Use the Selection tool to squeeze their shapes to the ones shown below:
Step 17: Add a Description Label
Create another new layer named "label" and add a text field with "label_txt" as its instance name. Don't forget to embed the font!
Step 18: Add a Value Label
Add a new layer named "value" and add a text field with "value_txt" as its instance name. Again, don't forget to embed the fonts. I'm using a font called LCDDot, which you can find in the zip file.
Step 19: Correcting the Needle's Rotation Point
Right now, the needle is pointing at the 50% mark. We need it to be pointing at 0% when it starts, so double-click "needle_mc", select the fill and rotate it to -143º. This will give us the offset we need.
Step 20: Set the Document Class
Make sure nothing is selected, then in the Properties panel, type Main into the Class box to set Main.as as your document class. Now open it.
Step 21: Import Classes
We will be using GreenSock's tweening engine, TweenMax. You can download it here: http://blog.greensock.com/tweenmax/
Import the necessary classes for Main.as:
1 |
|
2 |
package { |
3 |
import flash.display.MovieClip; |
4 |
import flash.events.Event; |
5 |
import flash.net.URLLoader; |
6 |
import flash.net.URLRequest; |
7 |
import com.greensock.TweenMax; |
8 |
import com.greensock.events.TweenEvent; |
9 |
}
|
Step 22: Write the Main Constructor
This code should go after "import com.greensock.events.TweenEvent;" but before the last "}". The Main() function will be the first function run when the SWF loads.
1 |
|
2 |
public class Main extends MovieClip { |
3 |
|
4 |
private var xmlLoader:URLLoader; //this will load the xml |
5 |
private var xml:XML; //this will contain the xml data loaded by the xmlLoader |
6 |
private var gauges:Array; //this will store the created gauges |
7 |
|
8 |
public function Main() { |
9 |
gauges = new Array(); //start the array |
10 |
xmlLoader = new URLLoader(); //start the loader |
11 |
xmlLoader.addEventListener(Event.COMPLETE,updateGauges) //when XML is loaded, updates the gauges |
12 |
xmlLoader.load(new URLRequest("gauge.xml")); //initiates the loading of the XML file |
13 |
|
14 |
}
|
15 |
}
|
Step 23: Make the Gauge Move
Put this code before the last two "}" in your file. This function will be run when the XML has loaded.
1 |
|
2 |
private function updateGauges(e:Event):void { |
3 |
//populates the xml with the received data
|
4 |
xml = new XML(e.target.data); |
5 |
|
6 |
//iterates through the gauges inside the xml structure
|
7 |
var ln:int = xml.gauge.length(); //number of <gauge>s inside the XML file |
8 |
var i:int = 0 |
9 |
|
10 |
while (i < ln) { |
11 |
gauges[i] = new Gauge(); //creates a new Gauge and puts it in the gauges[] array |
12 |
gauges[i].label_txt.text = xml.gauge[i].description[0].toUpperCase(); //adds the description to the label of the i-th gauge based on the XML's i-th <gauge> |
13 |
gauges[i].value_txt.text = "0%" //starts the gauge meter value |
14 |
//animates the gauge rotation (286 is the maximum rotation of the needle we built)
|
15 |
var tm:TweenMax = new TweenMax(gauges[i].needle_mc, 2, { rotation:Math.round(xml.gauge[i].value[0] * 286 / 100) } ); |
16 |
//this event is activated when the tween value changes; we do this to update the value text according to the needle position
|
17 |
tm.addEventListener(TweenEvent.UPDATE, onTween) |
18 |
//y positioning
|
19 |
gauges[i].y = 45 |
20 |
//x positioning (220 pixels of distance between them and 50 pixels offset from the left margin
|
21 |
gauges[i].x = (i * 220) + 50 |
22 |
//adds to stage
|
23 |
addChild(gauges[i]); |
24 |
//increases i for the next iteration
|
25 |
i++ |
26 |
}
|
27 |
}
|
Step 24: Make the Numbers Change
Again, insert this before the last two "}" in your code. This function is run repeatedly as the needle is tweened (rotated).
1 |
|
2 |
private function onTween(e:Event):void { |
3 |
/*this will prevent a well known rotation bug inside flash
|
4 |
* where, when rotating, after it reaches 180º it starts to count up from -180
|
5 |
* (i.e. 0 to 180, -180 to 0). By adding 360 to the equation when the rotation is negative
|
6 |
* we can make sure the value is correct.
|
7 |
* */
|
8 |
if (e.target.target.rotation < 0) { |
9 |
e.target.target.parent.value_txt.text = (Math.round( (360+e.target.target.rotation) * 100 / 286) + "%"); |
10 |
}else{ |
11 |
e.target.target.parent.value_txt.text = (Math.round( e.target.target.rotation * 100 / 286) + "%"); |
12 |
}
|
13 |
}
|
Step 25: Check Out the Full Code
Confused about where any of the code should go? Check it out here.
Step 26: Finish Up
Now all you need is to head back to gauge.fla, and in the first frame add a background and a title:
Conclusion
As you can see, it's easier than it looks. Take your time and expand upon the concept: make a preloader, a bandwidth meter, whatever you like. Hope you enjoyed this tutorial, thanks for reading!