看到Transformmanager里边的光标都是用graphics画出来的,不知道人家是怎么做到的,虽然无非是划线+填充,但是用完全代码实现,我是做不到的。
我在想,是否能在flash中画好矢量图,导出fxg文件,然后根据fxg文件的内容,自动生成graphics画图的代码呢?
经过一天的努力,确实可行。
代码如下:
Main.as
package
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.TextField;
public class Main extends MovieClip
{
public var inputTf:TextField;
public var outputTf:TextField;
public var btn:SimpleButton;
public var tf:TextField;
private var con:Sprite;
public function Main()
{
con = new Sprite();
addChildAt(con,0);
inputTf.text = xml.toXMLString();
outputTf.selectable = true;
btn.addEventListener(MouseEvent.CLICK, start);
}
private function start(e:MouseEvent):void
{
var xml:XML = XML(inputTf.text);
var g:Group = new Group(XML(inputTf.text));
if (tf.text=="") {
while (con.numChildren) {
con.removeChildAt(0);
}
}
con.addChild(g);
var code:String = g.code;
outputTf.text = code;
trace(code);
}
//end functions
}
}
Group.as
package
{
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.text.TextField;
public class Group extends Sprite
{
public var code:String;
public function Group(xml:XML)
{
// constructor code
start(xml);
}
public function start(xml:XML):void
{
try
{
graphics.clear();
code = fxg2as(xml);
code += groupParam(xml, "rotation");
code += groupParam(xml, "x");
code += groupParam(xml, "y");
code += groupParam(xml, "scaleX");
code += groupParam(xml, "scaleY");
}
catch (e:Error)
{
code = "" + e;
}
}
function groupParam(xml:XML, par:String):String {
var s:String = "";
if (xml["@" + par].length()) {
this[par] = xml["@" + par];
s += par + " = " + this[par]+";\n";
}
return s;
}
/**
* fxg格式转换为as用graphic画图的代码
* @param xml
* @return
*/
private function fxg2as(xml:XML):String
{
var s:String = "";
s += "var matrix:Matrix;\n";
var pathList:XMLList = xml.Path;
var len:int = pathList.length();
for (var i:int = 0; i < len; i++)
{
var path:XML = pathList[i];
//
if (path.fill.length())
{
//trace("----------fill--------------");
var fill:XML = path.fill[0];
if (fill.SolidColor.length())
{
s += solidFill(graphics, fill.SolidColor[0]);
}
else if (fill.RadialGradient.length())
{
s += gradientFill(graphics, GradientType.RADIAL, fill.RadialGradient[0]);
}
else if (fill.LinearGradient.length())
{
s += gradientFill(graphics, GradientType.LINEAR, fill.LinearGradient[0]);
}
}
else if (path.stroke.length())
{
//trace("----------stroke--------------");
var stroke:XML = path.stroke[0];
if (stroke.SolidColorStroke.length())
{
s += solidStroke(graphics, stroke.SolidColorStroke[0]);
}
else if (stroke.RadialGradientStroke.length())
{
s += gradientStroke(graphics, GradientType.RADIAL, stroke.RadialGradientStroke[0]);
}
else if (stroke.LinearGradientStroke.length())
{
s += gradientStroke(graphics, GradientType.LINEAR, stroke.LinearGradientStroke[0]);
}
}
//
var data:String = path.@data;
s += drawData(graphics, data);
} //end for
return s;
}
/**
*
* @param graphics
* @param date
*/
private function drawData(graphics:Graphics, data:String):String
{
var s:String = "";
var arr:Array = formatData(data);
var len:int = arr.length;
var startP:Array = [];
var lastP:Array = [];
var rf:Array = [];
var lc:String = "";
for (var i:int = 0; i < len; i++)
{
var cc:String = arr[i];
var n:uint = 1;
while (n)
{
n--;
switch (cc)
{
case "M":
graphics.moveTo(arr[i + 1], arr[i + 2]);
startP[0] = arr[i + 1];
startP[1] = arr[i + 2];
lastP[0] = arr[i + 1];
lastP[1] = arr[i + 2];
s += "graphics.moveTo(" + arr[i + 1] + "," + arr[i + 2] + ");";
s += "\n";
i += 2;
lc = "L";
break;
case "L":
graphics.lineTo(arr[i + 1], arr[i + 2]);
lastP[0] = arr[i + 1];
lastP[1] = arr[i + 2];
s += "graphics.lineTo(" + lastP[0] + "," + lastP[1] + ");";
s += "\n";
i += 2;
lc = "L";
break;
case "Q":
graphics.curveTo(arr[i + 1], arr[i + 2], arr[i + 3], arr[i + 4]);
rf[0] = arr[i + 1];
rf[1] = arr[i + 2];
lastP[0] = arr[i + 3];
lastP[1] = arr[i + 4];
s += "graphics.curveTo(" + arr[i + 1] + "," + arr[i + 2] + "," + arr[i + 3] + "," + arr[i + 4] + ");";
s += "\n";
i += 4;
lc = "Q";
break;
case "C":
graphics.cubicCurveTo(arr[i + 1], arr[i + 2], arr[i + 3], arr[i + 4], arr[i + 5], arr[i + 6]);
rf[0] = arr[i + 3];
rf[1] = arr[i + 4];
lastP[0] = arr[i + 5];
lastP[1] = arr[i + 6];
s += "graphics.cubicCurveTo(" + arr[i + 1] + "," + arr[i + 2] + "," + arr[i + 3] + "," + arr[i + 4] + "," + arr[i + 5] + "," + arr[i + 6] + ");";
s += "\n";
i += 6;
lc = "C";
break;
case "Z":
graphics.lineTo(startP[0], startP[1]);
lastP[0] = startP[0];
lastP[1] = startP[1];
s += "graphics.lineTo(" + lastP[0] + "," + lastP[1] + ");";
s += "\n";
lc = "Z";
break;
case "H":
graphics.lineTo(arr[i + 1], lastP[1]);
lastP[0] = arr[i + 1];
s += "graphics.lineTo(" + lastP[0] + "," + lastP[1] + ");";
s += "\n";
i += 1;
lc = "H";
break;
case "V":
graphics.lineTo(lastP[0], arr[i + 1]);
lastP[1] = arr[i + 1];
s += "graphics.lineTo(" + lastP[0] + "," + lastP[1] + ");";
s += "\n";
i += 1;
lc = "V";
break;
case "T":
rf[0] = lastP[0] * 2 - rf[0];
rf[1] = lastP[1] * 2 - rf[1];
graphics.curveTo(rf[0], rf[1], arr[i + 1], arr[i + 2]);
lastP[0] = arr[i + 1];
lastP[1] = arr[i + 2];
s += "graphics.curveTo(" + rf[0] + "," + rf[1] + "," + arr[i + 1] + "," + arr[i + 2] + ");";
s += "\n";
i += 2;
lc = "T";
break;
case "S":
rf[0] = lastP[0] * 2 - rf[0];
rf[1] = lastP[1] * 2 - rf[1];
graphics.cubicCurveTo(rf[0], rf[1], arr[i + 1], arr[i + 2], arr[i + 3], arr[i + 4]);
rf[0] = arr[i + 1];
rf[1] = arr[i + 2];
lastP[0] = arr[i + 3];
lastP[1] = arr[i + 4];
s += "graphics.cubicCurveTo(" + rf[0] + "," + rf[1] + "," + arr[i + 1] + "," + arr[i + 2] + "," + arr[i + 3] + "," + arr[i + 4] + ");";
s += "\n";
i += 4;
lc = "S";
break;
default:
cc = lc;
i--;
n++;
break;
}
}
}
graphics.endFill();
s += "graphics.endFill();";
return s + "\n";
}
/**
*
* @param data
* @return
*/
private function formatData(data:String):Array
{
var arr:Array = [];
data = data.toUpperCase();
var c:Array = ["Z", "C", "S", "H", "L", "M", "Q", "T", "V"];
var i:int;
var j:int;
var s:String = "";
for (i = 0; i < data.length; i++)
{
var f:Boolean = false;
var char:String = data.charAt(i);
for (j = 0; j < c.length; j++)
{
if (char == c[j])
{
f = true;
break;
}
}
if (f)
{
s += " " + char + " ";
}
else
{
s += char;
}
}
var la:Array = s.split(" ");
for (i = 0; i < la.length; i++)
{
if (la[i])
arr.push(la[i]);
}
return arr;
}
/**
* 单色填充
* @param g
* @param SolidColor
*/
private function solidFill(g:Graphics, SolidColor:XML):String
{
var color:uint = 0x000000;
var alpha:Number = 1.0;
//SolidColor.@color居然是XMLList, typeof XMLList居然是xml
if (SolidColor.@color.length())
color = formatColor(SolidColor.@color);
if (SolidColor.@alpha.length())
alpha = Number(SolidColor.@alpha);
graphics.beginFill(color, alpha);
var s:String = "";
s += "graphics.beginFill(" + color.toString(16) + "," + alpha + ");";
return s + "\n";
}
/**
* 渐变填充
* @param g
* @param type
* @param GradientXML
*/
private function gradientFill(g:Graphics, type:String, GradientXML:XML):String
{
var colors:Array = [];
var alphas:Array = [];
var ratios:Array = [];
var matrix:Matrix = new Matrix();
var GradientEntryList:XMLList = GradientXML.GradientEntry;
var len:int = GradientEntryList.length();
for (var i:int = 0; i < len; i++)
{
var GradientEntry:XML = GradientEntryList[i];
colors[i] = GradientEntry.@color.length() ? formatColor(GradientEntry.@color) : 0x000000;
alphas[i] = GradientEntry.@alpha.length() ? Number(GradientEntry.@alpha) : 1;
ratios[i] = Number(GradientEntry.@ratio) * 255;
}
var tx:Number = GradientXML.@x.length() ? Number(GradientXML.@x) : 0;
var ty:Number = GradientXML.@y.length() ? Number(GradientXML.@y) : 0;
var r:Number = GradientXML.@rotation.length() ? Number(GradientXML.@rotation) : 0;
var w:Number = GradientXML.@scaleX.length() ? Number(GradientXML.@scaleX) : 0;
var h:Number = GradientXML.@scaleY.length() ? Number(GradientXML.@scaleY) : 0;
r = r * Math.PI / 180;
if (type == GradientType.LINEAR)
{
h = w;
matrix.tx = tx+w*Math.cos(r)/2;
matrix.ty = ty+w*Math.sin(r)/2;
}
else {
matrix.tx = tx;
matrix.ty = ty;
}
//---------------不知道为什么--------------
matrix.a = Math.cos(r) * w / 1640;
matrix.d = Math.cos(r) * h / 1640;
matrix.b = Math.sin(r) * w / 1640;
matrix.c = -Math.sin(r) * h / 1640;
//-------------------------------
graphics.beginGradientFill(type, colors, alphas, ratios, matrix);
var s:String = "";
s += "matrix = new Matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.tx + "," + matrix.ty + ");";
s += "\n" + "graphics.beginGradientFill('" + type + "'," + formatArray(colors, "color") + "," + formatArray(alphas) + "," + formatArray(ratios) + "," + "matrix" + ");";
return s + "\n";
}
private function formatArray(arr:Array, type:String = "normal"):String
{
var s:String = "";
var i:int;
var len:int = arr.length;
switch (type)
{
case "color":
s += "["
for (i = 0; i < len; i++)
{
var ai:Number = arr[i];
s += "0x" + ai.toString(16);
if (i != len - 1)
s += ",";
}
if (s.length > 1)
{
s += "]";
}
break;
default:
s = "[" + arr + "]";
break;
}
return s;
}
/**
* 单色笔触
* @param g
* @param SolidColorStroke
*/
private function solidStroke(g:Graphics, SolidColorStroke:XML):String
{
var color:uint = SolidColorStroke.@color.length() ? formatColor(SolidColorStroke.@color) : 0x000000;
var alpha:Number = SolidColorStroke.@alpha.length() ? Number(SolidColorStroke.@alpha) : 1.0;
var weight:Number = SolidColorStroke.@weight.length() ? Number(SolidColorStroke.@weight) : 1;
graphics.lineStyle(weight, color, alpha);
var s:String = "";
s += "graphics.lineStyle(" + weight + "," + color.toString(16) + "," + alpha + ");";
return s + "\n";
}
/**
* 渐变笔触
* @param g
* @param type
* @param GradientStrokeXML
*/
private function gradientStroke(g:Graphics, type:String, GradientStrokeXML:XML):String
{
var s:String = "";
s+=solidStroke(graphics, GradientStrokeXML);
var colors:Array = [];
var alphas:Array = [];
var ratios:Array = [];
var matrix:Matrix = new Matrix();
var GradientEntryList:XMLList = GradientStrokeXML.GradientEntry;
var len:int = GradientEntryList.length();
for (var i:int = 0; i < len; i++)
{
var GradientEntry:XML = GradientEntryList[i];
colors[i] = GradientEntry.@color.length() ? formatColor(GradientEntry.@color) : 0x000000;
alphas[i] = GradientEntry.@alpha.length() ? Number(GradientEntry.@alpha) : 1;
ratios[i] = Number(GradientEntry.@ratio) * 255;
}
var tx:Number = GradientStrokeXML.@x.length() ? Number(GradientStrokeXML.@x) : 0;
var ty:Number = GradientStrokeXML.@y.length() ? Number(GradientStrokeXML.@y) : 0;
var r:Number = GradientStrokeXML.@rotation.length() ? Number(GradientStrokeXML.@rotation) : 0;
var w:Number = GradientStrokeXML.@scaleX.length() ? Number(GradientStrokeXML.@scaleX) : 0;
var h:Number = GradientStrokeXML.@scaleY.length() ? Number(GradientStrokeXML.@scaleY) : 0;
r = r * Math.PI / 180;
if (type == GradientType.LINEAR)
{
h = w;
matrix.tx = tx+w*Math.cos(r)/2;
matrix.ty = ty+w*Math.sin(r)/2;
}
else {
matrix.tx = tx;
matrix.ty = ty;
}
//---------------不知道为什么--------------
matrix.a = Math.cos(r) * w / 1640;
matrix.d = Math.cos(r) * h / 1640;
matrix.b = Math.sin(r) * w / 1640;
matrix.c = -Math.sin(r) * h / 1640;
//-------------------------------
graphics.lineGradientStyle(type, colors, alphas, ratios, matrix);
s += "matrix = new Matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.tx + "," + matrix.ty + ");";
s += "\n" + "graphics.lineGradientStyle('" + type + "'," + formatArray(colors, "color") + "," + formatArray(alphas) + "," + formatArray(ratios) + "," + "matrix" + ");";
return s + "\n";
}
/**
* #ff0000格式转成uint
* @param value
* @return
*/
private function formatColor(value:String):uint
{
return uint("0x" + value.substring(1));
}
//end functions
}
}
效果如下,请点击确定按钮:
使用方法:将fxg文件中Path上一级的Group复制到确定按钮上面的文本框中,需要手动把把flm:isDrawingObject="false"去掉,然后点击确定按钮,按钮下面的文本框中将输出用graphics画图的代码,并且会在舞台上画出对应的图形。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。