07/23: 水面の波紋のようなエフェクト
Category: ActionScript
Posted by: sato
「img1」「img2」で画像を読み込みます。
画像をクリックすると波紋が広がります。
いっぱいクリックするといっぱい波紋ができます。
画像は2つ用意しました。画像のサイズに合わせて波紋の大きさ・速さを変えるようにしています。
ちょっと乱雑なコードですが、.flaファイルダウンロードできます。
仕組みは、
画像の手前にちょっと(0.05%ほど)拡大した同じ画像を用意します。
その手前の画像にマスクをかけて、
マスクにワッカ形状を作成すると、その部分だけ手前の画像が見えるといった感じです。
サイズ100px・太さ5px程度のワッカ形状のシンボルを作成します。

線はマスクに使用できないので、塗りに変換します。中心が原点になるようにします。
ルートタイムラインに以下のActionScriptを記述します。
波紋がいくつも作られて、それぞれが自分の管理をするために、rippleクラスを作りました。動作はいたって簡単です。
ripple.asファイルを作成します。(文字コードUTF-8)
ポイントとしては、
1)loadClipしたMCにイベントをセットできない。
2)穴あきマスクは、閉じた状態とされてしまう?
マニュアル等では未確認ですが、うまくいかなかったので、
1)親MCにイベントをセット
2)小さく切れ目をいれて開いた形状にした。

といった対策をとりました。
サンプルファイルです。
zipファイル[943clicks]
あ、※1の部分は、
0.05%大きい手前の画像の余分な部分を白い枠で覆っています。(5%の間違いです。)
画像をクリックすると波紋が広がります。
いっぱいクリックするといっぱい波紋ができます。
画像は2つ用意しました。画像のサイズに合わせて波紋の大きさ・速さを変えるようにしています。
ちょっと乱雑なコードですが、.flaファイルダウンロードできます。
仕組みは、
画像の手前にちょっと(0.05%ほど)拡大した同じ画像を用意します。
その手前の画像にマスクをかけて、
マスクにワッカ形状を作成すると、その部分だけ手前の画像が見えるといった感じです。
サイズ100px・太さ5px程度のワッカ形状のシンボルを作成します。

線はマスクに使用できないので、塗りに変換します。中心が原点になるようにします。
ルートタイムラインに以下のActionScriptを記述します。
img1.swapDepths(1048574); //ボタンを最善面に
img2.swapDepths(1048575);
var main = this.createEmptyMovieClip("main", 0); //MovieClipを作成
var pic1 = main.createEmptyMovieClip("pic1", 0);
var ripp = this.createEmptyMovieClip("ripp", 1);
var pic2 = ripp.createEmptyMovieClip("pic2", 0);
var mask = this.createEmptyMovieClip("mask", 2);
var cLoad1 = new MovieClipLoader(); //MovieClipLoader作成
var cLoad2 = new MovieClipLoader();
var cLsnr = new Object(); //リスナー作成
cLoad1.addListener(cLsnr); //リスナー登録
img1.onRelease = function(){ img_load("http://wa.otesei.com/media/as/Water_lilies_big.jpg"); } //img1を押した時
img2.onRelease = function(){ img_load("http://wa.otesei.com/media/as/pic.jpg"); } //img2を押した時
//画像読込
function img_load(url:String){
cLoad2.loadClip(url, pic2);
cLoad1.loadClip(url, pic1);
}
//リスナーイベント(読み込み完了し初期化後)
cLsnr.onLoadInit = function(tgt){
//rippの中心に原点がくるようにして拡大する。
_root.ripp.pic2._x = -tgt._width / 2;
_root.ripp.pic2._y = -tgt._height / 2;
_root.ripp._x = tgt._width / 2;
_root.ripp._y = tgt._height / 2;
_root.ripp._xscale = 105;
_root.ripp._yscale = 105;
_root.attachMovie("valid", "valid", 3,
{ _xscale:tgt._width , _yscale:tgt._height }); //※1)はみ出した部分を隠す為
}
//マスクをセット
ripp.setMask(mask);
//クリックイベント(波紋を2つ作成)
main.onPress = function(){
var dep = _root.mask.getNextHighestDepth(); //利用可能な深度
para = { _x:this._xmouse, _y:this._ymouse, max_size:_root.main.pic1._width, _width:30, _height:30 };
_root.mask.attachMovie("ripple", "ripple" + dep , dep , para);
para = { _x:this._xmouse, _y:this._ymouse, max_size:_root.main.pic1._width, _width: 1, _height: 1 };
_root.mask.attachMovie("ripple", "ripple" + (dep + 1), dep + 1, para);
}
波紋がいくつも作られて、それぞれが自分の管理をするために、rippleクラスを作りました。動作はいたって簡単です。
ripple.asファイルを作成します。(文字コードUTF-8)
class ripple extends MovieClip {
var max_size:Number; //最大サイズ
//──────────────────────────────────
//コンストラクタ
//──────────────────────────────────
function ripple (){
this.onEnterFrame = function(){
this._width = this._height += max_size / 30; //大きくなるスピードは最大サイズに合わせて変化
if (this._width > max_size){ this.removeMovieClip(); } //設定した最大サイズに達したら自分を削除
}
}
}
ポイントとしては、
1)loadClipしたMCにイベントをセットできない。
2)穴あきマスクは、閉じた状態とされてしまう?
マニュアル等では未確認ですが、うまくいかなかったので、
1)親MCにイベントをセット
2)小さく切れ目をいれて開いた形状にした。

といった対策をとりました。
サンプルファイルです。

zipファイル[943clicks]あ、※1の部分は、