curveToでマウスに追従する曲線。
ENTER_FRAMEで拾った座標を配列に次々に登録していく。曲線の描画は配列に登録した座標をforでループしてcurveToで一気に書く。
配列に登録された座標と次の座標の中間をアンカーポイントにしてcurveToしていく。
SAMPLE VIEW CODE
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
public class NMain extends MovieClip {
//-------------------------------------------------------------------------------- Properties
private var _this:MovieClip;
private var _stage:Stage;
//-------------------------------------------------------------------------------- Constractor
public function NMain() {
_this = this;
_stage = stage;
_stage.scaleMode = StageScaleMode.NO_SCALE;
_stage.align = StageAlign.TOP_LEFT;
Init();
}
//-------------------------------------------------------------------------------- Function
/**
* initialize
*/
public function Init():void {
initmaru();
_stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mousedown);
}
//
private function stage_mousedown(eo:* = null) {
_stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseup);
drawstart();
}
//
private function stage_mouseup(eo:* = null) {
_stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseup);
drawstop();
}
/**
* initialize maru
*/
private var _maru:MovieClip;
private function initmaru():void {
_maru = new maru();
_maru.visible = false;
_this.addChild(_maru);
}
/**
* draw action
*/
private var _line:MovieClip;
private var distancepoint:Point;
private var targetpoint:Point;
private var drawstopping:Boolean;
//
private function drawstart():void {
_line = new Line();
_line.Start(_this.mouseX, _this.mouseY);
_this.addChild(_line);
targetpoint = new Point();
distancepoint = new Point();
_maru.visible = true;
_maru.x = _this.mouseX;
_maru.y = _this.mouseY;
_this.setChildIndex(_maru, _this.numChildren - 1);
drawstopping = false;
_this.addEventListener(Event.ENTER_FRAME, drawaction);
}
//
private function drawstop():void {
drawstopping = true;
_maru.visible = false;
}
/** */
private function drawaction(eo:* = null):void {
if(!drawstopping) {
targetpoint.x = _this.mouseX;
targetpoint.y = _this.mouseY;
}
distancepoint.x = targetpoint.x - _line.lastpoint.x;
distancepoint.y = targetpoint.y - _line.lastpoint.y;
maruaction();
lineaction();
}
/** */
private function maruaction():void {
_maru.x += (targetpoint.x - _maru.x) * .2;
_maru.y += (targetpoint.y - _maru.y) * .2;
_maru.rotation = Math.atan2(distancepoint.y , distancepoint.x) * 180 / Math.PI;
if(drawstopping) {
if(Math.abs(targetpoint.x - _maru.x) < 5 && Math.abs(targetpoint.y - _maru.y) < 5) {
_this.removeEventListener(Event.ENTER_FRAME, drawaction);
}
}
}
/** */
private function lineaction():void {
_line.Draw(_maru.x, _maru.y);
}
}
}
/**
* Line Class
*/
import flash.display.*;
import flash.geom.*;
import frocessing.color.*;
class Line extends MovieClip {
//-------------------------------------------------------------------------------- Properties
private var _this:MovieClip;
private var points:Array;
public var lastpoint:Point;
private var colorhsv:ColorHSV;
//-------------------------------------------------------------------------------- Constractor
public function Line() {
_this = this;
Init();
}
//-------------------------------------------------------------------------------- Function
/**
* initialize
*/
public function Init():void {
points = new Array();
}
/**
* start
*/
public function Start(posx:Number, posy:Number):void {
lastpoint = new Point(posx, posy);
points.push(lastpoint);
colorhsv = new ColorHSV();
colorhsv.s = .6;
colorhsv.h = 360 * Math.random();
}
/**
* draw line
*/
public function Draw(posx:Number, posy:Number):void {
lastpoint = new Point(posx, posy);
points.push(lastpoint);
var g:Graphics = _this.graphics;
g.clear();
g.lineStyle(20, colorhsv.value, .8, false, "normal", "round", null, 3);
g.moveTo(points[0].x, points[0].y);
for (var i:int = 1; i < points.length - 1; i++) {
g.curveTo(points[i].x,
points[i].y,
(points[i].x + points[i + 1].x) / 2,
(points[i].y + points[i + 1].y) / 2);
}
}
}