fl.motion.BezierSegmentで三次ベジェ
fl.motion.BezierSegmentクラスを使用して三次ベジェ曲線を描く。
BezierSegmentの分割数を変える為のコンポーネントを追加し、値を変えた時に再描画するようイベントリスナーを設置。
また、2個のアンカーと2個のハンドルを追加し、ドラッグ時に再描画するようイベントリスナを設置。
BezierSegmentクラスは、コンストラクタに2個のアンカーと2個のハンドルの座標をPointで渡してインスタンスを生成する。
BezierSegment.getValue(t);で媒介変数t=0〜1の値を順に渡していってtに相当する座標をPointで取得し、lineToで描画する。
今回は、t=0〜1を何分割するかをNumericStepperで切り替えるようにしてみた。
- ActionScript
- Main.as
- Source
package {
import fl.controls.NumericStepper;
import fl.motion.BezierSegment;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
public class Main extends Sprite {
private var curveLayer:Sprite;
private var lineLayer:Sprite;
private var interpolate:NumericStepper;
private var base:MovieClip;
private var a:Anchor;
private var b:Handle;
private var c:Handle;
private var d:Anchor;
private var interpolateNumber:int = 50;
public function Main() {
this.interpolate = new NumericStepper();
this.interpolate.maximum = 100;
this.interpolate.value = 50;
this.interpolate.x = 470;
this.interpolate.y = 528;
this.interpolate.addEventListener(Event.CHANGE, this.onInterpolateChange);
this.addChild(this.interpolate);
this.base = this.getChildByName('_base') as MovieClip;
this.initLayer();
this.initControllPoints();
this.draw();
}
private function get pointA():Point {return new Point(this.a.x, this.a.y);}
private function set pointA(value:Point):void {this.a.x = value.x; this.a.y = value.y};
private function get pointB():Point {return new Point(this.b.x, this.b.y);}
private function set pointB(value:Point):void {this.b.x = value.x; this.b.y = value.y};
private function get pointC():Point {return new Point(this.c.x, this.c.y);}
private function set pointC(value:Point):void {this.c.x = value.x; this.c.y = value.y};
private function get pointD():Point {return new Point(this.d.x, this.d.y);}
private function set pointD(value:Point):void {this.d.x = value.x; this.d.y = value.y};
private function initLayer():void {
this.curveLayer = new Sprite();
this.lineLayer = new Sprite();
this.addChild(this.lineLayer);
this.addChild(this.curveLayer);
}
private function initControllPoints():void {
var movableRectangle:Rectangle = new Rectangle(4, 4, this.base.width - 8, this.base.height - 8);
this.a = new Anchor(true);
this.b = new Handle(true);
this.c = new Handle(true);
this.d = new Anchor(true);
this.a.x = 100;
this.a.y = this.stage.stageHeight - 100;
this.a.movableRectangle = movableRectangle;
this.a.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
this.b.x = 100;
this.b.y = 100;
this.b.movableRectangle = movableRectangle;
this.b.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
this.c.x = this.stage.stageWidth - 100;
this.c.y = 100;
this.c.movableRectangle = movableRectangle;
this.c.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
this.d.x = this.stage.stageWidth - 100;
this.d.y = this.stage.stageHeight - 100;
this.d.movableRectangle = movableRectangle;
this.d.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
this.addChild(this.a);
this.addChild(this.b);
this.addChild(this.c);
this.addChild(this.d);
}
private function onDragProgress(e:DragEvent):void {
this.draw();
}
private function onInterpolateChange(e:Event):void {
this.draw();
}
private function draw():void {
this.drawLine();
this.drawCurve();
}
private function drawLine():void {
this.lineLayer.graphics.clear();
this.lineLayer.graphics.lineStyle(1, 0xAAAAAA);
this.lineLayer.graphics.moveTo(this.pointA.x, this.pointA.y);
this.lineLayer.graphics.lineTo(this.pointB.x, this.pointB.y);
this.lineLayer.graphics.moveTo(this.pointC.x, this.pointC.y);
this.lineLayer.graphics.lineTo(this.pointD.x, this.pointD.y);
}
private function drawCurve():void {
var bezierSegment:BezierSegment = new BezierSegment(this.pointA, this.pointB, this.pointC, this.pointD);
var interpolate:int = this.interpolate.value;
var timeUnit:Number = 1 / interpolate;
var point:Point;
this.curveLayer.graphics.clear();
this.curveLayer.graphics.lineStyle(1, 0x333333);
this.curveLayer.graphics.moveTo(bezierSegment.a.x, bezierSegment.a.y);
for (var i:int = 0; i < interpolate; i++) {
point = bezierSegment.getValue(timeUnit * (i + 1));
this.curveLayer.graphics.lineTo(point.x, point.y);
}
}
}
}- package {
- import fl.controls.NumericStepper;
- import fl.motion.BezierSegment;
- import flash.display.MovieClip;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.geom.Point;
- import flash.geom.Rectangle;
- public class Main extends Sprite {
- private var curveLayer:Sprite;
- private var lineLayer:Sprite;
- private var interpolate:NumericStepper;
- private var base:MovieClip;
- private var a:Anchor;
- private var b:Handle;
- private var c:Handle;
- private var d:Anchor;
- private var interpolateNumber:int = 50;
- public function Main() {
- this.interpolate = new NumericStepper();
- this.interpolate.maximum = 100;
- this.interpolate.value = 50;
- this.interpolate.x = 470;
- this.interpolate.y = 528;
- this.interpolate.addEventListener(Event.CHANGE, this.onInterpolateChange);
- this.addChild(this.interpolate);
- this.base = this.getChildByName('_base') as MovieClip;
- this.initLayer();
- this.initControllPoints();
- this.draw();
- }
- private function get pointA():Point {return new Point(this.a.x, this.a.y);}
- private function set pointA(value:Point):void {this.a.x = value.x; this.a.y = value.y};
- private function get pointB():Point {return new Point(this.b.x, this.b.y);}
- private function set pointB(value:Point):void {this.b.x = value.x; this.b.y = value.y};
- private function get pointC():Point {return new Point(this.c.x, this.c.y);}
- private function set pointC(value:Point):void {this.c.x = value.x; this.c.y = value.y};
- private function get pointD():Point {return new Point(this.d.x, this.d.y);}
- private function set pointD(value:Point):void {this.d.x = value.x; this.d.y = value.y};
- private function initLayer():void {
- this.curveLayer = new Sprite();
- this.lineLayer = new Sprite();
- this.addChild(this.lineLayer);
- this.addChild(this.curveLayer);
- }
- private function initControllPoints():void {
- var movableRectangle:Rectangle = new Rectangle(4, 4, this.base.width - 8, this.base.height - 8);
- this.a = new Anchor(true);
- this.b = new Handle(true);
- this.c = new Handle(true);
- this.d = new Anchor(true);
- this.a.x = 100;
- this.a.y = this.stage.stageHeight - 100;
- this.a.movableRectangle = movableRectangle;
- this.a.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
- this.b.x = 100;
- this.b.y = 100;
- this.b.movableRectangle = movableRectangle;
- this.b.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
- this.c.x = this.stage.stageWidth - 100;
- this.c.y = 100;
- this.c.movableRectangle = movableRectangle;
- this.c.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
- this.d.x = this.stage.stageWidth - 100;
- this.d.y = this.stage.stageHeight - 100;
- this.d.movableRectangle = movableRectangle;
- this.d.addEventListener(DragEvent.DRAG_PROGRESS, this.onDragProgress);
- this.addChild(this.a);
- this.addChild(this.b);
- this.addChild(this.c);
- this.addChild(this.d);
- }
- private function onDragProgress(e:DragEvent):void {
- this.draw();
- }
- private function onInterpolateChange(e:Event):void {
- this.draw();
- }
- private function draw():void {
- this.drawLine();
- this.drawCurve();
- }
- private function drawLine():void {
- this.lineLayer.graphics.clear();
- this.lineLayer.graphics.lineStyle(1, 0xAAAAAA);
- this.lineLayer.graphics.moveTo(this.pointA.x, this.pointA.y);
- this.lineLayer.graphics.lineTo(this.pointB.x, this.pointB.y);
- this.lineLayer.graphics.moveTo(this.pointC.x, this.pointC.y);
- this.lineLayer.graphics.lineTo(this.pointD.x, this.pointD.y);
- }
- private function drawCurve():void {
- var bezierSegment:BezierSegment = new BezierSegment(this.pointA, this.pointB, this.pointC, this.pointD);
- var interpolate:int = this.interpolate.value;
- var timeUnit:Number = 1 / interpolate;
- var point:Point;
- this.curveLayer.graphics.clear();
- this.curveLayer.graphics.lineStyle(1, 0x333333);
- this.curveLayer.graphics.moveTo(bezierSegment.a.x, bezierSegment.a.y);
- for (var i:int = 0; i < interpolate; i++) {
- point = bezierSegment.getValue(timeUnit * (i + 1));
- this.curveLayer.graphics.lineTo(point.x, point.y);
- }
- }
- }
- }
- ActionScript
- Anchor.as
- Source
package {
import flash.display.CapsStyle;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
public class Anchor extends DraggableSprite {
public function Anchor(isDraggable:Boolean, rectSides:Number = 6, lineThickness:Number = 1, lineColor:uint = 0xAAAAAA, lineAlpha:Number = 1, fillColor:uint = 0xFFFFFF, fillAlpha:Number = 0.5) {
super(isDraggable);
this.graphics.lineStyle(lineThickness, lineColor, lineAlpha, false, LineScaleMode.NONE, CapsStyle.NONE, JointStyle.MITER, 3);
this.graphics.beginFill(fillColor, fillAlpha);
this.graphics.drawRect(-3, -3, rectSides, rectSides);
this.graphics.endFill();
}
}
}- package {
- import flash.display.CapsStyle;
- import flash.display.JointStyle;
- import flash.display.LineScaleMode;
- public class Anchor extends DraggableSprite {
- public function Anchor(isDraggable:Boolean, rectSides:Number = 6, lineThickness:Number = 1, lineColor:uint = 0xAAAAAA, lineAlpha:Number = 1, fillColor:uint = 0xFFFFFF, fillAlpha:Number = 0.5) {
- super(isDraggable);
- this.graphics.lineStyle(lineThickness, lineColor, lineAlpha, false, LineScaleMode.NONE, CapsStyle.NONE, JointStyle.MITER, 3);
- this.graphics.beginFill(fillColor, fillAlpha);
- this.graphics.drawRect(-3, -3, rectSides, rectSides);
- this.graphics.endFill();
- }
- }
- }
- ActionScript
- Handle.as
- Source
package {
public class Handle extends DraggableSprite {
public function Handle(isDraggable:Boolean, circleRadius:Number = 3, fillColor:uint = 0xAAAAAA, fillAlpha:Number = 1) {
super(isDraggable);
this.graphics.beginFill(fillColor, fillAlpha);
this.graphics.drawCircle(0, 0, circleRadius);
this.graphics.endFill();
}
}
}- package {
- public class Handle extends DraggableSprite {
- public function Handle(isDraggable:Boolean, circleRadius:Number = 3, fillColor:uint = 0xAAAAAA, fillAlpha:Number = 1) {
- super(isDraggable);
- this.graphics.beginFill(fillColor, fillAlpha);
- this.graphics.drawCircle(0, 0, circleRadius);
- this.graphics.endFill();
- }
- }
- }
- ActionScript
- DraggableSprite.as
- Source
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
public class DraggableSprite extends Sprite {
private var _isDraggable:Boolean;
public var movableRectangle:Rectangle;
public function DraggableSprite(isDraggable:Boolean) {
super();
this.isDraggable = isDraggable;
this.movableRectangle = new Rectangle();
}
public function get isDraggable():Boolean {
return this._isDraggable;
}
public function set isDraggable(value:Boolean):void {
this._isDraggable = value;
if (this.isDraggable) {
this.buttonMode = true;
this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
} else {
this.buttonMode = false;
this.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
}
}
private function onMouseDown(e:MouseEvent):void {
this.dispatchEvent(new DragEvent(DragEvent.DRAG_START));
this.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
this.stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
this.startDrag(false, this.movableRectangle);
}
private function onMouseUp(e:MouseEvent):void {
this.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
this.stopDrag();
this.dispatchEvent(new DragEvent(DragEvent.DRAG_PROGRESS));
this.dispatchEvent(new DragEvent(DragEvent.DRAG_COMPLETE));
}
private function onStageMouseMove(e:MouseEvent):void {
this.dispatchEvent(new DragEvent(DragEvent.DRAG_PROGRESS));
e.updateAfterEvent();
}
public function removeAllEventListener():void {
this.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
this.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
if (this.stage != null) {
this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
}
}
}
}- package {
- import flash.display.Sprite;
- import flash.events.MouseEvent;
- import flash.geom.Rectangle;
- public class DraggableSprite extends Sprite {
- private var _isDraggable:Boolean;
- public var movableRectangle:Rectangle;
- public function DraggableSprite(isDraggable:Boolean) {
- super();
- this.isDraggable = isDraggable;
- this.movableRectangle = new Rectangle();
- }
- public function get isDraggable():Boolean {
- return this._isDraggable;
- }
- public function set isDraggable(value:Boolean):void {
- this._isDraggable = value;
- if (this.isDraggable) {
- this.buttonMode = true;
- this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
- } else {
- this.buttonMode = false;
- this.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
- }
- }
- private function onMouseDown(e:MouseEvent):void {
- this.dispatchEvent(new DragEvent(DragEvent.DRAG_START));
- this.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- this.stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- this.stage.addEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
- this.startDrag(false, this.movableRectangle);
- }
- private function onMouseUp(e:MouseEvent):void {
- this.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
- this.stopDrag();
- this.dispatchEvent(new DragEvent(DragEvent.DRAG_PROGRESS));
- this.dispatchEvent(new DragEvent(DragEvent.DRAG_COMPLETE));
- }
- private function onStageMouseMove(e:MouseEvent):void {
- this.dispatchEvent(new DragEvent(DragEvent.DRAG_PROGRESS));
- e.updateAfterEvent();
- }
- public function removeAllEventListener():void {
- this.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
- this.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- if (this.stage != null) {
- this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onStageMouseMove);
- this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
- }
- }
- }
- }
- ActionScript
- DragEvent.as
- Source
package {
import flash.events.Event;
public class DragEvent extends Event {
public static const DRAG_START:String = 'dragStart';
public static const DRAG_PROGRESS:String = 'dragProgress';
public static const DRAG_COMPLETE:String = 'dragComplete';
public function DragEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
}
}
}- package {
- import flash.events.Event;
- public class DragEvent extends Event {
- public static const DRAG_START:String = 'dragStart';
- public static const DRAG_PROGRESS:String = 'dragProgress';
- public static const DRAG_COMPLETE:String = 'dragComplete';
- public function DragEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false) {
- super(type, bubbles, cancelable);
- }
- }
- }
実際に描画すると、45°の倍数の近傍の線がやたら細く見える。
これについては1pxの斜線で、実験してみた。
About this entry
You’re currently reading “fl.motion.BezierSegmentで三次ベジェ,” an entry on jp.ferv.blog
- Published:
- Tue, Dec 30th, 2008 at 12:19 PM
- Author:
- dsk
- Category:
- Web
- Tags:
- ActionScript 3.0
No comments
Jump to comment form | comments rss | trackback uri