10
2015
09

fxg转as

看到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
	}

}

效果如下,请点击确定按钮:

获得 Adobe Flash Player

使用方法:将fxg文件中Path上一级的Group复制到确定按钮上面的文本框中,需要手动把把flm:isDrawingObject="false"去掉,然后点击确定按钮,按钮下面的文本框中将输出用graphics画图的代码,并且会在舞台上画出对应的图形。


源码打包下载

« 上一篇下一篇 »

相关文章:

闪电效果  (2017-11-28 15:4:19)

线段与椭圆的交点  (2017-1-6 14:43:41)

as3录制swf并保存flv视频  (2016-12-28 8:43:41)

解九连环  (2016-12-1 20:58:11)

as3实现setTimeout和trace  (2016-11-10 16:47:37)

registerCursor注册系统光标  (2016-9-14 9:49:40)

鼠标光标管理  (2016-9-13 17:44:3)

变形框(transform)实现  (2016-9-13 16:56:6)

flash文本消除锯齿不显示  (2016-8-25 11:43:31)

greenSock的easing曲线  (2016-8-24 18:30:11)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。