前編では基本的な図形描画の方法を習得しました。後編では応用例としてWeb 2.
超クールなWeb 2.0風バッジを描く
次のようなバッジをActionScript 3.

ちょっと長いですが、
package {
import flash.display.Sprite; ┐
import flash.geom.Matrix; │
import flash.geom.Point; │(1)
import flash.filters.DropShadowFilter; │
import flash.text.TextField; ┘
public class Web2Badge extends Sprite {
// インスタンス変数を宣言
private const LINE_COLOR:uint = 0xffffff; ┐
private const BODY_COLOR1:uint = 0xffff66; │
private const BODY_COLOR2:uint = 0xffcc00; │
private const CORNER:int = 12; │(2)
private const RADIUS1:Number = 26; │
private const RADIUS2:Number = 22; │
private const TEXT:String = "BETA"; ┘
// コンストラクタ
public function Web2Badge() {
// バッジの小さいほうの直径
var d:Number = Math.min(RADIUS1, RADIUS2) * 2;
// Spriteを作成
var s:Sprite = new Sprite();
s.graphics.lineStyle(1, LINE_COLOR);
// グラデーションの範囲と方向をMatrixオブジェクトに格納
// (d×dの範囲を-45°の方向に)
var matrix:Matrix = new Matrix();
matrix.createGradientBox(d, d, -Math.PI / 4);
// グラデーションの情報を指定
s.graphics.beginGradientFill(
"linear", // 線状のグラデーション
[BODY_COLOR1, BODY_COLOR2], // 色
[1, 1], // 透明度
[0, 255], // 色の位置
matrix); // 範囲と角度
// 星型の描画
var angle:Number = 2 * Math.PI / CORNER;
var p1:Point, p2:Point;
s.graphics.moveTo(RADIUS1, 0);
for(var i:int = 0; i < CORNER; i++) {
p1 = Point.polar(RADIUS2, angle * (i + 0.5));
p2 = Point.polar(RADIUS1, angle * (i + 1));
s.graphics.lineTo(p1.x, p1.y);
s.graphics.lineTo(p2.x, p2.y);
}
s.graphics.endFill();
// 影をつける
s.filters = [new DropShadowFilter(4, 45, 0, 0.5)];
// 中に表示するテキストを作成
var size:int = d / TEXT.length;
var text:TextField = new TextField();
text.htmlText = '<font size="' + size + '" color="#ffffff">'
+ '<b>' + TEXT + '</font></b>';
text.x = -text.textWidth / 2;
text.y = -text.textHeight / 2;
text.filters = [new DropShadowFilter(1, 45, 0, 0.8)];
s.addChild(text);
// (100, 100) に表示
s.x = s.y = 100;
addChild(s);
}
}
}
ソースコードをWeb2Badge.
mxmlc Web2Badge.as
Web2Badge.
ソースコードを見ていこう
では、
冒頭(1)のimport文は利用するクラスを列挙しています。前回はimportするクラスはSpriteだけでしたが、
(2)では、
インスタンス変数は次のようにして宣言します。

属性にはprivate・
インスタンス変数の宣言には、
バッジ本体の描画
グラデーションを定義する
まずはバッジの背景を描画するところを見ていきましょう。背景にはうっすらとグラデーションがかかっています。
前回ご説明したbeginFill()メソッドは単色でしか塗れませんでしたが、
// グラデーションの範囲と方向を Matrix オブジェクトに格納
// (d×dの範囲を-45°の方向に)
var matrix:Matrix = new Matrix();
matrix.createGradientBox(d, d, -Math.PI / 4);
// グラデーションの情報を指定
s.graphics.beginGradientFill(
"linear", // 線状のグラデーション
[BODY_COLOR1, BODY_COLOR2], // 色
[1, 1], // 透明度
[0, 255], // 色の位置
matrix); // 範囲と角度
最初に、
次に、
星型を描画する
星を描画するところのソースを見てみましょう。
// 星型の描画
var angle:Number = 2 * Math.PI / CORNER;
var p1:Point, p2:Point;
s.graphics.moveTo(RADIUS1, 0);
for(var i:int = 0; i < CORNER; i++) {
p1 = Point.polar(RADIUS2, angle * (i + 0.5));
p2 = Point.polar(RADIUS1, angle * (i + 1));
s.graphics.lineTo(p1.x, p1.y);
s.graphics.lineTo(p2.x, p2.y);
}
s.graphics.endFill();
for文を利用していますね。CORNERの回数だけループを回しています。
点の座標計算にはPointクラスのstaticなメソッドpolar()を利用しています。
polar( 原点からの距離:Number, ラジアンで表した角度:Number ):Point
polar()メソッドは、
2つの円

影をつけるには
バッジにはうっすらと影がついています。影をつけるにはDropShadowFilterクラスを用います。
// 影をつける
s.filters = [new DropShadowFilter(4, 45, 0, 0.5)];
DropShadowFilter のコンストラクタに渡しているパラメータは、
フィルタを指定するには、
// フィルタを作成
var filter:DropShadowFilter= new DropShadowFilter(4, 45, 0, 0.5);
// 配列を作成
var array:Array = [];
// 配列にfilterを追加
array.push(filter);
// s のfiltersプロパティにarrayを指定
s.filters = array;
配列で指定しているところからも分かる通り、
テキストを配置
文字列の表示はTextFieldクラスを利用します。
var text:TextField = new TextField();
var size:int = d / TEXT.length; --(1)
text.htmlText = '<font size="' + size + '" color='#ffffff'>'
+ '<b>' + TEXT + '</font></b>'; --(2)
text.x = -text.textWidth / 2; ┐
text.y = -text.textHeight / 2; ┘(3)
text.filters = [new DropShadowFilter(1, 45, 0, 0.8)];
s.addChild(text);
座標計算を行っているところが少し複雑でしょうか。
- (1) バッジの直径に合わせて、
フォントサイズを決定している。 - (2) TextFieldクラスのhtmlTextプロパティを利用して、
HTMLの形式で文字サイズと色を設定する。 - (3) (2)で作成した文字列のサイズを取得して、
原点を中心に文字が表示されるように位置を調整する。
ちょっとした修正でいろんなバッジを
以上でソースコードの読解は完了です。ここからは、
Web2Badgeクラスの先頭では、
例えば、
private const LINE_COLOR:uint = 0x7FCE3D;
private const BODY_COLOR1:uint = 0xCDEEB7;
private const BODY_COLOR2:uint = 0x74CA31;
private const CORNER:int = 8;
private const RADIUS1:Number = 26;
private const RADIUS2:Number = 18;
private const TEXT:String = "SALE";
角の数が少なく、

曲線で結ぶ
今度は描画処理も修正してみましょう。lineTo()で直線を引いている箇所を、
s.graphics.moveTo(RADIUS1, 0);
for(var i:int = 0; i < CORNER; i++) {
p1 = Point.polar(RADIUS2, angle * (i + 0.5));
p2 = Point.polar(RADIUS1, angle * (i + 1));
s.graphics.curveTo(p1.x, p1.y, p2.x, p2.y);
}
s.graphics.endFill();
RADIUS1とRADIUS2のどちらが大きいかによって、

private const LINE_COLOR:uint = 0xAEAFB1;
private const BODY_COLOR1:uint = 0xAEAFB1;
private const BODY_COLOR2:uint = 0x2B2B2B;
private const CORNER:int = 10;
private const RADIUS1:Number = 20;
private const RADIUS2:Number = 26;
private const TEXT:String = "BETA";
private const LINE_COLOR:uint = 0xffffff;
private const BODY_COLOR1:uint = 0xFFDAED;
private const BODY_COLOR2:uint = 0xFD037F;
private const CORNER:int = 16;
private const RADIUS1:Number = 26;
private const RADIUS2:Number = 18;
private const TEXT:String = "SALE";
パラメータを修正するだけで、
まとめ
Flashはもともとデザイナーが使うものだっただけに、
ActionScriptを使っての描画に興味を持った方は、
次回は、