251 lines
7.6 KiB
Haxe
251 lines
7.6 KiB
Haxe
/**
|
|
* FlxGradient
|
|
* -- Part of the Flixel Power Tools set
|
|
*
|
|
* v1.6 Fixed bug where gradients with chunk sizes>1 would ignore alpha values
|
|
* v1.5 Alpha values used in the gradient map
|
|
* v1.4 Updated for the Flixel 2.5 Plugin system
|
|
*
|
|
* @version 1.6 - May 9th 2011
|
|
* @link http://www.photonstorm.com
|
|
* @author Richard Davey / Photon Storm
|
|
* @see Requires FlxMath
|
|
*/
|
|
|
|
package org.flixel.plugin.photonstorm
|
|
{
|
|
import flash.geom.Point;
|
|
import flash.geom.Rectangle;
|
|
import org.flixel.*;
|
|
|
|
import flash.display.Bitmap;
|
|
import flash.geom.Matrix;
|
|
import flash.display.BitmapData;
|
|
import flash.display.Shape;
|
|
import flash.display.GradientType;
|
|
import flash.display.SpreadMethod;
|
|
import flash.display.InterpolationMethod;
|
|
|
|
/**
|
|
* Adds a set of color gradient creation / rendering functions
|
|
*/
|
|
class FlxGradient
|
|
{
|
|
|
|
public function new()
|
|
{
|
|
}
|
|
|
|
public static function createGradientMatrix(width:Int, height:Int, colors:Array, chunkSize:Int=1, rotation:Int=90):Dynamic
|
|
{
|
|
var gradientMatrix:Matrix=new Matrix();
|
|
|
|
// Rotation(in radians)that the gradient is rotated
|
|
var rot:Float=FlxMath.asRadians(rotation);
|
|
|
|
// Last 2 values=horizontal and vertical shift(in pixels)
|
|
if(chunkSize==1)
|
|
{
|
|
gradientMatrix.createGradientBox(width, height, rot, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
gradientMatrix.createGradientBox(width, height / chunkSize, rot, 0, 0);
|
|
}
|
|
|
|
// Create the alpha and ratio arrays
|
|
|
|
var alpha:Array<Dynamic>=new Array();
|
|
|
|
for(ai in 0...colors.length)
|
|
{
|
|
alpha.push(FlxColor.getAlphaFloat(colors[ai]));
|
|
}
|
|
|
|
var ratio:Array<Dynamic>=new Array();
|
|
|
|
if(colors.length==2)
|
|
{
|
|
ratio[0]=0;
|
|
ratio[1]=255;
|
|
}
|
|
else
|
|
{
|
|
// Spread value
|
|
var spread:Int=255 /(colors.length - 1);
|
|
|
|
ratio.push(0);
|
|
|
|
for(ri in 1...colors.length - 1)
|
|
{
|
|
ratio.push(ri * spread);
|
|
}
|
|
|
|
ratio.push(255);
|
|
}
|
|
|
|
return { matrix:gradientMatrix, alpha:alpha, ratio:ratio };
|
|
}
|
|
|
|
public static function createGradientArray(width:Int, height:Int, colors:Array, chunkSize:Int=1, rotation:Int=90, Interpolate:Bool=true):Array
|
|
{
|
|
var data:BitmapData=createGradientBitmapData(width, height, colors, chunkSize, rotation, Interpolate);
|
|
|
|
var result:Array<Dynamic>=new Array();
|
|
|
|
for(y in 0...data.height)
|
|
{
|
|
result.push(data.getPixel32(0, y));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an FlxSprite of the given width/height with a colour gradient flowing through it.
|
|
*
|
|
* @param width The width of the FlxSprite(and therefore gradient)
|
|
* @param height The height of the FlxSprite(and therefore gradient)
|
|
* @param colors An array of colour values for the gradient to cycle through
|
|
* @param chunkSize If you want a more old-skool looking chunky gradient, increase this value!
|
|
* @param rotation Angle of the gradient in degrees. 90=top to bottom, 180=left to right. Any angle is valid
|
|
* @param interpolate Interpolate the colours? True uses RGB Interpolation, false uses linear RGB
|
|
*
|
|
* @return An FlxSprite containing your gradient(if valid parameters given!)
|
|
*/
|
|
public static function createGradientFlxSprite(width:Int, height:Int, colors:Array, chunkSize:Int=1, rotation:Int=90, Interpolate:Bool=true):FlxSprite
|
|
{
|
|
var data:BitmapData=createGradientBitmapData(width, height, colors, chunkSize, rotation, Interpolate);
|
|
|
|
var dest:FlxSprite=new FlxSprite().makeGraphic(width, height);
|
|
|
|
dest.pixels=data;
|
|
|
|
return dest;
|
|
}
|
|
|
|
public static function createGradientBitmapData(width:Int, height:Int, colors:Array, chunkSize:Int=1, rotation:Int=90, Interpolate:Bool=true):BitmapData
|
|
{
|
|
// Sanity checks
|
|
if(width<1)
|
|
{
|
|
width=1;
|
|
}
|
|
|
|
if(height<1)
|
|
{
|
|
height=1;
|
|
}
|
|
|
|
var gradient:Dynamic=createGradientMatrix(width, height, colors, chunkSize, rotation);
|
|
|
|
var s:Shape=new Shape();
|
|
|
|
if(interpolate)
|
|
{
|
|
s.graphics.beginGradientFill(GradientType.LINEAR, colors, gradient.alpha, gradient.ratio, gradient.matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
|
|
}
|
|
else
|
|
{
|
|
s.graphics.beginGradientFill(GradientType.LINEAR, colors, gradient.alpha, gradient.ratio, gradient.matrix, SpreadMethod.PAD, InterpolationMethod.LINEAR_RGB, 0);
|
|
}
|
|
|
|
if(chunkSize==1)
|
|
{
|
|
s.graphics.drawRect(0, 0, width, height);
|
|
}
|
|
else
|
|
{
|
|
s.graphics.drawRect(0, 0, width, height / chunkSize);
|
|
}
|
|
|
|
var data:BitmapData=new BitmapData(width, height, true, 0x0);
|
|
|
|
if(chunkSize==1)
|
|
{
|
|
data.draw(s);
|
|
}
|
|
else
|
|
{
|
|
var tempBitmap:Bitmap=new Bitmap(new BitmapData(width, height / chunkSize, true, 0x0));
|
|
tempBitmap.bitmapData.draw(s);
|
|
tempBitmap.scaleY=chunkSize;
|
|
|
|
var sM:Matrix=new Matrix();
|
|
sM.scale(tempBitmap.scaleX, tempBitmap.scaleY);
|
|
|
|
data.draw(tempBitmap, sM);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Creates a new gradient and overlays that on-top of the given FlxSprite at the destX/destY coordinates(default 0,0)<br />
|
|
* Use low alpha values in the colours to have the gradient overlay and not destroy the image below
|
|
*
|
|
* @param dest The FlxSprite to overlay the gradient onto
|
|
* @param width The width of the FlxSprite(and therefore gradient)
|
|
* @param height The height of the FlxSprite(and therefore gradient)
|
|
* @param colors An array of colour values for the gradient to cycle through
|
|
* @param destX The X offset the gradient is drawn at(default 0)
|
|
* @param destY The Y offset the gradient is drawn at(default 0)
|
|
* @param chunkSize If you want a more old-skool looking chunky gradient, increase this value!
|
|
* @param rotation Angle of the gradient in degrees. 90=top to bottom, 180=left to right. Any angle is valid
|
|
* @param interpolate Interpolate the colours? True uses RGB Interpolation, false uses linear RGB
|
|
* @return The composited FlxSprite(for chaining, if you need)
|
|
*/
|
|
public static function overlayGradientOnFlxSprite(dest:FlxSprite, width:Int, height:Int, colors:Array, destX:Int=0, destY:Int=0, chunkSize:Int=1, rotation:Int=90, Interpolate:Bool=true):FlxSprite
|
|
{
|
|
if(width>dest.width)
|
|
{
|
|
width=dest.width;
|
|
}
|
|
|
|
if(height>dest.height)
|
|
{
|
|
height=dest.height;
|
|
}
|
|
|
|
var source:FlxSprite=createGradientFlxSprite(width, height, colors, chunkSize, rotation, Interpolate);
|
|
|
|
dest.stamp(source, destX, destY);
|
|
|
|
return dest;
|
|
}
|
|
|
|
/**
|
|
* Creates a new gradient and overlays that on-top of the given BitmapData at the destX/destY coordinates(default 0,0)<br />
|
|
* Use low alpha values in the colours to have the gradient overlay and not destroy the image below
|
|
*
|
|
* @param dest The BitmapData to overlay the gradient onto
|
|
* @param width The width of the FlxSprite(and therefore gradient)
|
|
* @param height The height of the FlxSprite(and therefore gradient)
|
|
* @param colors An array of colour values for the gradient to cycle through
|
|
* @param destX The X offset the gradient is drawn at(default 0)
|
|
* @param destY The Y offset the gradient is drawn at(default 0)
|
|
* @param chunkSize If you want a more old-skool looking chunky gradient, increase this value!
|
|
* @param rotation Angle of the gradient in degrees. 90=top to bottom, 180=left to right. Any angle is valid
|
|
* @param interpolate Interpolate the colours? True uses RGB Interpolation, false uses linear RGB
|
|
* @return The composited BitmapData
|
|
*/
|
|
public static function overlayGradientOnBitmapData(dest:BitmapData, width:Int, height:Int, colors:Array, destX:Int=0, destY:Int=0, chunkSize:Int=1, rotation:Int=90, Interpolate:Bool=true):BitmapData
|
|
{
|
|
if(width>dest.width)
|
|
{
|
|
width=dest.width;
|
|
}
|
|
|
|
if(height>dest.height)
|
|
{
|
|
height=dest.height;
|
|
}
|
|
|
|
var source:BitmapData=createGradientBitmapData(width, height, colors, chunkSize, rotation, Interpolate);
|
|
|
|
dest.copyPixels(source, new Rectangle(0, 0, source.width, source.height), new Point(destX, destY), null, null, true);
|
|
|
|
return dest;
|
|
}
|
|
|
|
} |