看到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画图的代码,并且会在舞台上画出对应的图形。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。