HTMLのCanvasについてのメモ
どうにもこうにも流行りの技術を使ってみたくて。
ただ一からやるには初心者には敷居が高すぎるので、先人のコードを読んで、いじってみることに。
お題はこちらから拝借!
canvasでキラキラした背景を作る方法 | tech.kayac.com - KAYAC engineers' blog
Canvasでガリガリ描写して、って使い方がまったくイメージわきません!
でもこんな風に背景として使ったり、ページのアクセントとしての使い方は素敵やなぁと思います。
なにはともあれそんな発想がすごいなぁー。
お世話になるコード
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> <script> $(function () { var hyperspace = new Hyperspace(); hyperspace.draw(); $("#canv").fadeIn('fast'); }); var Hyperspace = function(){ var canvas = document.getElementById('canv'); var ctx = canvas.getContext('2d'); //background ctx.fillRect(0, 0, canvas.width, canvas.height); var star = new Array(5); for( i=0; i<star.length; i++ ){ star[i] = new Array(7); star[i][0] = Math.random()*canvas.width; // x star[i][1] = Math.random()*canvas.height; // y star[i][2] = Math.random()*canvas.width/3 + canvas.width/14; // r star[i][3] = Math.random()*0.05 + 0.2; star[i][7] = true; var r = Math.random()*255; // R var g = Math.random()*255; // G var b = Math.random()*255; // B r = Math.ceil(r); g = Math.ceil(g); b = Math.ceil(b); star[i][4] = r; //r star[i][5] = g; //g star[i][6] = b; //b } //draw ------------------------------------- var draw = function draw(){ //reset ctx.globalCompositeOperation = "source-over"; //ctx.fillStyle = "rgba(255, 255, 255, 1)"; ctx.fillStyle = "rgba(0, 0, 0, 1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = "lighter"; //point for(i=0; i<star.length; i++){ ctx.beginPath(); var edgecolor1 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.93)"; var edgecolor2 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.6)"; var edgecolor3 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.1)"; var edgecolor4 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0)"; var gradblur = ctx.createRadialGradient(star[i][0], star[i][1], 0, star[i][0], star[i][1], star[i][2]); gradblur.addColorStop(0,edgecolor1); gradblur.addColorStop(0.4,edgecolor1); gradblur.addColorStop(0.7,edgecolor2); gradblur.addColorStop(0.9,edgecolor3); gradblur.addColorStop(1,edgecolor4); ctx.fillStyle = gradblur; ctx.arc(star[i][0], star[i][1], star[i][2], 0, Math.PI*2, false); ctx.fill(); } }; return ({'draw': draw}); }; </script>
大きな流れ
- Canvasを描く場所を決める
- 今回は円を描くので、円の設定(色とか大きさとか)を決める
- 決められた設定の通りに描画する
- っていう一連の流れを実行!
1.Canvasを描く場所を決める
var canvas = document.getElementById('canv'); var ctx = canvas.getContext('2d');
お決まりのやつなので、そのまま覚える。
本家は画面サイズいっぱいに・・・っていうくだりがあるけどもここでは割愛。
2.円の設定
var star = new Array(5); //円の数 for( i=0; i<star.length; i++ ){ star[i] = new Array(7); star[i][0] = Math.random()*canvas.width; // 円のx座標 star[i][1] = Math.random()*canvas.height; // 円のy座標 star[i][2] = Math.random()*canvas.width/3 + canvas.width/14; // 円の半径r star[i][3] = Math.random()*0.05 + 0.2; star[i][7] = true; var r = Math.random()*255; // R var g = Math.random()*255; // G var b = Math.random()*255; // B r = Math.ceil(r); g = Math.ceil(g); b = Math.ceil(b); star[i][4] = r; //r star[i][5] = g; //g star[i][6] = b; //b }
円を描くメソッドはコレ。
hoge.arc(x, y, radius, startAngle, endAngle, anticlockwise)
// x座標、y座標、半径、開始角度、終了角度、時計回りかどうか
これら7つを設定しなきゃだめ、と。
ただ円弧じゃなくて円を描くので、後ろ4つの値はどうでも良いというわけなのね。
後半は色の情報も一緒に作っている模様。
乱数作って、整数にして、格納、っと、
ここはもっと雑に一文で書けるとみた!
3.円の描画
ここからが肝心の。
var draw = function draw(){ //reset ctx.globalCompositeOperation = "source-over"; ctx.fillStyle = "rgba(0, 0, 0, 1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = "lighter";
ド素人にはこの初期化処理の必要性がわかりません・・誰か教えてください!
最後の一文は描いたものの合成処理のされ方を指定するそうな。
この設定をlighterにしてるからこそ、ふわっとした光り方になってるみたい。
//point for(i = 0; i < star.length; i++){ ctx.beginPath(); var edgecolor1 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.93)"; var edgecolor2 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.6)"; var edgecolor3 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0.1)"; var edgecolor4 = "rgba(" + star[i][4] + "," + star[i][5] + "," + star[i][6] + ",0)"; var gradblur = ctx.createRadialGradient(star[i][0], star[i][1], 0, star[i][0], star[i][1], star[i][2]); gradblur.addColorStop(0,edgecolor1); gradblur.addColorStop(0.4,edgecolor1); gradblur.addColorStop(0.7,edgecolor2); gradblur.addColorStop(0.9,edgecolor3); gradblur.addColorStop(1,edgecolor4); ctx.fillStyle = gradblur; ctx.arc(star[i][0], star[i][1], star[i][2], 0, Math.PI*2, false); ctx.fill(); }
挫折しそうw
こっちが本番の描画処理。
createRadialGradient(x0, y0, r0, x1, y1, r1) メソッドには 6 つの引数を与えます。
最初の 3 つの引数は、中心が (x0, y0) で半径が r0 の開始円を表します。
残りの3つは、中心が (x1, y1) で半径が r1 の終了円を表します。
その値は、座標空間の単位となります。
引数に、無限大や NaN がひとつでもあれば、NOT_SUPPORTED_ERR 例外が発生させなければいけません。
r0 または r1 のいずれかが負であれば、INDEX_SIZE_ERR 例外を発生させなければいけません。
そうでなければ、このメソッドは、指定の 2 つの円で初期化された円形の CanvasGradient オブジェクトを返さなければいけません。
createRadialGradient() メソッド - Canvasリファレンス - HTML5.JP
うん、わかんないw
最初に円の設定を作る時に、それぞれの円の色情報は作ってあったはず。
それを元に、円のグラデーションを指定している部分ということやと思う!
最初に設定値を作るところで、この設定もまとめて作っておけば良かったんじゃ?と思うものの、うーむ。
4.実行!
書いてある順番的には一番最初ですが、呼び出してこその関数なので、実行処理を忘れないようにしないと・・。
$(function () { var hyperspace = new Hyperspace(); hyperspace.draw(); $("#canv").fadeIn('fast'); });
単純に実行するんじゃなくて、newして実行してるのは、プログラムのお作法としてそうすべきってものやとは思うものの。
ちなみに、fadeInさせる意味もわかりません・・。
おわりに
これを読みといて思ったのは、
- プロパティ多すぎ!みんなこれを覚えてるもんなんだろうか。
- でもやってる内容は簡単。
- 発想が素敵!
- JavaScriptってなんでもできるんねー。
ちょっと気になる疑問を解消すべく、次回はサンプルを作ってみようと思います。