この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Flex 4 コンポーネント拡張の小ネタを紹介します。
アルファマスクは、ブレンドモードを使用することによって実現できます。 マスク対象コンポーネントとマスクの関係を「表示オブジェクトの親子関係」として、マスク対象コンポーネントのブレンドモードを「レイヤー (BlendMode.LAYER) 」、マスクのブレンドモードを「削除 (BlendMode.ERASE) 」と定義することによって、「塗りのアルファ」がマスクとして機能します。
実装コード (AlphaMaskList.as)
package jp.classmethod.sample {
import flash.display.BlendMode;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.geom.Matrix;
import spark.components.List;
import spark.core.SpriteVisualElement;
/** <p>maskColors 配列内の各色に対応するアルファ値の配列。有効な値は 0 ~ 1 です。 0 未満の値を指定した場合、デフォルトで 0 が適用されます。1 より大きい値を指定した場合、デフォルトで 1 が適用されます。</p> */
[Style(name="maskAlphas", type="Array", arrayType="int", inherit="no")]
/** <p>グラデーションで使用する RGB 16 進カラー値の配列 ( 赤 0xFF0000、青 0x0000FF など )。 最大 15 色まで指定できます。 各色について、maskAlphas スタイルプロパティと maskRatios スタイルプロパティに対応する値を指定してください。 </p> */
[Style(name="maskColors", type="Array", arrayType="int", inherit="no")]
/** <p>色分布比率の配列です。0 ~ 255 の範囲の値を指定できます。この値は、100% でサンプリングされる色の幅の割合をパーセントで定義します。 値 0 はグラデーションボックスの左の位置を表し、255 はグラデーションボックスの右の位置を表します。</p> */
[Style(name="maskRatios", type="Array", arrayType="int", inherit="no")]
/**
* <p>オサレなアルファマスク List コンポーネント</p>
* @author taiga
*/
public class AlphaMaskList extends List {
/** <p>mask alphas</p> */
protected var _maskAlphas:Array;
/** <p>mask colors</p> */
protected var _maskColors:Array;
/** <p>mask ratios</p> */
protected var _maskRatios:Array;
[SkinPart]
/** <p>アルファマスク</p> */
public var alphaMask:SpriteVisualElement;
/** <p>コンストラクタ</p> */
public function AlphaMaskList() {
super();
setStyle("skinClass", AlphaMaskListSkin);
blendMode = BlendMode.LAYER;
_maskColors = [0, 0, 0];
_maskAlphas = [1, 0, 1];
_maskRatios = [0, 127, 255];
}
/** @private */
protected override function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if(instance == alphaMask) {
alphaMask.includeInLayout = false;
alphaMask.mouseEnabled = false;
alphaMask.blendMode = BlendMode.ERASE;
}
}
/** @private */
protected override function commitProperties():void {
super.commitProperties();
var alphas:Array = getStyle("maskAlphas");
var colors:Array = getStyle("maskColors");
var ratios:Array = getStyle("maskRatios");
if(alphas != null) {
_maskAlphas = alphas;
}
if(colors != null) {
_maskColors = colors;
}
if(ratios != null) {
_maskRatios = ratios;
}
}
/** @private */
protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(alphaMask != null) {
var g : Graphics;
var m : Matrix;
var rad : Number;
var w : Number;
var h : Number;
rad = Math.PI * 0.5;
w = unscaledWidth - 16;
h = unscaledHeight - 2;
m = new Matrix();
m.createGradientBox(w, h, rad);
g = alphaMask.graphics;
g.clear();
g.beginGradientFill(GradientType.LINEAR, _maskColors, _maskAlphas, _maskRatios, m);
g.drawRect(1, 1, w, h);
g.endFill();
}
}
}
}
実装コード (AlphaMaskListSkin.mxml)
<?xml version="1.0" encoding="utf-8"?>
<s:Skin
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
minWidth = "112"
alpha.disabled = "0.5"
blendMode = "normal"
>
<fx:Metadata>
<![CDATA[
[HostComponent("jp.classmethod.sample.AlphaMaskList")]
]]>
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<s:Rect left="0" right="0" top="0" bottom="0" id="border">
<s:stroke>
<s:SolidColorStroke id="borderStroke" weight="1"/>
</s:stroke>
</s:Rect>
<s:Rect id="background" left="1" right="1" top="1" bottom="1" >
<s:fill>
<s:SolidColor id="bgFill" color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Scroller left="0" top="0" right="0" bottom="0" id="scroller" minViewportInset="1" hasFocusableChildren="false">
<s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="5" paddingTop="100" paddingBottom="100" />
</s:layout>
</s:DataGroup>
</s:Scroller>
<s:SpriteVisualElement id="alphaMask" left="0" top="0" right="0" bottom="0" />
</s:Skin>
実装コード (Main.mxml)
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
xmlns:cm = "jp.classmethod.sample.*"
fontSize = "30"
>
<cm:AlphaMaskList
width = "300"
height = "400"
verticalCenter = "0"
horizontalCenter = "0"
itemRenderer = "spark.skins.spark.DefaultComplexItemRenderer"
>
<cm:dataProvider>
<s:ArrayList>
<s:Button label="AAAA" width="100%" height="50" />
<s:Button label="BBBB" width="100%" height="50" />
<s:Button label="CCCC" width="100%" height="50" />
<s:Button label="DDDD" width="100%" height="50" />
<s:Button label="EEEE" width="100%" height="50" />
<s:Button label="FFFF" width="100%" height="50" />
<s:Button label="GGGG" width="100%" height="50" />
<s:Button label="HHHH" width="100%" height="50" />
<s:Button label="IIII" width="100%" height="50" />
<s:Button label="JJJJ" width="100%" height="50" />
<s:Button label="KKKK" width="100%" height="50" />
<s:Button label="LLLL" width="100%" height="50" />
<s:Button label="MMMM" width="100%" height="50" />
<s:Button label="NNNN" width="100%" height="50" />
</s:ArrayList>
</cm:dataProvider>
</cm:AlphaMaskList>
</s:Application>
出力結果
出力結果は次の通り
[SWF]http://public-blog-dev.s3.amazonaws.com/wp-content/uploads/2011/09/AlphaMaskListSample.swf,640,480[/SWF]