flash – 在绘图对象周围移动符号

前端之家收集整理的这篇文章主要介绍了flash – 在绘图对象周围移动符号前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经将Adobe Illustrator文档中的许多路径导入到Flash文件中.路径在场景中作为绘图对象存在.使用纯动作脚本,如何在不使用预定义动作参考线的情况下在每条线后移动符号.

编辑:我附加了Flash文件,充满了绘图对象.

http://rapidshare.com/files/406497264/pather.fla.html

问题是:这些绘图对象是否可以通过AS3访问,或者我应该将它们转换为符号/任何必要的格式.请举几个AS示例.

谢谢!

解决方法

好问题1

我已经看到了工作中的fla,没有cs5回家,但我明白你想要实现的目标.

我的方法是:

>运动路径:

从Flash CS4开始,您可以复制路径,并将其粘贴到Motion Tween上.这将类似于Classic Tween的运动指南功能.这有很多问题:

>您可能需要手动执行剪切/粘贴
>并非所有路径都可以粘贴到动画上
>您可以使用AnimationFactory类并添加目标,但问题是,而
目标是动画,你没有动作控制它.您可以设置计时器
对于AnimationFactory的动作持续时间,但它变得麻烦.

显然这是禁忌.

>使用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,因为它会浪费太多空间.
result并不是那么好.你可以看看fla,看看我的意思.
jsfl脚本可能会被更改,但我看到你强调了actionscript的用法,所以这也是不行的.

>使用AS3SWF在运行时反编译swf并访问形状:

Claus Wahlers开发了一个令人惊叹的as3库,名为as3swf,它允许flash / flex开发人员在运行时反编译swfs.这是一个awesome article解释
swfs内部形状的来龙去脉.已经写了很多exporters.

我刚刚复制了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.
我传递给构造函数的3个参数是:swf实例,补间目标的名称和每个补间的时间.

这是我的黑客攻击类的样子:

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.*;\r\rTweenPlugin.activate([BezierPlugin]);\r\rvar 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后,需要将此类保存在导出程序包中.
这是result.你可以下载它的fla以及生成代码fla.

这是一个纯粹的动作版本,并且结果不错.

动画看起来很生涩,因为它使用相同的时间量来补间每个线段.有些较短,有些较长.您可以存储先前的位置并将其与当前位置一起使用来计算距离,并根据该位置为每个TweenLite实例生成一个体面.
也可以随心所欲地修改该类(比如你想使用Timer等)

更新

我有时间再修补一下.
我稍微更改了导出器,现在它还期望目标对象的最大距离.这将是选择的宽度或高度(所有线条),具体取决于哪一个更大(宽度与高度).存储先前的x和y值
并用于计算距离,然后该距离除以最大行程距离.这反过来用于缩放每个补间的时间.此外,我已将缓动设置为线性,因为默认(Quad.eaSEOut)添加到抖动中.时间不是很准确,但看起来是a bit better.更新了fla的herehere

更新的时间线代码

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文件类型
这是我使用的fxg file.

日本再做一次:)
惊人的Lib Spark包含一个FXG Parser.还有一个SVGParser,但是现在我只玩fxg.

所以第一步是下载库:

svn export http://www.libspark.org/svn/as3/FxgParser

您可以使用该示例,因为您使用的是Flash CS5.解析器使用TLF作为文本.我没有费心下载整个flex4 sdk以获得swc和设置.我刚刚注释了Text解析器,因为我们关注路径.注释掉的课程位于底部.

该库包含一个Path解析器,它被克隆并修改以获得一些动画代码PathTween.as
您可能会认识到as3swf类中的一些变量.
以下是我添加的一些变量的一些解释:

> ID – 是静态的,是解析的Path数量的计数器,这意味着我们可以单独为每个路径设置动画
> CODE – static,包含每个路径实例的时间轴lite代码的导入代码,这是代码:)
> MAX_DISTANCE – 类似于as3swf方法,用于根据行进距离改变每个补间的时间
> TIME – 每个补间的通用时间,方便从课外设置
> TARGET – 将为每个路径递增的名称,并用作补间目标.
> _code,_distance,_x,_y,_timeScale – 与as3swf方法相同
> _timeRel – 每次的相对时间(例如,在调整之后)

此外,我已经做了一个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中设置常量
>加载fxg
>一旦装好,就画出来.在绘图时,代码后台生成
>一旦绘制完毕,将代码放入剪贴板.对于我的路径,我有大约11K的生成线,因此跟踪在这里不是一个好主意
>也只保留PathTween中的补间代码,我生成一些代码(getClips())来制作目标影片剪辑.您可以根据需要随意在PathTween中添加此类功能.

然后我打开了一个新的fla文件

>粘贴已经在剪贴板中的剪辑(几千行代码)
>从“输出面板”复制代码并在“TweenPlugin.activate([BezierPlugin]);”之后粘贴它

你可以看到result并获得fla.

到目前为止,as3swf很酷,一旦你准备好粘贴插画路径,
可能会更快,因为as3swf使用字节.
我喜欢FXG方法

>您跳过粘贴的步骤
图形成fla,你只需保存一个
复制为FXG.你可以用一个fla来
只需生成所需的所有代码
更改fxg文件的路径
想要动画.
>每个路径都是单独解析的,因此更灵活一些.
>虽然它产生的代码比as3swf版本,立方贝塞尔曲线,弧线更多
和其他曲线分解为lineTo命令,这些命令使动画均匀一点.

这实际上很有趣,有个别的时间表,所以我制作了另一个副本,吸引了一些
俗气的痕迹成为位图数据.

Here是PathTweenTracer类,与前一个类一样,将它放在解析器包中.
同样,需要在FxgFactory中更新PARSERS常量:

private static const PARSERS:Array = [  Graphic,RichText ];

timeline代码几乎相同.
result看起来不错(source)

以下是生成的动画的一些屏幕截图:

fxg anim 1

fxg anim 2

fxg anim 3

TextGraphic.as注释掉

FXG方法更适合这个问题(‘使用纯动作脚本,如何在不使用预定义的运动参考线的情况下在每条线后移动符号?’)

至于嵌套问题(‘这些绘图对象是否可以通过AS3访问,或者我应该将它们转换为符号/任何必要的格式?’):

正如@Casey所提到的,一旦设置完就无法访问图形.使用更新的Graphics API,您可以将图形从一个Graphics实例复制到另一个,但不会公开命令.我记得Tink在Flash Player 10之前有something方式,但我不知道它的进展是什么.

HTH

猜你在找的Flash相关文章