您的位置:首页 > 其它

flash绘图API :蚂蚁线

2011-05-24 23:44 204 查看
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();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: