flash繪圖API :螞蟻線

weixin_34402090發表於2011-05-24

       ps 工具當中的有一個工具叫套索工具,選取一個區域之後,可以實現虛線條滾動的效果,同樣選擇矩形選框工具也可以看到這種滾動的效果。看起來很像螞蟻走動一樣。在9ria天地會當中,看到一個貼裡面實現了矩形的虛線滾動效果。要實現滾動,就需要結合到動畫程式設計,相隔一定時間讓線條重新繪製,形成一個像gif那樣的動畫。重新繪製是多少有點技巧的。

首先先看一下虛線的繪製:

例如:ABC--DEF-- GHI---GKL--MNO

我們把A-0字母看著每一個點。 從A--moveTo() 到lineTo() C 為一條線,中間D-F 需要用作虛線不進行描點連線,然後再從G點MoveTo() 到lineTo()I點 ,重複以上動作,這樣可以實現虛線繪製的。

 如圖: 虛線效果 (---  ---  ---  --- )

下面利用這個原理,簡單實現這個套索工具當中的螞蟻線效果。實現方法多少不算準確,只是一種思路實驗。

在ps套索工具使用的時候,我們將滑鼠點記錄起來,當滑鼠鬆開手的時候,需要再進行記錄 鬆開時候是點和開始點之間的所有點集。把所有路徑點都記錄點完畢之後。

我們採用間隔的畫法去進行連線描點。例如每隔 3點為一段A-C,單數為準,如此下去,就可以繪製出一個近似的任意虛線效果圖形。

為了實現動畫效果,需要結合時間器進行每隔一段時間進行重新繪製,繪製的時候。我們把採用移動辦法讓其產生一個動畫效果。

例如moveTo(開始點X,開始點Y) 開始點的位置從(0,0)開始進行繪製描點,如果每隔一段時間後,讓其開始點變成(1,1),(2,2) (,3,3) 然後當達到一定程度時候,重新 設定開始點為(0,0)。這些動畫多少有點像gif 原理。

效果圖:

     

下面是一個小小實驗。具體怎樣算也行還想有一個其他新的思路。目前今晚只是想到這裡,知道的也不是很多。

好,累。休息去。 

程式碼沒怎麼優化。僅僅作演示而已。

而要實現套索工具,多少還有很大一段距離。不知道套索工具是怎樣算的?這方面的資料相對比較少。圖形的要求多少還是停留很原始的想法當中。如果有更好的想法,不妨留下你的意見。

這種描點法算起來的效果並不是很理想和智慧,不知道還有無其他方式去實現。

 var shape:Shape=new Shape(); shape.graphics.lineStyle(0,0x000000,0.5); addChild(shape); var points:Array=[];//點集 var startPoint:Point;//開始點 var tempPoint:Point;//臨時點 var IntervalId:uint; stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler); function onMouseDownHandler(event:MouseEvent):void { points=[]; clearInterval(IntervalId); startPoint=new Point(mouseX,mouseY); tempPoint=startPoint; points.push(startPoint); shape.graphics.moveTo(startPoint.x,startPoint.y); stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMoveHandler); stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler); } //移動的時候記錄兩點之間的點 function onMouseMoveHandler(event:MouseEvent):void { var point:Point=new Point(mouseX,mouseY); points.push(point); var tempArray:Array=getPoints(tempPoint,point); points=points.concat(tempArray); tempPoint=point; shape.graphics.lineTo(point.x,point.y); event.updateAfterEvent(); } function onMouseUpHandler(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMoveHandler); stage.removeEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler); shape.graphics.lineTo(startPoint.x,startPoint.y); var tempArray:Array=getPoints(tempPoint,startPoint); points=points.concat(tempArray); drawDottedLine(6); tempPoint=null; IntervalId=setInterval(redraw,100); } //已經兩點,求兩點間所有的點,並返回一組陣列點 function getPoints(startPoint:Point,endPoint:Point):Array { var result:Array=[]; var angle:Number=Math.atan2(endPoint.y-startPoint.y,endPoint.x-startPoint.x); var distan:Number=Math.sqrt(Math.pow(endPoint.x-startPoint.x,2)+Math.pow(endPoint.y-startPoint.y,2)); for (var i:int=1; i<distan-1; i++) { var px:Number=startPoint.x+Math.cos(angle)*i; var py:Number=startPoint.y+Math.sin(angle)*i; result.push(new Point(px,py)); } return result; } //繪製虛線 function drawDottedLine(gap:int=3):void { var len:int=points.length; shape.graphics.clear(); shape.graphics.lineStyle(0,0x000000,0.5,true); trace(len); var flag:int=0; for (var i:int=0; i<len; i++) { if (i%gap==0 ) { flag++; if (flag<2) { shape.graphics.moveTo(points[i].x,points[i].y); if (i+gap-1>=len) { shape.graphics.lineTo(points[len-1].x,points[len-1].y); } else { shape.graphics.lineTo(points[i+gap-1].x,points[i+gap-1].y); } } if(flag==2){flag=0;} } } } var n:int=0; //重繪 function redraw(gap:int=6):void { var len:int=points.length; shape.graphics.clear(); shape.graphics.lineStyle(0,0x000000,0.5,true); var flag:int=0; n+=2; if(n==8)n=0; for (var i:int=0; i<len; i++) { if (i%gap==0) { flag++; if (flag<2) { if(i+n>=len) { shape.graphics.moveTo(points[i].x,points[i].y); } else { shape.graphics.moveTo(points[i+n].x,points[i+n].y); } if (i+gap-1+n>=len) { shape.graphics.lineTo(points[len-1].x,points[len-1].y); } else { shape.graphics.lineTo(points[i+gap-1+n].x,points[i+gap-1+n].y); } } if(flag==2){flag=0;} } } }

 2011年5月26日

  今天的發現某一些人有另外一種做法,於是嘗試修改一下。採用辦法是drawpath的api ,採用的是填充漸變的方式來實現這種動畫效果。

這種做法比之前會簡單一點。

封裝了一個小測試工具。

 package { import flash.display.Sprite; import flash.display.GraphicsPath; import flash.events.*; import flash.geom.*; import flash.display.Shape; import flash.utils.Timer; public class AntsLine extends Sprite { public var commands:Vector.<int> = new Vector.<int>(); public var data:Vector.<Number> = new Vector.<Number>(); private var antsPath:GraphicsPath; private var lineMatrix:Matrix = new Matrix(); private var fillMatrix:Matrix = new Matrix(); private var antsLine:Shape=new Shape(); private var delayTime:uint;//動畫執行時間 private var _startPoint:Point; //開始點位置 private var timer:Timer; public function AntsLine(delayTime:uint=120) { this.delayTime = delayTime; addChild(antsLine); lineMatrix.createGradientBox(5, 5, Math.PI/4, 0, 0); fillMatrix.createGradientBox(5, 5, Math.PI/4, 0, 0); antsLine.graphics.lineStyle(0); antsLine.graphics.lineGradientStyle("linear", [0x000000, 0xFFFFFF], [1, 1], [0xFF/2, 0xFF/2+1], lineMatrix, "repeat"); } //建立路徑 public function creatPath():void { antsPath=new GraphicsPath(); } public function setlineStyle():void { antsLine.graphics.lineStyle(0,0.5); antsLine.graphics.lineGradientStyle("linear", [0x000000, 0xFFFFFF], [1, 1], [0xFF/2, 0xFF/2+1], lineMatrix, "repeat"); } //設定開始點位置 public function set startPoint(value:Point):void { this._startPoint = value; antsPath.moveTo(value.x, value.y); } //獲取開始點位置 public function get startPoint():Point { return this._startPoint; } //新增點集 public function addPoint(point:Point):void { antsPath.lineTo(point.x, point.y); antsLine.graphics.drawPath(antsPath.commands, antsPath.data); } //連結開始點; public function joinStartPoint():void { antsPath.lineTo(_startPoint.x, _startPoint.y); antsLine.graphics.drawPath(antsPath.commands, antsPath.data); } //開始運動; public function startMotion():void { if (timer==null) { timer = new Timer(delayTime); timer.addEventListener(TimerEvent.TIMER,onTimerHandler); timer.start(); } else { timer.start(); } } //停止運動 public function stopMotion():void { timer.stop(); } //是否在運動 public function isRuning():Boolean { return timer.running; } private function onTimerHandler(event:TimerEvent):void { draw(); } private function draw():void { antsLine.graphics.clear(); antsLine.graphics.lineStyle(0,0.5); antsLine.graphics.lineGradientStyle("linear", [0x000000, 0xFFFFFF], [1, 1], [0xFF/2, 0xFF/2+1], lineMatrix, "repeat"); antsLine.graphics.drawPath(antsPath.commands, antsPath.data); lineMatrix.tx += 0.3; } //填充顏色 public function beginFill(color:uint=0x000000,alpha:Number=0.3):void { antsPath.lineTo(startPoint.x, startPoint.y); this.graphics.beginFill(color,alpha); this.graphics.drawPath(antsPath.commands, antsPath.data); this.graphics.endFill(); addEventListener(MouseEvent.MOUSE_DOWN,onDragHandler); addEventListener(MouseEvent.MOUSE_UP,onDragHandler); } private function onDragHandler(event:MouseEvent):void { if(event.type==MouseEvent.MOUSE_DOWN) this.startDrag(); if(event.type==MouseEvent.MOUSE_UP) this.stopDrag(); } //清理填充,線條 ,和資料 public function clear():void { this.graphics.clear(); antsLine.graphics.clear(); while (commands.length>0) commands.shift(); while (data.length>0) data.shift(); if (timer!=null) stopMotion(); antsPath = null; removeEventListener(MouseEvent.MOUSE_DOWN,onDragHandler); removeEventListener(MouseEvent.MOUSE_UP,onDragHandler); } //設定位置 public function move(x:Number,y:Number):void { this.x=x; this.y=y; } public function removeTimerListener():void { if (timer!=null) timer.removeEventListener(TimerEvent.TIMER,onTimerHandler); } } }

測試:

package { import flash.display.Sprite; import flash.events.*; import flash.geom.Point; public class Main extends Sprite { private var antsline:AntsLine; public function Main() { var canvas:Canvas=new Canvas();//底部容器 addChild(canvas) antsline=new AntsLine(); addChild(antsline); canvas.addEventListener(MouseEvent.MOUSE_DOWN, onMouseHandler); } private function onMouseHandler(event:MouseEvent):void { switch (event.type) { case MouseEvent.MOUSE_DOWN : antsline.clear();//清除 antsline.setlineStyle();//設定樣式 antsline.creatPath();//建立路徑 antsline.move(0,0);//設定位置 antsline.startPoint = new Point(mouseX,mouseY);//設定開始點 stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseHandler); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseHandler); break; case MouseEvent.MOUSE_MOVE : antsline.addPoint(new Point(mouseX,mouseY));//新增點集 break; case MouseEvent.MOUSE_UP : stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseHandler); stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseHandler); antsline.joinStartPoint();//連結開始點 antsline.beginFill();//填充 antsline.startMotion();//啟動漸變動畫效果 break; } } } } import flash.display.Sprite; class Canvas extends Sprite { function Canvas() { this.graphics.beginFill(0x99CC00); this.graphics.drawRect(0,0,550,400); this.graphics .endFill(); } }

相關文章