PRACTICE

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 = new createjs.Shape();
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]で表現しますが、やり過ぎるとシルエットがくっきりして漫画の☆っぽくなるので、いい塩梅で調整します。

RADIUS = 6;
// 半径
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。

COUNT = Math.floor( “canvasの幅” * ( “canvasの高さ” *4/5 ) / 60000 );
// 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]を使って行います。

DISTANCE = Math.floor( Math.sqrt(Math.pow(“canvasの幅” /2, 2) + Math.pow(“canvasの高さ” *4/5, 2)) );
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要素 –

ドットインストール : HTML5 Canvas入門
ドットインストールはプログラミング学習サイト。プログラム習得の最初の1歩にお勧めです。

– CreateJS –

HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う
CreateJSはGrant Skinner氏作成のJavaScriptライブラリー、野中文雄氏がサンプル付きで説明しています。

– 線形グラデーション –

JS5 :HTML5向けjavascriptフレームワークのチュートリアルサイト
CreateJS(EaselJS)の線形グラデーションの説明ページ、切替点の説明が分かり易いです。

– 円形グラデーション –

JS5 :HTML5向けjavascriptフレームワークのチュートリアルサイト
CreateJS(EaselJS)の円形グラデーションの説明ページ、線形同様に切替点の説明が分かり易いです。

– CreateJSのトゥイーン機能 –

msto.jp : TweenJSでHTML5/Canvasアニメーション
Tweenの動きが分かり易いです、熊のイラストがかわいいです。

– BoxBlurFilter –

EaselJS編 BoxBlurFilter
CreateJS(EaselJS)のバージョンによってライブラリの実装が違うみたいです、自分の環境で動作したのがこちらの指定方法でした。

– ALOHA GIRL –

ALOHA GIRL
CreateJSを使用したアニメーションページです。見ていてリラックス出来るコンテンツをテーマにしています。

Posted on 29 Mar, 2014

END OF PRACTICE #01