夏休みにはじめて触ったActionScript3.0。回転式のつまみを作ってみました。
できあがったものは、どうってことはないです。
フレームアクション
フィルターをActionScriptで掛けるとソースが長くなるので、Flashのワークスペースでフィルターもろもろ全部かけたMovieClipを作ってそれをクラスに割り当てました。
つまみ本体、つまみ内の発光部分、液晶表示部分のMovieClipをそれぞれ作成して、コンストラクタに渡します。
//つまみ本体
var rd = new RotationDial(dial_mc);
//つまみ本体に発光部分を追加
rd.addIndicator(dial_mc.indicator_mc);
//液晶部分
var digit = new Digit(digit_mc);
//液晶部分につまみ本体を追加
digit.addProvider(rd);
RotationDial.as
つまみ本体。
AS3では表示オブジェクトがEventDispatcherクラスを継承しているので、MovieClipクラスを継承させてEventDispatcherを使えるようにします。AS2ではMovieClipのイベントハンドラに無名関数をかましたりしていましたが、AS3ではMovieClipにaddEventListnerできるので1行で済む。これは楽チン。
AS2ではどこからでもStageにアクセスできたが、AS3ではMovieClipやSpriteのstageプロパティにアクセスすることになっている。スコープを逆にさかのぼるみたいでちょっと気持ち悪い。
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
public class RotationDial extends MovieClip
{
private var mc:MovieClip;
private var indicator:Indicator;
private var angle:Number;
private var O:Point;
private var P:Point;
function RotationDial(_mc:MovieClip)
{
mc = _mc;
mc.addEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
mc.stage.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
mc.rotation += 90;
angle = mc.rotation;
O = new Point(mc.x, mc.y);
}
public function addIndicator(_mc):void
{
indicator = new Indicator(_mc);
}
public function get _rotation():Number
{
return angle;
}
private function onStartDrag(e:Event):void
{
mc.addEventListener(Event.ENTER_FRAME, onDrag);
dispatchEvent(new Event("onStartDrag"));
indicator.light();
}
private function onStopDrag(e:Event):void
{
mc.removeEventListener(Event.ENTER_FRAME, onDrag);
dispatchEvent(new Event("onStopDrag"));
indicator.die();
}
private function onDrag(e:Event):void
{
P = new Point(O.x-this.mouseX, O.y-this.mouseY);
angle = Math.atan2(P.y, P.x)*180/Math.PI;
mc.rotation = angle;
dispatchEvent(new Event("onDrag"));
}
}
}
Indicator.as
つまみ内の発光部分。無くてもいいぐらいの感じですが。light関数でフィルターかけて光っている感じを出したり、拡張できるように。
package
{
import flash.display.MovieClip;
import flash.geom.ColorTransform;
public class Indicator
{
private var mc:MovieClip;
private var def_c:uint = 0x333333;
private var light_c:uint = 0xff0000;
function Indicator(_mc)
{
mc = _mc;
coloring(def_c);
}
public function light():void
{
coloring(light_c);
}
public function die():void
{
coloring(def_c);
}
private function coloring(_c):void
{
var ct:ColorTransform;
ct = new ColorTransform();
ct.color = _c;
mc.transform.colorTransform = ct;
}
}
}
Digit.as
にせ液晶表示部分。カスタムイベントonDragイベントを受け取って角度を表示します。
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Digit
{
private var rd:RotationDial;
private var mc:MovieClip;
private var digit:Number;
function Digit(_mc)
{
mc = _mc;
}
public function addProvider(_rd:RotationDial)
{
rd = _rd;
rd.addEventListener("onDrag", onChange);
}
private function onChange(e:Event):void
{
show(e.target._rotation);
}
private function show(_angle:Number):void
{
if(-180<=_angle&&_angle<90)
{
digit = 270+_angle;
} else {
digit = _angle-90;
}
mc.digit_txt.text = Math.floor(digit);
}
}
}