-
-
Save Klug76/121b829190173097b948dc596f25a41d to your computer and use it in GitHub Desktop.
A Starling Mesh that displays a slice of a quad (just like a pie chart, but rectangular). Useful e.g. for a circular progress indicator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package starling.extensions | |
{ | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import starling.display.Mesh; | |
import starling.rendering.IndexData; | |
import starling.rendering.VertexData; | |
import starling.textures.Texture; | |
public class QuadSection extends Mesh | |
{ | |
private var _width:Number; | |
private var _height:Number; | |
private var _color:uint; | |
private var _ratio:Number; | |
private static var sPoint:Point = new Point(); | |
private static const sSlices:Array = | |
[ | |
{ ratio: 0.0, u: 0.5, v: 0.0 }, | |
{ ratio: 0.125, u: 1.0, v: 0.0 }, | |
{ ratio: 0.375, u: 1.0, v: 1.0 }, | |
{ ratio: 0.625, u: 0.0, v: 1.0 }, | |
{ ratio: 0.875, u: 0.0, v: 0.0 }, | |
{ ratio: 1.0, u: 0.5, v: 0.0 } | |
]; | |
public function QuadSection(width:Number, height:Number, color:uint = 0xffffff) | |
{ | |
_color = color; | |
_width = width; | |
_height = height; | |
_ratio = 1.0; | |
var vertexData:VertexData = new VertexData(null, 6); | |
var indexData:IndexData = new IndexData(15); | |
super(vertexData, indexData); | |
this.updateVertices(); | |
} | |
private function updateVertices():void | |
{ | |
vertexData.numVertices = 0; | |
indexData.numIndices = 0; | |
if (_ratio < 1.e-4) | |
{ | |
setVertexDataChanged(); | |
return; | |
} | |
var angle:Number = (_ratio * 2.0 - 0.5) * Math.PI; | |
var numSlices:int = sSlices.length; | |
updateVertex(0, 0.5, 0.5); // center point | |
for (var i:int = 1; i < numSlices; ++i) | |
{ | |
var currSlice:Object = sSlices[i]; | |
var prevSlice:Object = sSlices[i - 1]; | |
var nextVertexID:int = i < 6 ? i + 1 : 1; | |
indexData.addTriangle(0, i, nextVertexID); | |
updateVertex(i, prevSlice.u, prevSlice.v); | |
if (_ratio > currSlice.ratio) | |
{ | |
updateVertex(nextVertexID, currSlice.u, currSlice.v); | |
} | |
else | |
{ | |
intersectLineWithSlice(prevSlice.u, prevSlice.v, currSlice.u, currSlice.v, angle, sPoint); | |
updateVertex(nextVertexID, sPoint.x, sPoint.y); | |
break; | |
} | |
} | |
setVertexDataChanged(); | |
} | |
private function updateVertex(vertexID:int, u:Number, v:Number):void | |
{ | |
var x:Number = u; | |
var y:Number = v; | |
var tex:Texture = super.texture; | |
if (tex !== null) | |
{ | |
var frame:Rectangle = tex.frame; | |
if (frame !== null) | |
{ | |
x -= 0.5; | |
y -= 0.5; | |
x *= tex.width / frame.width; | |
y *= tex.height / frame.height;// assume equal aspect | |
x += 0.5; | |
y += 0.5; | |
} | |
tex.setTexCoords(vertexData, vertexID, "texCoords", u, v); | |
} | |
x *= _width; | |
y *= _height; | |
vertexData.setPoint(vertexID, "position", x, y); | |
vertexData.setColor(vertexID, "color", _color); | |
} | |
private function intersectLineWithSlice(ax:Number, ay:Number, bx:Number, by:Number, angle:Number, out:Point = null):Point | |
{ | |
if ((ax == bx) && (ay == by)) return null; // length = 0 | |
var abx:Number = bx - ax; | |
var aby:Number = by - ay; | |
var cdx:Number = Math.cos(angle); | |
var cdy:Number = Math.sin(angle); | |
var tDen:Number = cdy * abx - cdx * aby; | |
if (tDen == 0.0) return null; // parallel or identical | |
out ||= new Point(); | |
var cx:Number = 0.5; | |
var cy:Number = 0.5; | |
var t:Number = (aby * (cx - ax) - abx * (cy - ay)) / tDen; | |
out.x = cx + t * cdx; | |
out.y = cy + t * cdy; | |
return out; | |
} | |
override public function get color():uint { return _color; } | |
override public function set color(value:uint):void { super.color = _color = value; } | |
override public function set texture(value:Texture):void | |
{ | |
if (super.texture === value) | |
return; | |
super.texture = value; | |
updateVertices(); | |
} | |
public function get ratio():Number { return _ratio; } | |
public function set ratio(value:Number):void | |
{ | |
if (_ratio != value) | |
{ | |
_ratio = value; | |
updateVertices(); | |
} | |
} | |
public static function fromTexture(texture:Texture):QuadSection | |
{ | |
var quadPie:QuadSection = new QuadSection(texture.width, texture.height); | |
quadPie.texture = texture; | |
return quadPie; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment