FALLING STAR
twinkle, falling and burn out
星は輝き、流れ星となって燃え尽きる
満天に輝く星空、その星空から星が一つ一つと流れ星となって地上にが降りそそいで行く。そんな夜空を描いていきたいと思います。
使用しているもの
- HTML5[style-referencing-01 id=”title-01″]canvas要素[/style-referencing-01]
- javascript[style-referencing-01 id=”title-02″]CreateJSライブラリー[/style-referencing-01]
夜空
星明かりに照らされた夜空は真黒でなく、黒から地平線に向かってやや明るくなるイメージです。canvas要素と同じサイズ(幅・高さ)にCreateJSで矩形を描写、天井を黒、底辺を濃紺の[style-referencing-01 id=”title-03″]線形グラデーション[/style-referencing-01]を指定します。
SKY.graphics.clear();
SKY.graphics.beginLinearGradientFill([‘#0000’, ‘#2B4465’], [0.2, 1], 0, 0, 0, “canvasの高さ”);
SKY.graphics.drawRect(0,0, “canvasの幅”, “canvasの高さ”);
- ※ SKY:夜空のshape
- ※ 切替点:[0.2, 1]はキレイなグラデーションだと明るすぎるので、切替点を遅らせています。
星
大きな星は月のような球形ですが、今回描きたい小さな星は点に近く、光り輝くと放射状の光の線を発します。丸(○)に光の放射(☆)を重ねたイメージです。放射は谷を深くした頂点が8個の多角形ですが光の長さは均等ではなく、上下左右(+)は長く、斜め(×)は短くしたいので、頂点が4個の多角形を2個重ねます。光は[style-referencing-01 id=”title-04″]円形グラデーション[/style-referencing-01]で表現しますが、やり過ぎるとシルエットがくっきりして漫画の☆っぽくなるので、いい塩梅で調整します。
// 半径
GRAPICS = new createjs.Graphics();
GRAPICS.clear();
// 星形大(+)
GRAPICS.beginRadialGradientFill( [‘rgba(255, 255, 255, 1)’, ‘rgba(100, 255, 255, 0.4)’], [0.1, 1], 0, 0, 1, 0, 0, RADIUS*1.2);
GRAPICS.drawPolyStar(0, 0, RADIUS*1.2, 4, 0.90, 0);
// 星形小(×)
GRAPICS.beginRadialGradientFill( [‘rgba(255, 255, 255, 1)’, ‘rgba(100, 255, 255, 0.4)’], [0.1, 1], 0, 0, 1, 0, 0, RADIUS);
GRAPICS.drawPolyStar(0, 0, RADIUS, 4, 0.94, 45);
// 丸
GRAPICS.beginRadialGradientFill( [‘rgba(255, 255, 248, 1)’,’rgba(255, 80, 80, 0.2)’], [0.1, 0.6], 0, 0, 0, 0, 0, RADIUS*2/3);
GRAPICS.drawCircle(0, 0, RADIUS*2/3);
GRAPICS.endFill();
- ※ RADIUS:星の半径です。 星形大(+)、星形小(×)、 丸それぞれで半径は異なりますが、ベースにする半径を定数にすると、調整し易いです。
- ※ GRAPICS:星のgraphics。後で複数の星のshapeに設定します。
星空
星を夜空にちりばめます。ランダムに位置取りをしますが、適度に間隔を取って配置したいです。割合は6000ピクセル(幅×高さ)に1個にします。地平線側には星を置きたくないので、高さはcanvas要素の4/5。
// Shapeの作成
STAR = {};
for (n = 0; n < COUNT; n++) { STAR.push( new createjs.Shape(GRAPHICS) ); }
// 配置
for (n = 0; n < STAR.length; n++) {
// 位置
STAR[n].x = Math.floor(Math.random() * “canvasの幅” );
STAR[n].y = Math.floor(Math.random() * ( “canvasの高さ” *4/5 ));
// サイズ
STAR[n].scaleX = 0.3;
STAR[n].scaleY = 0.3;
}
- ※ COUNT:割合(6000ピクセル)から星の数を算出。
- ※ STAR:星の配列です、先程作成した星のGraphicsを使用して星のShapeをCOUNT分作成して配列に追加します。
- ※ 位置:星の配置をランダムに計測、y軸の最大値をcanvas要素の4/5しています。
- ※ サイズ:星のサイズを調整し直します。
輝く
星の輝きは、キラキラというよりゆっくり点滅するイメージです。星が全て同じ大きさだと不自然なので輝きの大きさを変えてみます、ランダムな方が本物っぽいですが今回は見栄え的に中点に大きな星を集めます。中点はcanvas要素の上辺の真ん中(x:canvasの幅/2, y:0)にします。中点からの距離を測り最大を3分割して星の大きさ(輝きの最大値)を3パターン設定します。輝きは[style-referencing-01 id=”title-05″]CreateJSのトゥイーン機能[/style-referencing-01]を使って行います。
for (n = 0; n < STAR.length; n++) {
// 輝きの間隔
WAIT = Math.floor(Math.random()*10000+1000);
// 星の中点からの距離
STAR[n].distance = Math.floor( Math.sqrt(Math.pow(CENTER.x – STAR[n].x,2) + Math.pow(CENTER.y – STAR[n].y,2)) );
// 星の大きさ(輝きの最大値)
switch(true){
case STAR[n].distance <
DISTANCE/3 : STAR[n].scale=1.4;
break;
case STAR[n].distance >= DISTANCE/3 && STAR[n].distance < DISTANCE*2/3 :
STAR[n].scale=0.8;
break;
case STAR[n].distance >= DISTANCE*2/3 :
STAR[n].scale=0.4;
break;
}
// 輝き
createjs.Tween.get(content.spStar.shape[n], {loop:true, override:true})
.wait(WAIT)
.to({scaleX:content.spStar.shape[n].scale, scaleY:content.spStar.shape[n].scale}, 3000, createjs.Ease.sineIn)
.to({scaleX:0.3, scaleY:0.3}, 3000, createjs.Ease.sineIn) }
- ※ DISTANCE:中点からの距離の最大。
- ※ WAIT:星がいっぺんに輝くとネオンみたいなので、ランダムな時差をつけます、1000ミリ 秒(1秒)〜約10000ミリ秒(10秒)未満。
- ※ STAR[n].distance:星の中点からの距離。
- ※ STAR[n].scale:星の中点からの距離を元に、星の大きさを3タイプに設定。
- ※ createjs.Tween:loopでループ指定、overrideは後で流れ星の動きで上書きしたいからです。
流れ星
最後は流れ星、地平線に向かって斜めに流れて消えて行くイメージです。星を流すときは輝きを止めますが、燃え落ちる感じなので[style-referencing-01 id=”title-06″]BoxBlurFilter[/style-referencing-01]でブラーフィルター(ぼかし)をかけて光に包まれた感じにします。
BLUR_STRONG = 0.5+RADIUS/5;
BLUR_FILTER = new createjs.BoxBlurFilter(BLUR_STRONG, BLUR_STRONG, 2); MARGINS = BLUR_FILTER.getBounds();
// 落下地点
ANGLE = 135 FALLING_X = Math.floor(“canvasの高さ” *4/5 * Math.cos(ANGLE / 180 * Math.PI));
FALLING_Y = Math.floor(“canvasの高さ” *4/5 * Math.sin(ANGLE / 180 * Math.PI)); createjs.Tween.get(STAR[INDEX], {loop:false, override:true})
// サイズ変更
.to({scaleX:1, scaleY:1}, 3000, createjs.Ease.linear )
.call( function(){
// フィルター
STAR[INDEX].filters = [blurFilter];
STAR[INDEX].cache(-RADIUS*1.2+MARGINS.x-9, -RADIUS*1.2+MARGINS.y-9, RADIUS*1.2*2+MARGINS.width+14, RADIUS*1.2*2+MARGINS.height+14); })
// 落下
.to({scaleX:0, scaleY:0, y:STAR[INDEX].y+FALLING_Y, x:STAR[INDEX].x+FALLING_X}, 1000, createjs.Ease.linear );
- ※ コードは流れ星1個分です、サンプルは星が6個流れているのでSTAR(星の配列)にINDEXを指定して6回実行しています。
- ※ RADIUS:星の半径で使用。
- ※ ANGLE:落下角度。
- ※ FALLING_X,Y:角度から割り出した(x:0, y:0)の落下位置、これに流れ星のx,yを足して落下位置を算出します。
- ※ scaleX, scaleY:スケールを0にして燃え尽きた感じにします。
公開
今回作った星空はアニメーションコンテンツ[style-referencing-01 id=”title-06″]ALOHA GIRL[/style-referencing-01]に取り込みました、めいいっぱい星をちりばめると重くなるので抑えてはいますが、宜しければご覧下さい。
references
戻る– HTML5のcanvas要素 –
– CreateJS –
– 線形グラデーション –
– 円形グラデーション –
– CreateJSのトゥイーン機能 –
– BoxBlurFilter –
– ALOHA GIRL –
Posted on 29 Mar, 2014