FXG is a declarative XML syntax for defining vector graphics
in applications built with Flex. FXG can also be used as an interchange
format with other Adobe tools such as Illustrator or Photoshop.
FXG closely follows the Flash Player 10 rendering model.
Designers can create vector images using tools such as Photoshop,
Illustrator and Fireworks and export them as an FXG document. You
can then use that FXG document as a component in your applications.
The following example is an FXG document that draws a filled
rectangle:
When using FXG documents as components, you specify the tag to
be the name of the FXG file, just as you would do with an ActionScript
or MXML component.
The following application uses the GraphicComp.fxg file as a
component:
The executing SWF file for the previous example is shown below:
FXG documents encapsulate nearly all of their functionality in
a single document. FXG documents cannot reference other FXG documents
or MXML documents. However, they can reference the following external
resources:
Like MXML graphics, FXG tags have an implicit depth order. The
order in which elements are defined defines their depth. Each tag
is effectively drawn above its previous sibling. Children are drawn
on top of their parents.
Adobe Creative Suite tools can be used to convert SVG to FXG.
To do this, open the SVG file in the tool and export it as an FXG
file.
FXG syntax
The root of an FXG document file is a <Graphic> tag.
An FXG document can include zero or more containers (such as Group)
and graphic elements, as well as a single library that can include
any number of definitions.
The <Graphic> tag can only appear once
in an FXG document. While the document cannot contain other <Graphic> elements,
it can contain other elements such as <Rect>, <Ellipse>, <Path>,
and <BitmapImage>. The <Graphic> tag
can also optionally contain a single child <Library> tag and/or
a single <mask> tag. These elements must
appear before any other tag. If both are present, then the <Library> tag
must come first.
You cannot specify an ID for the root <Graphic> tag
in an FXG document.
FXG documents use the following language namespace:
http://ns.adobe.com/fxg/2008
When you create an FXG document, you must also add the version attribute
to the <Graphic> root tag. The currently
supported version is 2. For example:
To use an FXG document in an application, you treat is as any
other component. In your application, you define a namespace that
matches the location of the FXG document. This namespace definition
includes a prefix. For example:
<s:Application
...
xmlns:comps="comps.*">
You then use that prefix to reference the FXG document as a component;
for example:
<comps:MyGraphicComp id="graphic1"/>
FXG data types
The following table describes the basic data types that
you can use in an FXG document:
Data Type
Description
angle
An arbitrary number specified as degrees.
Angles are clockwise.
color
A numerical RGB specification in hexadecimal
notation. You specify a color by using a pound sign (#) immediately
followed by six hexadecimal characters. You cannot use the 0x notation
that is supported in MXML graphics.
coordinate
Represents a length in the local coordinate
system that is the given distance from the origin of the local coordinate
system along the relevant axis (the x-axis for x coordinates, the
y-axis for y coordinates).
identifier
A text string that matches the regular expression
[A-Za-z][A-Za-z0-9_]*.
integer
An optional sign character (+ or -) followed
by one or more digits 0 through 9. If the sign character is not
present, the number is non-negative. Unless stated otherwise for
a particular attribute or property, the range for an integer ranges from
-2147483648 to 2147483647.
length
A distance measurement. The format of a
length is a number.
number
Specified either in decimal notation, or
in scientific notation. Decimal notation consists of either an integer
or an optional sign character, followed by zero or more digits,
followed by a dot (.), followed by one or more digits. Scientific notation
consists of a decimal-number immediately followed by the letter
"e" or "E" immediately followed by an integer.
Unless stated
otherwise for a particular attribute or property, a number has the
capacity for at least a single-precision floating point number and
has a range of -3.4e+38F to +3.4e+38F.
percentage
A number immediately followed by a percentage
sign (%). Percentage values are always relative to another value;
for example, a length. Attributes or properties that allow percentage
values also define the reference distance measurement to which the
percentage refers.
Tags not supported by FXG
While FXG is syntactically very similar to MXML, FXG does
not define equivalents for all the MXML language tags. It does,
however, include the <Definition>, <Library> and <Private> elements,
which are equivalent to the MXML language tags of the same names.
FXG does not define any other MXML language tags. The MXML language
tags not defined by FXG include the following tags:
<fx:Binding>
<fx:Component>
<fx:Declaration>
<fx:Metadata>
<fx:Model>
<fx:Reparent>
<fx:Repeater>
<fx:Script>
<fx:State>
<fx:states>
<fx:Style>
FXG syntax also does not include any ActionScript 3.0 built-in
primitive tags. The list of built-in tags that are not defined by
FXG includes the following:
<fx:Array>
<fx:Boolean>
<fx:Class>
<fx:Date>
<fx:Function>
<fx:int>
<fx:Number>
<fx:Object>
<fx:String>
<fx:uint>
<fx:XML>
<fx:XMLList>
FXG does not support data binding. If you try to use the data
binding short-hand syntax in an FXG document, the compiler treats
it as a literal String value.
Using FXG in applications built with Flex
When you use an FXG document as a component in your application,
the compiler optimizes the document into a subclass of the spark.core.SpriteVisualElement
class. Specifically, the compiler maps the FXG elements to SWF graphics
primitive tags and links only a light-weight, Sprite-based class
into your application.
The SpriteVisualElement class extends the Sprite class. It adds
support for sizing, positioning, and alpha when used in an application
built with Flex.
To use FXG as a component in your applications:
Store the FXG document in a location where the compiler
can find it. This can be in the same directory as the application,
or in a separate location. If you store the FXG document in a separate
location, you must add the location to the compiler’s source path.
Declare a namespace for the component. For example, if the
FXG file is in the same directory as the main application that uses
it, you can declare a namespace of “*”. If the FXG file is in a
directory called comps, you can declare a namespace of “comps.*”.
Add a tag in your application that declares the component
inside a Spark container. (You cannot use a MX container as a direct
parent of an FXG component.) You can set DisplayObject properties
on the tag, such as x and y, alpha, height and width.
You can also add event handlers that are supported by the SpriteVisualElement
class on the tag.
The following example creates multiple instances of the star.fxg
component, and sets properties on each of those instances:
The executing SWF file for the previous example is shown below:
The following is the FXG component that is used by the previous
example:
<?xml version='1.0' encoding='UTF-8'?>
<!-- fxg/star.fxg -->
<fxg:Graphic xmlns:fxg="http://ns.adobe.com/fxg/2008" version="2">
<fxg:Path x="9.399" y="10.049" data="M 82.016 78.257 L 51.895 69.533 L 27.617 89.351 L 26.621 58.058 L 0.231 41.132 L 29.749 30.52 L 37.714 0.241 L 56.944 24.978 L 88.261 23.181 L 70.631 49.083 Z">
<fxg:fill>
<fxg:SolidColor color="#FFFFFF"/>
</fxg:fill>
<fxg:stroke>
<fxg:SolidColorStroke
caps="none"
color="#4769C4"
joints="miter"
miterLimit="4"
weight="20"/>
</fxg:stroke>
</fxg:Path>
</fxg:Graphic>
FXG documents use only the *.fxg filename suffix. You cannot
have another file of the same name with an *.mxml or *.as suffix
in the same directory.
You can use ActionScript to instantiate an FXG component. When
you do this, you declare the FXG tag to be of type SpriteVisualElement.
You then add the component to the display list by calling the addElement() method,
as the following example shows:
<?xml version="1.0" encoding="utf-8"?>
<!-- fxg/OptimizedFXGActionScriptExample.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
width="500" height="300"
creationComplete="drawStar()">
<fx:Script>
<![CDATA[
import spark.core.SpriteVisualElement;
private var myStar:SpriteVisualElement;
private function drawStar():void {
// Create new instances of star.fxg as if it were a local component.
for (var i:int = 0; i<4; i++) {
myStar = new star();
myStar.x = 50 + (i*75);
myStar.y = 50;
myStar.height = 100 - (i*30);
myStar.width = 100 - (i*30);
myStar.alpha = 1 - (i*.2);
myStar.rotationX = 20 + (i*20);
addElement(myStar);
}
}
]]>
</fx:Script>
</s:Application>
The executing SWF file for the previous example is shown below:
Generating FXG
When you export a graphic file from a tool such as Adobe
Illustrator in the FXG format, the tool writes a *.fxg file with
a <Graphic> root tag.
If you are given the option to select a version of FXG, select
version 2.
You can ignore the information in the <Private> code
block, as long as you also leave the its namespace declaration.
The contents of the <Private> block must
be well-formed and valid XML but is not rendered.
You can optionally remove the <Private> tag
and its contents from the FXG document. Some tools export FXG with
additional syntax so that the file can be re-edited. An FXG document
exported from Illustrator, for example, includes a <Private> block
of code that is used by Illustrator if you want to edit the file again.
If you do not expect to edit the file in Illustrator again, then
you can remove the <Private> block.
Converting FXG elements to MXML graphics
In general, you should use an FXG document as a standalone
component in your applications. This gives you the greatest amount
of memory optimization, and lets you reuse your FXG files in other
parts of the same application, or in other applications. In addition,
by keeping the FXG document separate from the application, you can
edit and export the FXG again from a graphics tool.
One disadvantage to using an FXG file as a standalone component
is that you cannot get a reference to individual elements in it.
The FXG component itself is a “black box”; you cannot interact with
individual elements from your application or other components. You
can, however, still apply effects, resize, position, and trigger
events from interaction with the FXG component itself.
In some cases, you might want to add the FXG output directly
into your application. You can do this, but you must convert the
FXG syntax to MXML graphics.
After converting FXG elements to MXML graphics, you can get a
reference to the various graphic elements, just as you can with
any other MXML tags. This is useful if you want to apply special
effects or events to what were previously FXG elements. After you
convert the FXG file to MXML graphics, you cannot re-edit the FXG
file in a graphics tool. It is now part of MXML.
To convert an FXG document to MXML graphics:
Start
by copying and pasting the FXG code into your MXML document.
Update the namespaces:
Change the FXG namespace
(http://ns.adobe.com/fxg/2008) to the Spark component namespace
(library://ns.adobe.com/flex/spark). There can be only one language
namespace per document.
If the FXG fragment uses additional tool specific namespaces,
you can add these to the root of the MXML file. For example, FXG
exported from Adobe Illustrator typically includes the following
namespace declarations:
These
namespaces do not impact the rendering of the document, but must be
retained to keep the XML document valid as tool-specific private
attributes will be prefixed in these namespaces.
Change or remove any namespace prefixes on the <Library>, <Definition>,
and <Private> elements. They must use the
MXML 2009 language namespace (http://ns.adobe.com/mxml/2009). If
you remove a namespace prefix on the tag, you can usually just add
the “fx:” prefix to each of these elements.
Move the <Library> tag and any <Definition> elements
it contains to the top of the MXML document. If there is already
a <fx:Library> tag in the MXML document,
move just the <Definition> elements into
it and remove the FXG <Library> tag.
For library definitions, add the “fx:” prefix to their tags
in the body of the MXML file. In MXML 2009 documents, library definitions
are actually in the language namespace. For example, the <fx:Definition name="BlueCircle"> tag
references to a definition that must also be in the “fx” namespace;
for example, <fx:BlueCircle>.
Move the <Private> tag to the end
of the MXML document or remove it. You do not need to include the <Private> tag
at all, but it can contain useful information about the tool that
generated the FXG.
Update the namespace prefix of the FXG elements. There is
likely to be an “s:” prefix already mapped to the Spark component
namespace on the MXML document’s root tag (xmlns:s="library://ns.adobe.com/flex/spark").
Add the “s:” prefix to all of the FXG graphical elements. For example,
change <Graphic> to <s:Graphic>.
For FXG 1.0 documents only:
Convert <TextGraphic> elements
to <s:RichText>. This does not apply to FXG
2.0 documents, which use the <RichText> tag.
In that case, you just add the “s:” prefix to the <RichText> tag
to make it conform to MXML syntax.
Convert <BitmapGraphic> elements to <s:BitmapImage>.
This does not apply to FXG 2.0 documents, which use the <BitmapImage> tag.
In that case, you just add the “s:” prefix to the <BitmapImage> tag
to make it conform to MXML syntax.
The following file, exported in FXG format from Adobe Illustrator,
includes the private information as well as the <Graphic> root
tag. The contents of this *.fxg file are being shown so that you
can then see in a subsequent example how the contents are converted
to MXML graphics.
Because the “d” and “ai” namespace definitions are intact,
you do not have to remove the attributes specific to these namespaces.
The attributes type and userLabel,
for example, appear on the <Group> tag from
the original FXG file. To further simplify this example, though,
you could remove them because Flex ignores anything in those namespaces.
The executing SWF file for the previous example is shown below:
Coordinate systems
FXG defines two coordinate system concepts: the document
coordinate system, and the user coordinate system.
The document coordinate system refers to the coordinate
system of the root tag. By default, its origin sits at the top left
of the document, and extends downward along the positive y axis,
and to the right along the positive x axis. 1 unit corresponds to
1 pixel on the screen.
The user coordinate system refers to the coordinate system
defined on any individual tag in the document. In FXG, the user
coordinate system at the root <Graphic> tag
is identical to the document coordinate system.
By default, each grouping instance element and graphic element
defines its user coordinate system to be identical to that of its
parent. Any geometry transform defined on the tag (through attributes
or child transform elements) transforms its parent’s user coordinate
system into a new system.
All attributes of elements are defined in units of the current
user coordinate system. As a result, the coordinates of the segments
of a path are relative to its coordinate system. To determine the
position of the path segments in document coordinates, you would
multiply its x and y by the geometry transform of the path and each
of its parent elements until you reached the root graphic tag.
Some fills and strokes have their own user coordinate system.
As with Groups, the default coordinate system is aligned with the
coordinate system of their most immediate parent instance. As appropriate,
fills and strokes support geometry transforms that can modify their
coordinate space.
Sizing FXG components
FXG elements use their height and width properties
to determine the size of the graphic. The graphic tag scales to
the values of the height and width properties.
The viewWidth and viewHeight properties
define the space that the graphic takes up. When you set these values,
the content is not scaled.
If you specify a viewWidth and viewHeight that
is larger than the natural size of the content, the graphic takes
up more space than its visual size. The result is a boundary around
the graphic.
You can also specify a viewWidth and viewHeight that
is smaller than the natural size of the content. You might do this
if your graphic has chrome such as a border that extends past the
edges of the graphic. In this case, be sure to turn off clipping
in your layout.
Optimizing FXG
Use the techniques described in this section when working
with FXG.
Composite path versus rounded rectangle
Composite paths create a cleaner look because there are
no extra pixels inside the corners. Rounded rectangles, on the other
hand, have extra pixels due to anti-aliasing. Rounded rectangles
convert to a <Rect> element in FXG, which
is preferable because a <Rect> element is
easier to manipulate than a compex path.
Move alpha values from the element to the fill or stroke
When exporting FXG files from a graphics editor, the alpha property
is sometimes placed on the graphic element tag. If you convert the
FXG to MXML, this element uses its own DisplayObject, which can
be computationally expensive. To avoid this, move any alpha properties
from the element tag down to the stroke or fill. If both the stroke/fill
and the element have alpha values, multiply the
stroke and fill alpha values by the element’s alpha value.
For example, if the stroke and element alpha values
are both .5, then remove the element’s alpha property
and set the stroke’s alpha to .25 (.5 x .5).
Round alpha values to 2 decimal places
Exported FXG files sometimes use percentage values for alpha values.
The visual difference between an alpha value with
two decimal places and a rounded alpha value is
negligible. To make your code more readable, round off alpha values
to 2 decimal places. For example, round an alpha value
of 0.05882352941176471 to 0.06.
Remove blendMode=”normal”
By default on graphic elements, the blendMode is
“auto”. When the blendMode property is “auto”,
Flash Player correctly determines whether the element needs to use
the “layer” blendMode based on the alpha value.
Identifying elements of an FXG file
Sometimes it can be hard to look at FXG tags and determine
what that element looks like. An easy way to do this is to copy
your FXG into a <s:Group> tag in an MXML
application. Then, change the x values of each element so that they
no longer overlap. For example, if your skin is 45 pixels wide and
is comprised of three <Rect> elements, increase
the x value of the second <Rect> by
50 and the third <Rect> by 100. When you
compile and run the application, you can see each layer spread separately.
An alternative is to toggle the visible property
of different elements so that you can isolate a particular element.
Placing shapes with odd stroke weights (mobile applications only)
For a given shape, strokes straddle the shape edges as
opposed to being on the inside or outside of an edge. For example,
take a vertical line starting from 0,0 to 0,100 with a 1-pixel wide
stroke. That stroke stretches in the x-axis from -.5 to .5. However,
because you cannot draw an element at a fractional pixel, Flash
Player draws an anti-aliased line 2 pixels wide to approximate the
fractional position.
This is true only on mobile applications. For desktop applications,
Flash Player pixel-snaps stroke segments.
To counteract this anti-aliasing, place your shapes with odd
numbered stroke weights on a half pixel boundary. For example, place
a <Rect> with a <SolidColorStroke> of
weight 1 at 10,10 at 10.5,10.5 instead.
An alternative is to leave all of your stroked shapes at integer
pixels and shift the entire FXG component by .5 in the x and y positions.
If possible, use filled <Rect> elements in
place of stroked <Rect> or <Line> elements.
If you have a <Rect> element with a fill
and a stroke, try to split it into two filled <Rect> elements
This technique works only if the fill is completely opaque. If you
have a <Line> element, try using a filled <Rect> element
instead. For example, if you have a horizontal <Line> element,
create a filled <Rect> element with a height equal
to the <Line> element’s stroke weight.
Reduce anti-aliasing due to stage quality
Mobile applications built in Flex are currently limited
to using StageQuality.MEDIUM. When designing skins
using FXG and/or programmatic graphics, watch for anti-aliasing
artifacts in rounded corners. The mobile skins mitigate this issue
by using FXG Path data with fills instead strokes to draw curves.
To create the appearance of a rounded rectangle at a 1px stroke
in Fireworks:
Draw a filled rounded rectangle.
Copy the rectangle, position it 1px down and to the left
of the original rectangle and reduce its width and height by 2px.
Select both rectangles, right click and choose Combine Path
> Punch.
Use 45 degree angles
Try to keep all angles at 45 degrees. This helps to reduce
the visual artifacts from anti-aliasing.