A quick introduction to OpenFL for Feathers UI

Feathers UI is powered by the OpenFL library and the Haxe programming language. OpenFL provides APIs for rendering, networking, user input, and more. At the core of OpenFL is the display list, its graphics system that can be used to draw vectors and bitmaps with the ability to intuitively group objects together in a parent-child hierarchy.

These primitives in OpenFL are combined in Feathers UI to create a set of flexible user interface components for creative projects — whether you are building rich applications, menu screens for games, interactive data visualizations, or immersive multimedia experiences.

This document is meant to provide a basic overview only. The following links provide more detailed documentation and learning materials for OpenFL.

The display list

The OpenFL display list provides a number of primitive display objects for rendering graphics.

One of these core primitives is the openfl.display.Sprite class, which provides vector drawing capabilities — plus the ability to behave as a container where you may add other display objects as children.

var sprite = new Sprite();
sprite.graphics.drawRoundRect(0.0, 0.0, 100.0, 25.0, 6.0);
sprite.x = 20.0;
sprite.y = 50.0;

The code above draws a red rectangle, changes its position, and adds it as a child on the display list.

Another primitive offered by OpenFL is the openfl.text.TextField class, which is used for rendering text.

var textField = new TextField();
textField.defaultTextFormat = new TextFormat("_sans", 20, 0xffffff);
textField.text = "Hello OpenFL";
textField.autoSize = TextFieldAutoSize.LEFT;
textField.x = (sprite.width - textField.width) / 2.0;
textField.y = (sprite.height - textField.height) / 2.0;

The example above adds the text "Hello OpenFL" as a child of the Sprite. The text's font styles are customized with openfl.text.TextFormat, and it is positioned in the center of the rectangle.

User input

OpenFL dispatches events for user input from a variety of sources, including keyboard, mouse, touchscreen, and game pads.


To listen for keyboard events globally, add an event listener for openfl.events.KeyboardEvent.KEY_DOWN to the OpenFL Stage object.

stage.addEventListener(KeyboardEvent.KEY_DOWN, (event:KeyboardEvent) -> {
    switch(event.keyCode) {
        case Keyboard.UP:
            trace("key down: up arrow");
        case Keyboard.DOWN:
            trace("key down: down arrow");
        case Keyboard.LEFT:
            trace("key down: left arrow");
        case Keyboard.RIGHT:
            trace("key down: right arrow");

The event listener above determines if the up, down, left, or right arrow keys have been pressed.

The trace() function is built into Haxe programming language, and it prints some text to the debug console.

In many cases, a listener is also added for openfl.events.KeyboardEvent.KEY_UP to determine when a key press ends.


To react when the user clicks a display object with the mouse, add an event listener for openfl.events.MouseEvent.CLICK.

sprite.addEventListener(MouseEvent.CLICK, (event:MouseEvent) -> {

Several more commonly-used mouse events offer real-time access to the mouse position and the button state.


To run some code when the user taps a display object on a mobile device's touchscreen, add an event listener for openfl.events.TouchEvent.TOUCH_TAP.

sprite.addEventListener(TouchEvent.TOUCH_TAP, (event:TouchEvent) -> {
    trace("tapped! " + event.touchPointID);

Similar to the low-level mouse events, a number of commonly-used low-level touch events are available too.

These events might be used to drag objects around or to create multitouch gestures.


One way that OpenFL provides to load data over the network is the openfl.net.URLLoader class, which can parse the returned data in multiple formats — including plaintext or binary.

var loader = new URLLoader();
loader.load(new URLRequest("http://api.example.com/list"));

The example above loads text from an API server by passing a openfl.net.URLRequest object to the loader's load() method.

The openfl.net.URLRequest class creates a GET request by default, but it also supports POST requests, and it can pass additional variables to the backend too.

To determine when the data has completed loading successfully, add an event listener for openfl.events.Event.COMPLETE to the URLLoader.

loader.addEventListener(Event.COMPLETE, (event:Event) -> {
    var loader = cast(event.currentTarget, URLLoader);
    var data = Std.string(loader.data);
    trace("data loaded: " + data);

Listen for openfl.events.ProgressEvent.PROGRESS to track how much data has loaded, and how much is still not available.

loader.addEventListener(ProgressEvent.PROGRESS, (event:ProgressEvent) -> {
    var loader = cast(event.currentTarget, URLLoader);
    var percent = 100.0 * loader.bytesLoaded / loader.bytesTotal;
    trace("Loaded: " + Math.floor(percent) + "%");