我已經從Adobe Illustrator文檔直接導入了很多路徑到一個Flash文件。路徑作爲繪圖對象存在於場景中。使用純粹的動作腳本,如何在每行之後移動一個符號,而無需使用預定義的運動向導。圍繞圖形對象移動符號
編輯:我已附加Flash文件,充滿繪圖對象。
http://rapidshare.com/files/406497264/pather.fla.html
的問題是:通過AS3訪問這些繪圖對象或者我應該將它們轉換爲符號/任何必要的格式。請給出一些AS示例。
謝謝!
我已經從Adobe Illustrator文檔直接導入了很多路徑到一個Flash文件。路徑作爲繪圖對象存在於場景中。使用純粹的動作腳本,如何在每行之後移動一個符號,而無需使用預定義的運動向導。圍繞圖形對象移動符號
編輯:我已附加Flash文件,充滿繪圖對象。
http://rapidshare.com/files/406497264/pather.fla.html
的問題是:通過AS3訪問這些繪圖對象或者我應該將它們轉換爲符號/任何必要的格式。請給出一些AS示例。
謝謝!
尼斯問題+1
我見過在工作中FLA,沒有CS5回家,但我明白你的」重新努力實現。
我的做法是:這些:
由於Flash CS4,您可以複製的路徑,並將其粘貼到補間動畫。這與經典補間動畫指南功能類似。有相當多的問題,這一點:
顯然這是一個禁忌。
使用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, t, {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, t, {x:ptArray[i],y:ptArray[i+1]}));
timeline.append(new TweenLite(ball, t, {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]);
}
}
*注:*本ptArray這裏沒有顯示,因爲它會浪費太多的空間。 result雖然不是那麼好。你可以看看fla看看我的意思。 jsfl腳本可以改變,但我看到你強調了actionscript的用法,所以這是一個不錯的選擇。
Claus Wahlers開發了一個驚人的AS3庫調用as3swf其允許閃光/柔性開發反編譯在運行時swfs。這是一個awesome article,解釋了 swf內部形狀的來龍去脈。已經寫了不少exporters。
我剛剛複製了AS3ShapeExporter,並將as3繪圖命令更改爲TweenLite代碼。基本上,我用一個快速補間來替換moveTo,將lineTo定位到常規補間和curveTo與bezier補間。 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解析形狀標籤並吐出動作。 我傳遞給構造函數的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, '%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], [%s], [%s], %s, '%s', '%s'\r);",
type,
asColors,
alphas.join(","),
ratios.join(","),
asMatrix,
spreadMethod,
interpolationMethod);
} else if (spreadMethod != SpreadMethod.PAD) {
_actionScript += StringUtils.printf("graphics.beginGradientFill('%s', [%s], [%s], [%s], %s, '%s');\r",
type,
asColors,
alphas.join(","),
ratios.join(","),
asMatrix,
spreadMethod);
} else if (matrix != null) {
_actionScript += StringUtils.printf("graphics.beginGradientFill('%s', [%s], [%s], [%s], %s);\r",
type,
asColors,
alphas.join(","),
ratios.join(","),
asMatrix);
} else {
_actionScript += StringUtils.printf("graphics.beginGradientFill('%s', [%s], [%s], [%s]);\r",
type,
asColors,
alphas.join(","),
ratios.join(","));
}
}
override public function beginBitmapFill(bitmapId:uint, matrix:Matrix = null, repeat:Boolean = true, smooth:Boolean = false):void {
var asMatrix:String = "null";
if (matrix != null) {
asMatrix = "new Matrix(" +
matrix.a + "," +
matrix.b + "," +
matrix.c + "," +
matrix.d + "," +
matrix.tx + "," +
matrix.ty + ")";
}
if (smooth) {
_actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d, %s, %s, %s);\r", bitmapId, asMatrix, repeat, smooth);
} else if (!repeat) {
_actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d, %s, %s, %s);\r", bitmapId, asMatrix, repeat);
} else {
_actionScript += StringUtils.printf("// graphics.beginBitmapFill(%d, %s, %s, %s);\r", bitmapId, 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, %s, %s, %s, %s, %f);\r",
thickness, color, 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, 0x%06x, %f, %s, %s, %s, %s);\r",
thickness, color, alpha, pixelHinting.toString(),
(scaleMode == null ? "null" : "'" + scaleMode + "'"),
(startCaps == null ? "null" : "'" + startCaps + "'"),
"'" + joints + "'");
} else if(startCaps != null && startCaps != CapsStyle.ROUND) {
_actionScript += StringUtils.printf("graphics.lineStyle(%f, 0x%06x, %f, %s, %s, %s);\r",
thickness, color, alpha, pixelHinting.toString(),
(scaleMode == null ? "null" : "'" + scaleMode + "'"),
"'" + startCaps + "'");
} else if(scaleMode != LineScaleMode.NORMAL) {
_actionScript += StringUtils.printf("graphics.lineStyle(%f, 0x%06x, %f, %s, %s);\r",
thickness, color, alpha, pixelHinting.toString(),
(scaleMode == null ? "null" : "'" + scaleMode + "'"));
} else if(pixelHinting) {
_actionScript += StringUtils.printf("graphics.lineStyle(%f, 0x%06x, %f, %s);\r",
thickness, color, alpha, pixelHinting.toString());
} else if(alpha != 1.0) {
_actionScript += StringUtils.printf("graphics.lineStyle(%f, 0x%06x, %f);\r", thickness, color, alpha);
} else if(color != 0) {
_actionScript += StringUtils.printf("graphics.lineStyle(%f, 0x%06x);\r", thickness, 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, %f);\r", x, y);
//_actionScript += StringUtils.printf(_target+".x = %f;\r"+_target+".y = %f;\r", x, y);
_actionScript += StringUtils.printf("shapeTimeline.append(new TweenLite("+_target+",0.001,{x:%f,y: %f}));\r", x, y);
}
override public function lineTo(x:Number, y:Number):void {
//_actionScript += StringUtils.printf("graphics.lineTo(%f, %f);\r", x, y);
_actionScript += StringUtils.printf("shapeTimeline.append(new TweenLite("+_target+","+_time+",{x:%f,y: %f}));\r", x, y);
}
override public function curveTo(controlX:Number, controlY:Number, anchorX:Number, anchorY:Number):void {
//_actionScript += StringUtils.printf("graphics.curveTo(%f, %f, %f, %f);\r", controlX, controlY, anchorX, anchorY);
_actionScript += StringUtils.printf("shapeTimeline.append(new TweenLite("+_target+","+_time+",{bezier:[{x:%f,y: %f},{x:%f,y: %f}]}));\r", controlX, controlY, anchorX, anchorY);
}
}
}
一旦你下載as3swf,你需要保存這個類出口商的包。 這是result。您可以下載它的fla以及生成該代碼的fla。
這是一個純粹的動作版本,並有不俗的結果。
該動畫看起來不穩定,因爲它爲每個線段使用了相同的時間補間。有些更短,而其他更長。您可以存儲之前的位置並將其與當前位置一起使用來計算距離,並基於該位置爲每個TweenLite實例生成一個體面。 還隨意修改類,你需要的任何方式(比如你想用一個定時器來代替等)
更新
我有時間多做一些修補。 我改變了出口商一下,現在它也期望你的目標對象的最大距離旅行。這將是選擇的寬度或高度(所有線),取決於哪一個更大(寬度與高度)。先前的x和y值存儲在 並用於計算距離,然後將該距離除以最大行進距離。這又用於縮放每個補間的時間。另外,我已將緩動設置爲線性,因爲默認(Quad.easeOut)會添加到抖動中。時間不是很準確,但看起來a bit better。更新FLA的here和here
更新時間表代碼:
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",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);
}
再次,隨意鼓搗。
更新2:
確定,這裏的又一種方法...
自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和setup。由於我們關注路徑,因此我只是將文本解析器註釋掉了。註釋掉的課程在底部。
庫包含一個Path解析器克隆和修改,以獲得一些動畫代碼:PathTween.as 你可能認識一些變量從as3swf類。 下面是一些我加入了變量的一些解釋:
而且,我已經做了一個quickfix,添加了一個默認繞組,因爲有時,繞組屬性可能會從.fxg文件中丟失,並且會破壞解析器。
爲了使用您需要對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 , Group , Library,
PathTweenTracer , Ellipse, Rect, Line,
BitmapGraphic, BitmapImage,
TextGraphic, 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,-2,4);\r'+(target+i)+'.graphics.endFill();\raddChild('+(target+i)+');\r';
return result;
}
這是相當簡單:
然後我打開了一個新的FLA文件和:
到目前爲止,as3swf很酷,一旦你已經準備好了粘貼illustrator路徑, 可能會更快,因爲as3swf使用字節。 我喜歡怎麼樣的FXG方法:
這實際上很有趣,有單獨的時間表,所以我製作了另一個副本,它將一些俗氣的曲線繪製成位圖數據。
Here PathTweenTracer類,就像以前一樣,將它放在解析器包中。 同樣,PARSERS不斷需要進行內部FxgFactory更新:
private static const PARSERS:Array = [ Graphic , Group , Library,
PathTweenTracer , Ellipse, Rect, Line,
BitmapGraphic, BitmapImage,
TextGraphic, RichText ];
的timeline代碼是大同小異的。 的result看起來不錯(source)
下面是生成的動畫的一些截圖:
FXG方法會更好地解決這個問題('使用純動作,我如何在每行後移動符號,而不使用預定義的Motion Guides?')
至於嵌套問題('這些繪圖可以通過AS3或I訪問的對象應該將它們轉換爲符號/任何必需的格式?'):
正如@Casey提到的,一旦設置了圖形,就無法訪問圖形。使用更新的圖形API,您可以將圖形從一個圖形實例複製到另一個,但不會公開這些命令。我記得Tink在Flash Player 10之前有something的方式,但我不知道那是什麼進展。
HTH
依我之見,這種分解爲兩個主要步驟:
要控制動畫,您將使用ENTER_FRAME事件在屏幕上移動符號。如:
stage.addEventListener(Event.ENTER_FRAME, doMotion);
...
public function doMotion(event:Event):void {
//animate along the path
targetSymbol.x = someNewValue;
targetSymbol.y = someNewValue;
}
另一種方法(一個我承認使用非常頻繁)是使用定時器來觸發動畫調用,在這種情況下,「doMotion」功能。如:
var FPS:Integer = 30; //frames per second (approx)
var animationTimer:Timer = new Timer(1/FPS * 1000); //converted from SEC to MS
animationTimer.addEventListener(TimerEvent.TIMER, doMotion);
animationTimer.start();
棘手的部分是確定運動路徑。從描述中無法知道最佳方法。但是,爲了刺穿它,似乎所有的路徑都是直線。
- 一種方法 -
如果是這樣,那麼你就可以計算出您的符號必須使用X,ÿ,寬度,高度和旋轉的線條值。請注意,旋轉以弧度表示。因此,在動畫開始時,您可以使用基本三角(arcsin,arccos,arctan)來查找線條的起點和終點。
一旦你知道了端點,你可以在開始的x/y開始你的targetSymbol並以任何你想要的方式將它移動到結尾的x/y。最簡單的方法是將x中的總變化除以完成動畫所需的幀數,然後重複和。然後將這些微小數字添加到每次迭代中的值爲x和y值。您還可以通過調整動作的「速度」來添加「緩動」等效果,以便輕輕地啓動和停止。「
由於行被導入到Flash中,因此可以爲它們指定實例名稱以使編碼更容易。或者,如果太多,則可以遍歷某些類型集合中存儲所有行的所有顯示對象。
- 另一種方法 -
您可能還可以創建一個動畫的影片剪輯,然後複製該影片剪輯其他地方需要動畫所以你可以「手動」畫/吐溫的令人印象深刻的動畫,然後以編程方式將動畫的變形實例放置在適當的位置ns將由現有線路決定。
我希望一切有助於在某種程度上,
--gMale
的問題是:通過AS3訪問這些繪圖對象或者我應該將它們轉換爲符號/任何必要的格式。請給出一些AS示例。
我不知道有什麼方法直接訪問AS3中的符號。從我可以告訴他們他們的父級MovieClip的圖形屬性的元素。然而,一旦你畫這種形狀的drawOnMe.graphics對象,你不能訪問它,因爲它沒有標識
var drawOnMe:Sprite = new Sprite();
drawOnMe.graphics.beginFill(0xCC0000);
drawOnMe.graphics.drawRect(0,0,100,100);
drawOnMe.graphics.endFill();
:例如,你可以這樣寫代碼。您的進口藝術品基本上在同一條船上。
由於您無法訪問該圖稿,因此無法從導入的輪廓中獲取點並沿着該路徑爲該元件設置動畫效果。總之,我並不認爲這可以做到。
在圖形性能更多信息:
哇,謝謝你的隊友,這是一個詳盡而正確的答案。非常感謝你! – Jauzsika 2010-07-19 07:55:16
@Jauzsika很高興我可以幫助和感謝代表。 – 2010-07-19 09:53:04