名刺を投げてみる。
ITLのサイトで名刺を「RESET ALL CARDS」して
名刺をドラッグしたときの動きの再現方法の検討用。
// forked from nabe's 名刺回転の検討の土台
// ITLのサイトで名刺を「RESET ALL CARDS」して
// 名刺をドラッグしたときの動きの再現方法の検討用。
// forked from nabe's ソースの雛形
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
[SWF(width="465", height="465", backgroundColor="0xAABBCC", frameRate="12")];
public class BaseClass extends Sprite {
//画面サイズ。
private var W_:uint;
private var H_:uint;
//状態の管理。
private const statReleased:uint = 0;
private const statBeginDrag:uint = 1;
private const statDragging:uint = 2;
private const statEndDrag:uint = 3;
private var stat_:uint = statReleased;
//現在の移動・回転の速度。
private var vPos:Point = new Point(10, 5);
private var vRot:Number = 5;
//摩擦係数。運動神経がにぶい場合は値を大きくすると捕まえ易くなる。
private const fPos:Number = 0.01;
private const fRot:Number = 0.01;
//名刺
private var card_:Sprite;
//マウスカーソル・重心の位置。
private var currentCur:Point = new Point();
private var lastCur:Point = new Point();
private var lastGC:Point = new Point();
public function BaseClass () {
//コンストラクタ。ここから全体の処理が開始する。
//1.初期化処理の呼び出しを仕込むに留める。
addEventListener(Event.ADDED_TO_STAGE, init_);
}
private function init_ (event_:Event):void {
//初期化処理。
//1.用済みのリスナ登録を解除する。
event_.target.removeEventListener(event_.type, arguments.callee);
//2.画面サイズを取得する。
W_ = stage.stageWidth;
H_ = stage.stageHeight;
//3.実際の処理を書き足す。
draw_();
//4.イベント処理を登録する。
updateCur();
addEventListener(Event.ENTER_FRAME, update_);
this.addEventListener(MouseEvent.MOUSE_DOWN, dragStart_);
stage.addEventListener(MouseEvent.MOUSE_UP, dragEnd_);
}
private function draw_ ():void {
//実際の表示内容を用意する。
//後で表示位置をずらすので独立したShapeとする。
card_ = new Sprite();
var graphics_:Graphics = card_.graphics;
graphics_.beginFill(0xCCCCFF);
graphics_.drawRect(-40, -80, 80, 160);
graphics_.endFill();
addChild(card_);
}
private function dragStart_ (event_:MouseEvent):void {
//ドラッグ開始時の処理。
if (stat_ == statReleased) stat_ = statBeginDrag;
}
private function dragEnd_ (event_:MouseEvent):void {
//ドラッグ終了時の処理。
if (stat_ == statDragging) stat_ = statEndDrag;
}
private function update_ (event_:Event):void {
updateCur();
switch (stat_) {
case statReleased:
//慣性で移動中の処理。
updatePos();
updateRot();
break;
case statBeginDrag:
//ドラッグ開始時の処理。
//マウスカーソルでつかむと、
//カーソル中心に回転し始める。
//回転中心をカーソル位置にずらす。
card_.x = -mouseX;
card_.y = -mouseY;
x = currentCur.x;
y = currentCur.y;
this.startDrag();
stat_ = statDragging;
break;
case statDragging:
//ドラッグ中の処理。
//マウスカーソルを振り回すと、
//回転中心はカーソル位置に合わせて移動する。
//回転速度が変化する。
updateRot();
break;
case statEndDrag:
//ドラッグ終了時の処理。
//マウスカーソルを離すと、
//カーソル中心に回転していたものが移動し始める。
var dPos:Point = currentCur.subtract(lastCur);
vPos.x = dPos.x;
vPos.y = dPos.y;
vRot = 4;
//回転中心を重心位置に戻す。
card_.x = 0;
card_.y = 0;
x = lastGC.x;
y = lastGC.y;
stopDrag();
stat_ = statReleased;
break;
}
}
private function updateCur ():void {
//マウスカーソル・重心の位置を更新する。
lastCur.x = currentCur.x;
lastCur.y = currentCur.y;
currentCur.x = parent.mouseX;
currentCur.y = parent.mouseY;
var temp_:Point = new Point(card_.x, card_.y);
temp_ = localToGlobal(temp_);
temp_ = parent.globalToLocal(temp_);
lastGC.x = temp_.x;
lastGC.y = temp_.y;
}
private function updatePos ():void {
//位置の更新。
//新しい座標を求める。
var newX:Number = x + vPos.x;
var newY:Number = y + vPos.y;
//座標を画面内に収める。
if (Math.abs(newX) > W_) newX = newX % W_;
if (Math.abs(newY) > W_) newY = newY % H_;
if (newX < 0) newX += W_;
if (newY < 0) newY += H_;
//現在の位置を更新する。
x = newX;
y = newY;
//摩擦を反映する。
vPos.x *= (1 - fPos);
vPos.y *= (1 - fPos);
}
private function updateRot ():void {
//角度の更新。
//現在の角度を更新する。
rotation += vRot;
//摩擦を反映する。
vRot *= (1 - fRot);
}
}
}