flash – 在绘图对象周围移动符号
我已经将Adobe Illustrator文档中的许多路径导入到Flash文件中.路径在场景中作为绘图对象存在.使用纯动作脚本,如何在不使用预定义动作参考线的情况下在每条线后移动符号.
编辑:我附加了Flash文件,充满了绘图对象. http://rapidshare.com/files/406497264/pather.fla.html 问题是:这些绘图对象是否可以通过AS3访问,或者我应该将它们转换为符号/任何必要的格式.请举几个AS示例. 谢谢! 解决方法
好问题1
我已经看到了工作中的fla,没有cs5回家,但我明白你想要实现的目标. 我的方法是: >运动路径: 从Flash CS4开始,您可以复制路径,并将其粘贴到Motion Tween上.这将类似于Classic Tween的运动指南功能.这有很多问题: >您可能需要手动执行剪切/粘贴 显然这是禁忌. >使用JSFL遍历IDE中的路径: 我偶然发现了这个非常方便的jsfl script by ericlin,它遍历了在舞台上选择的所有形状.如果您选择路径并运行脚本(您只需双击jsfl文件),您将获得解析的坐标. 我使用TweenLite做了一个简单的测试: import com.greensock.*; import com.greensock.easing.*; import com.greensock.plugins.*; TweenPlugin.activate([BezierPlugin]); graphics.lineStyle(0.05); var index:int = 0; var ball:Sprite = new Sprite(); ball.graphics.beginFill(0x009900,.75);ball.graphics.drawCircle(-2,-2,4);ball.graphics.endFill(); addChild(ball); drawLines(); function drawLines():void{ var t:Number = .01; var timeline:TimelineLite = new TimelineLite(); var i:int = index; for(index; index <= ptArray.length; index += 12){ timeline.append( new TweenLite(ball,t,{x:ptArray[i],y:ptArray[i+1]}) ); timeline.append( new TweenLite(ball,{bezier:[{x:ptArray[i+2],y:ptArray[i+3]},{x:ptArray[i+4],y:ptArray[i+5]}]}) ); this.graphics.moveTo(ptArray[i],ptArray[i+1]); this.graphics.curveTo(ptArray[i+2],ptArray[i+3],ptArray[i+4],ptArray[i+5]); i += 6; timeline.append( new TweenLite(ball,ptArray[i+5]); } } *注意:*此处未显示ptArray,因为它会浪费太多空间. >使用AS3SWF在运行时反编译swf并访问形状: Claus Wahlers开发了一个令人惊叹的as3库,名为as3swf,它允许flash / flex开发人员在运行时反编译swfs.这是一个awesome article解释 我刚刚复制了AS3ShapeExporter并将as3 draw命令更改为TweenLite代码.基本上我用快速补间将moveTo替换为使用bezier补间的常规补间和curveTo定位lineTo. Tween Lite的BezierPlugin幸运地使用了二次贝塞尔曲线,就像curveTo一样. 以下是您需要粘贴到包含形状的fla内部的代码: import com.codeazur.as3swf.*; import com.codeazur.as3swf.tags.*; import com.codeazur.as3swf.exporters.*; this.loaderInfo.addEventListener(Event.COMPLETE,completeHandler); function completeHandler(e:Event):void { var swf:SWF = new SWF(this.loaderInfo.bytes);//new SWF(URLLoader(e.target).data as ByteArray); var doc:AS3ShapeTweenLiteExporter = new AS3ShapeTweenLiteExporter(swf,"ball",.01); // Loop over all tags for (var i:uint = 0; i < swf.tags.length; i++) { var tag:ITag = swf.tags[i]; // Check if tag is a DefineShape if (tag is TagDefineShape) { // Export shape tween TagDefineShape(tag).export(doc); } } trace(doc.actionScript); } 基本上我加载了swf,一旦它准备就绪,我将它的字节传递给as3swf并使用AS3ShapeTweenLiteExporter来解析形状标签并吐出actionscript. 这是我的黑客攻击类的样子: package com.codeazur.as3swf.exporters { import com.codeazur.as3swf.SWF; import com.codeazur.utils.StringUtils; import flash.display.CapsStyle; import flash.display.InterpolationMethod; import flash.display.JointStyle; import flash.display.LineScaleMode; import flash.display.SpreadMethod; import flash.geom.Matrix; import com.codeazur.as3swf.exporters.core.DefaultShapeExporter; public class AS3ShapeTweenLiteExporter extends DefaultShapeExporter { protected var _actionScript:String; protected var _target:String; protected var _time:Number; public function AS3ShapeTweenLiteExporter(swf:SWF,target:String,time:Number) { super(swf); _target = target; _time = time; } public function get actionScript():String { return _actionScript; } override public function beginShape():void { _actionScript = "import com.greensock.*;rimport com.greensock.plugins.*;rrTweenPlugin.activate([BezierPlugin]);rrvar shapeTimeline:TimelineLite = new TimelineLite()r"; } override public function beginFills():void { //_actionScript += "// Fills:rgraphics.lineStyle();r"; } override public function beginLines():void { //_actionScript += "// Lines:r"; } override public function beginFill(color:uint,alpha:Number = 1.0):void { if (alpha != 1.0) { _actionScript += StringUtils.printf("graphics.beginFill(0x%06x,%f);r",color,alpha); } else { _actionScript += StringUtils.printf("graphics.beginFill(0x%06x);r",color); } } override public function beginGradientFill(type:String,colors:Array,alphas:Array,ratios:Array,matrix:Matrix = null,spreadMethod:String = SpreadMethod.PAD,interpolationMethod:String = InterpolationMethod.RGB,focalPointRatio:Number = 0):void { var asMatrix:String = "null"; if (matrix != null) { asMatrix = "new Matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.tx + "," + matrix.ty + ")"; } var asColors:String = ""; for (var i:uint = 0; i < colors.length; i++) { asColors += StringUtils.printf("0x%06x",colors[i]); if (i < colors.length - 1) { asColors += ","; } } if (focalPointRatio != 0.0) { _actionScript += StringUtils.printf("graphics.beginGradientFill('%s',[%s],%s,'%s',%s);r",type,asColors,alphas.join(","),ratios.join(",asMatrix,spreadMethod,interpolationMethod,focalPointRatio.toString()); } else if (interpolationMethod != InterpolationMethod.RGB) { _actionScript += StringUtils.printf("graphics.beginGradientFill('%s','%s'r);",interpolationMethod); } else if (spreadMethod != SpreadMethod.PAD) { _actionScript += StringUtils.printf("graphics.beginGradientFill('%s','%s');r",spreadMethod); } else if (matrix != null) { _actionScript += StringUtils.printf("graphics.beginGradientFill('%s',asMatrix); } else { _actionScript += StringUtils.printf("graphics.beginGradientFill('%s',[%s]);r",")); } } override public function beginBitmapFill(bitmapId:uint,repeat:Boolean = true,smooth:Boolean = false):void { var asMatrix:String = "null"; if (matrix != null) { asMatrix = "new Matrix(" + matrix.a + "," + matrix.ty + ")"; } if (smooth) { _actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d,bitmapId,repeat,smooth); } else if (!repeat) { _actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d,repeat); } else { _actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d,asMatrix); } } override public function endFill():void { _actionScript += "graphics.endFill();r"; } override public function lineStyle(thickness:Number = NaN,color:uint = 0,alpha:Number = 1.0,pixelHinting:Boolean = false,scaleMode:String = LineScaleMode.NORMAL,startCaps:String = null,endCaps:String = null,joints:String = null,miterLimit:Number = 3):void { /* if (miterLimit != 3) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,0x%06x,%f,thickness,alpha,pixelHinting.toString(),(scaleMode == null ? "null" : "'" + scaleMode + "'"),(startCaps == null ? "null" : "'" + startCaps + "'"),(joints == null ? "null" : "'" + joints + "'"),miterLimit); } else if (joints != null && joints != JointStyle.ROUND) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,"'" + joints + "'"); } else if(startCaps != null && startCaps != CapsStyle.ROUND) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,"'" + startCaps + "'"); } else if(scaleMode != LineScaleMode.NORMAL) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,(scaleMode == null ? "null" : "'" + scaleMode + "'")); } else if(pixelHinting) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,pixelHinting.toString()); } else if(alpha != 1.0) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,alpha); } else if(color != 0) { _actionScript += StringUtils.printf("graphics.lineStyle(%f,0x%06x);r",color); } else if(!isNaN(thickness)) { _actionScript += StringUtils.printf("graphics.lineStyle(%f);r",thickness); } else { _actionScript += "graphics.lineStyle();r"; } */ } override public function moveTo(x:Number,y:Number):void { //_actionScript += StringUtils.printf("graphics.moveTo(%f,x,y); //_actionScript += StringUtils.printf(_target+".x = %f;r"+_target+".y = %f;r",y); _actionScript += StringUtils.printf("shapeTimeline.append(new TweenLite("+_target+",0.001,{x:%f,y: %f}));r",y); } override public function lineTo(x:Number,y:Number):void { //_actionScript += StringUtils.printf("graphics.lineTo(%f,"+_time+",y); } override public function curveTo(controlX:Number,controlY:Number,anchorX:Number,anchorY:Number):void { //_actionScript += StringUtils.printf("graphics.curveTo(%f,controlX,controlY,anchorX,anchorY); _actionScript += StringUtils.printf("shapeTimeline.append(new TweenLite("+_target+",{bezier:[{x:%f,y: %f},y: %f}]}));r",anchorY); } } } 下载as3swf后,需要将此类保存在导出程序包中. 这是一个纯粹的动作版本,并且结果不错. 动画看起来很生涩,因为它使用相同的时间量来补间每个线段.有些较短,有些较长.您可以存储先前的位置并将其与当前位置一起使用来计算距离,并根据该位置为每个TweenLite实例生成一个体面. 更新 我有时间再修补一下. 更新的时间线代码: import com.codeazur.as3swf.*; import com.codeazur.as3swf.tags.*; import com.codeazur.as3swf.exporters.*; this.loaderInfo.addEventListener(Event.COMPLETE,1,300); // Loop over all tags for (var i:uint = 0; i < swf.tags.length; i++) { var tag:ITag = swf.tags[i]; // Check if tag is a DefineShape if (tag is TagDefineShape) { // Export shape tween TagDefineShape(tag).export(doc); } } trace(doc.actionScript); System.setClipboard(doc.actionScript); } updated exporter: 再次,随时修补. 更新2: 好的,这是另一种方法…… >使用AS3解析直接从Illustrator导出的FXG: 从Illustrator CS4开始,您可以通过文件>将图形保存为FXG.保存副本>选择FXG文件类型 日本再做一次:) 所以第一步是下载库: svn export http://www.libspark.org/svn/as3/FxgParser 您可以使用该示例,因为您使用的是Flash CS5.解析器使用TLF作为文本.我没有费心下载整个flex4 sdk以获得swc和设置.我刚刚注释了Text解析器,因为我们关注路径.注释掉的课程位于底部. 该库包含一个Path解析器,它被克隆并修改以获得一些动画代码:PathTween.as > ID – 是静态的,是解析的Path数量的计数器,这意味着我们可以单独为每个路径设置动画 此外,我已经做了一个quickfix,添加了一个默认的绕组,因为有时,.fxg文件中可能缺少winding属性并且会破坏解析器. 为了使用,您需要对FxgFactory.as进行微小更改,以便它使用PathTween解析器而不是默认的Path类. private static const PARSERS:Array = [ Graphic,Group,Library,Path,Ellipse,Rect,Line,BitmapGraphic,BitmapImage,TextGraphic,RichText ]; 变为: private static const PARSERS:Array = [ Graphic,PathTweenTracer,RichText ]; 最后,一些使用所有这些的基本时间轴代码: import fxgparser.* import fxgparser.parser.*; var fxgurl:String = "fingerprint.fxg"; var fxgSprite:FxgDisplay; var loader:URLLoader = new URLLoader( new URLRequest( fxgurl ) ); loader.addEventListener( Event.COMPLETE,displayData ); //some setup PathTween.MAX_DISTANCE = 360;//change this to fit your shape's largest dimension(width || height) PathTween.TIME = 2;//change this to your needs PathTween.TARGET = "ball";//a name of a target clip that will be incremented for each move,line,curve function displayData( e:Event ):void { var fxgxml:XML = XML( e.currentTarget.data ); fxgSprite = new FxgDisplay( fxgxml ); //parse SVG System.setClipboard(PathTween.CODE); //make some clips for the tester trace(getClips()); addChild( fxgSprite ); } function getClips():String { var result:String = 'this.filters = [new GlowFilter(0x00ff99)]r'; var clipsNum:int = PathTween.ID; var target:String = PathTween.TARGET; for(var i:int = 0 ; i < clipsNum ; i++) result += 'var '+(target+i)+':Sprite = new Sprite();r'+(target+i)+'.graphics.beginFill(0x00ff00);r'+(target+i)+'.graphics.drawCircle(-2,4);r'+(target+i)+'.graphics.endFill();raddChild('+(target+i)+');r'; return result; } 这很简单: >在PathTween中设置常量 然后我打开了一个新的fla文件: >粘贴已经在剪贴板中的剪辑(几千行代码) 你可以看到result并获得fla. 到目前为止,as3swf很酷,一旦你准备好粘贴插画路径, >您跳过粘贴的步骤 这实际上很有趣,有个别的时间表,所以我制作了另一个副本,吸引了一些 Here是PathTweenTracer类,与前一个类一样,将它放在解析器包中. private static const PARSERS:Array = [ Graphic,RichText ]; timeline代码几乎相同. 以下是生成的动画的一些屏幕截图: TextGraphic.as注释掉 FXG方法更适合这个问题(‘使用纯动作脚本,如何在不使用预定义的运动参考线的情况下在每条线后移动符号?’) 至于嵌套问题(‘这些绘图对象是否可以通过AS3访问,或者我应该将它们转换为符号/任何必要的格式?’): 正如@Casey所提到的,一旦设置完就无法访问图形.使用更新的Graphics API,您可以将图形从一个Graphics实例复制到另一个,但不会公开命令.我记得Tink在Flash Player 10之前有something方式,但我不知道它的进展是什么. HTH (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |