2009年04月23日
AS3.0 だけでちょっと素敵なボタンを描くよ

生の ActionScript には標準のボタンコントロールがなくて、手軽に UI を作りこむのが面倒なんだけど、その分、ちょっとがんばればかっこいいボタンを作れちゃうのも魅力的。
ここでは70行ほどで作った簡単なボタンを紹介する。北海道を落とすとどう跳ねるのか? で使ったやつ。
うれしいこと
- 画像でデータを持つよりもサイズが小さい。
- 拡大しても劣化しない。
- 使い回しがきく。使いまわすと、Flash 全体で見た目を統一できる。
実物
上下のボタンはクリックすると移動するよ。TEST ボタンは押しても何も起こらないよ。
やってること:
- グラデーションを定義
drawRoundRect()で角丸四角を描く- 内側に向けて
GlowFilterで光らせる - 太めに境界線を描く
- マウスが乗っていないときには白黒にする
みどころ
テキストの中身の HTML を作るときに、E4X を使ってテンプレート風の書き方をしてる。
textField.htmlText = <font size={size} color="#6B8399">
{label}
</font>.toXMLString();
たとえば、size 変数が 11 で label 変数が foo だったときには、
<font size="11" color="#6B8399"> foo </font>
が入るわけですな。
コレはお手軽!
(関連) E4X の変数展開 深追い (1)
ソース
ソースは以下に(99行)
package{
import flash.display.*;
import flash.events.*;
[SWF(backgroundColor="#f0f3f9", width="180", height="120")]
public class ButtonTest extends Sprite{
public function ButtonTest(){
var up:Button = addChild(new Button(30, 30, 30, "▲", 21)) as Button;
var down:Button = addChild(new Button(30, 30, 30, "▼", 21)) as Button;
down.y = 40;
up.addEventListener("click", function(event:Event):void{
up.y -= 5; down.y -= 5;
});
down.addEventListener("click", function(event:Event):void{
up.y += 5; down.y += 5;
});
addChild(new Button(100, 40, 20, "TEST", 32)).x = 50;
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.geom.Matrix;
import flash.filters.ColorMatrixFilter;
import flash.filters.GlowFilter;
class Button extends Sprite{
private static const mono:ColorMatrixFilter = new ColorMatrixFilter([
1 / 3, 1 / 3, 1 / 3, 0, 10,
1 / 3, 1 / 3, 1 / 3, 0, 10,
1 / 3, 1 / 3, 1 / 3, 0, 10,
0, 0, 0, 1, 0
]);
private var _hover:Boolean = false;
public function get hover():Boolean{
return _hover;
}
public function set hover(value:Boolean):void{
if(_hover != value){
_hover = value;
filters = (_hover ? null : [mono]);
}
}
public function Button(W:Number, H:Number, R:Number, label:String = "", size:int = 11){
var matrix:Matrix = new Matrix();
matrix.createGradientBox(W, H, Math.PI / 2);
var bg:Sprite = new Sprite();
bg.graphics.beginGradientFill("linear", [0xDDE9F4, 0xD5E4F1, 0xBAD2E8], [1, 1, 1],
[0, 120, 136], matrix);
bg.graphics.drawRoundRect(0, 0, W, H, R, R);
bg.graphics.endFill();
bg.filters = [new GlowFilter(0xFFFFBE, .5, 10, 10, 2, 1, true)];
addChild(bg);
var line:Sprite = new Sprite();
line.graphics.lineStyle(3, 0xBAD2E8);
line.graphics.drawRoundRect(0, 0, W, H, R, R);
addChild(line);
filters = [mono];
buttonMode = true;
mouseChildren = false;
if (label != ""){
var textField:TextField = new TextField();
textField.selectable = false;
textField.autoSize = "left";
textField.htmlText = <font size={size} color="#6B8399">{label}</font>.toXMLString();
textField.x = (W - textField.width) / 2;
textField.y = (H - textField.height) / 2;
addChild(textField);
}
addEventListener("rollOver", buttonRollOver);
addEventListener("rollOut", buttonRollOut);
addEventListener("removed", function(event:Event):void{
removeEventListener("rollOver", buttonRollOver);
removeEventListener("rollOut", buttonRollOut);
removeEventListener("removed", arguments.callee);
});
}
protected function buttonRollOver(event:Event):void{
hover = true;
}
protected function buttonRollOut(event:Event):void{
hover = false;
}
}