Thanks for sharing. 🙂
Btw. this is my refactored "RadialProgressBar" and "RadialPolygon" class. Feel free to use it.
The important thing is that "loadingAnimationEnabled" property is creating similiar effect as you created. 🙂
Usage:
var radialProgressBar:RadialProgressBar = new RadialProgressBar();
radialProgressBar.backgroundTexture = someTexture;
radialProgressBar.progressTexture = someAnotherTexture;
radialProgressBar.loadingAnimationEnabled = true;
addChild(radialProgressBar);
package com.thebutton.game.ui {
import com.thebutton.ui.RadialPolygon;
import feathers.core.FeathersControl;
import starling.display.Image;
import starling.textures.Texture;
/**
* Progress bar with radial mask.
* @author Jakub Wagner, J4W
*/
public class RadialProgressBar extends FeathersControl {
private var radialPolygon:RadialPolygon;
private var _background:Image;
private var _progress:Image;
private var _backgroundTexture:Texture;
private var _progressTexture:Texture;
private var _backgroundOffsetX:Number = 0;
private var _backgroundOffsetY:Number = 0;
public function RadialProgressBar() {
super();
radialPolygon = new RadialPolygon();
}
override protected function initialize():void {
super.initialize();
_background = new Image(backgroundTexture);
_progress = new Image(progressTexture);
addChild(_background);
addChild(_progress);
addChild(radialPolygon);
width = _progress.width;
height = _progress.height;
_progress.mask = radialPolygon;
}
override protected function draw():void {
super.draw();
if (isInvalid(INVALIDATION_FLAG_SIZE)) {
_progress.width = width;
_progress.height = height;
radialPolygon.radius = width / 2;
radialPolygon.x = width / 2;
radialPolygon.y = height / 2;
_background.scale = _progress.scaleX;
_background.x = _backgroundOffsetX * _progress.scale;
_background.y = _backgroundOffsetY * _progress.scale;
}
}
public function get backgroundImage():Image {
return _background;
}
public function get progressImage():Image {
return _progress;
}
public function get backgroundTexture():Texture {
return _backgroundTexture;
}
public function set backgroundTexture(value:Texture):void {
_backgroundTexture = value;
if (_background)
_background.texture = value;
}
public function get progressTexture():Texture {
return _progressTexture;
}
public function set progressTexture(value:Texture):void {
_progressTexture = value;
if (_progress)
_progress.texture = value;
}
public function get backgroundOffsetX():Number {
return _backgroundOffsetX;
}
public function set backgroundOffsetX(value:Number):void {
_backgroundOffsetX = value;
if (_background)
_background.x = value;
}
public function get backgroundOffsetY():Number {
return _backgroundOffsetY;
}
public function set backgroundOffsetY(value:Number):void {
_backgroundOffsetY = value;
if (_background)
_background.y = value;
}
/* DELEGATE com.thebutton.ui.RadialPolygon */
public function get loadingAnimationEnabled():Boolean {
return radialPolygon.loadingAnimationEnabled;
}
public function set loadingAnimationEnabled(value:Boolean):void {
radialPolygon.loadingAnimationEnabled = value;
}
public function tweenTo(value:Number, time:Number = 5, onComplete:Function = null):void {
radialPolygon.tweenTo(value, time, onComplete);
}
public function get value():Number {
return radialPolygon.value;
}
public function set value(value:Number):void {
radialPolygon.value = value;
}
}
}
package com.thebutton.ui {
import starling.animation.Transitions;
import starling.core.Starling;
import starling.display.Canvas;
import starling.events.EnterFrameEvent;
import starling.geom.Polygon;
/**
* X-sided polygon that can be tweened.
* @author Jakub Wagner, J4W
*/
public class RadialPolygon extends Canvas {
private var polygon:Polygon;
private var _loadingAnimationEnabled:Boolean = false;
private var _sides:Number = 4;
private var _value:Number = 0;
private var _radius:Number;
public function RadialPolygon() {
}
protected function draw():void {
pivotX = pivotY = radius;
polygon = new Polygon();
// TODO: do not re-create polygon over and over
updatePolygon(value, radius, radius, radius, Math.PI / 2);
clear();
beginFill(0xFF0000);
drawPolygon(polygon);
endFill();
}
public function get value():Number {
return _value;
}
public function set value(value:Number):void {
if (_value != value) {
_value = value;
draw();
}
}
public function get radius():Number {
return _radius;
}
public function set radius(value:Number):void {
if (_value != value) {
_radius = value;
draw();
}
}
public function get sides():Number {
return _sides;
}
public function set sides(value:Number):void {
if (_value != value) {
_sides = value;
draw();
}
}
/**
* Show loading rotating circle animation if true. Overrides current progress.
* Progress is set to 0 if set to false.
*/
public function get loadingAnimationEnabled():Boolean {
return _loadingAnimationEnabled;
}
public function set loadingAnimationEnabled(value:Boolean):void {
_loadingAnimationEnabled = value;
this.value = 0;
if (value) {
Starling.juggler.tween(this, 1, {value: 1, onRepeat: onLoadingAnimationStepComplete, repeatCount: 0, reverse: true, transition: Transitions.EASE_IN_OUT});
addEventListener(EnterFrameEvent.ENTER_FRAME, onLoadingAnimationFrame);
} else {
Starling.juggler.removeTweens(this);
removeEventListener(EnterFrameEvent.ENTER_FRAME, onLoadingAnimationFrame);
rotation = 0;
}
}
public function tweenTo(value:Number, time:Number = 5, onComplete:Function = null):void {
Starling.juggler.tween(this, time, {value: value, onComplete: onComplete, transition: Transitions.EASE_IN_OUT});
}
[Inline]
private function lineToRadians(rads:Number, radius:Number, x:Number, y:Number):void {
polygon.addVertices(Math.cos(rads) * radius + x, Math.sin(rads) * radius + y);
}
private function updatePolygon(percentage:Number, radius:Number = 50, x:Number = 0, y:Number = 0, rotation:Number = 0):void {
polygon.addVertices(x, y);
if (sides < 3)
sides = 3; // 3 sides minimum
radius /= Math.cos(1 / sides * Math.PI);
var sidesToDraw:int = Math.floor(percentage * sides);
for (var i:int = 0; i <= sidesToDraw; i++)
lineToRadians((i / sides) * (Math.PI * 2) + rotation, radius, x, y);
if (percentage * sides != sidesToDraw)
lineToRadians(percentage * (Math.PI * 2) + rotation, radius, x, y);
}
// ************************************************************* //
// ********************Event Listeners********************** //
// ************************************************************* //
private function onLoadingAnimationFrame(e:EnterFrameEvent):void {
rotation += 0.03;
}
private function onLoadingAnimationStepComplete():void {
scaleX = -scaleX;
}
}
}