その90。
tmlib.js 怒濤の 100 サンプル!! – Graphics(HTML5 Canvas) 編
今回試すサンプルは「図形(上級)」の「魔法陣を描画してみよう」です。
ではサンプルが掲載されているのでまずは見てみましょう。
中央のボタンを押してみて下さい。
漫画やアニメに出てきそうないかにもな魔法陣が描画されたと思います。
/* * 定数 */ var SCREEN_WIDTH = 465; var SCREEN_HEIGHT= 465; var SHAPE_RADIUS = 128; tm.main(function() { // canvas インスタンス生成 var canvas = tm.graphics.Canvas("#world"); // 幅, 高さを指定 canvas.resize(SCREEN_WIDTH, SCREEN_HEIGHT); // 画面にフィットさせる canvas.fitWindow(); // 黒でクリア canvas.clearColor("black"); // 影をセット canvas.shadowBlur = 20; canvas.shadowColor = "yellow"; // カラーを指定 canvas.strokeStyle = "yellow"; canvas.fillStyle = "yellow"; // 座標を中心に移動 canvas.setTransformCenter(); // 星 canvas.lineWidth = 2; canvas.strokeStar(0, 0, SHAPE_RADIUS, 5); // 五角形 canvas.lineWidth = 1; canvas.strokePolygon(0, 0, SHAPE_RADIUS, 5); // 円 canvas.strokeCircle(0, 0, SHAPE_RADIUS); // 外側の円 canvas.lineWidth = 4; canvas.strokeCircle(0, 0, SHAPE_RADIUS*1.35); // テキスト var text = "Time is money. Time is money. Time"; canvas.lineWidth = 1; canvas.font = '24px "Meiryo", "メイリオ", "ヒラギノ角ゴ Pro W3", sans-serif'; for (var i=0,len=text.length; i<len; ++i) { canvas.save(); canvas.rotate(Math.degToRad(i*10)); canvas.translate(0, -SHAPE_RADIUS*1.1); canvas.fillText(text[i], 0, 0); canvas.restore(); } });
難しそうなことをやっているようで実は今まで勉強したことを組み合わせて表現しているので一つ一つ分解すると理解出来ます。
6行目
「 SHAPE_RADIUS 」という変数を定義し、「 128 」という数値を設定しています。
これは魔法陣の基準となる大きさを決めているものになります。
20行目
影のぼかしサイズを決めています。
「 ドロップシャドウ 」という言い方もしますね。
その64で勉強していますので復習も兼ねてどうぞ。
21行目
20行目で設定した影の色をyellow
(黄色)に指示しています。
その65で勉強した内容ですね。
24・25行目
この2行は説明不要ってほどの基本ですね。
描画のストロークと塗りのスタイルを影と同じくyellow
(黄色)に指示しています。
28行目
その73で勉強した図形等を画面中央に描画するメソッドです。
基準点を画面中央にトランスフォーム(変化)させるという感じで個人的に解釈しています。
31行目(星)
その59で勉強した内容です。
コメントで星とある通リ星の線幅を「 2 」と指示しています。
32行目(星)
31行目で指示した線幅で星を描画しています。
パラメータの詳細はその23を見て頂くとして半径を決めるパラメータに6行目で定義した「 SHAPE_RADIUS 」が使われています。
34行目(五角形)
星の描画に続いて五角形です。
31行目では星の線幅を指示していましたが、今度は五角形の線幅を「 1 」と指示しています。
35行目(五角形)
その21で勉強した多角形の描画で行なっています。
こちらも半径を決めるパラメータに「 SHAPE_RADIUS 」が使われています。
37行目(円)
その12で勉強した円の描画を行なっています。
こちらも半径を決めるパラメータに「 SHAPE_RADIUS 」を使用して円を描画しています。
星や五角形を描画する際に線幅を指示していたのに円では指示していません。
これは34行目で指示した線幅を引き継いでいるからなのです。
星の線幅や五角形の線幅と表現していましたが、正確にはストロークで描画する線幅となります。
線幅を変更しない限りどんな図形をストロークで描画しても必ず同じ線幅になります。
逆を言えば線幅を変えて描画したい場合は必ず図形を描画する前に線幅を変更して下さい。
39・40行目(外側の円)
一番外側の円を描画します。
39行目で線幅を「 4 」と指示しています。
この円も半径を決めるパラメータに「 SHAPE_RADIUS 」を使っていますが「 SHAPE_RADIUS*1.35 」となっていますね。
これは「 SHAPE_RADIUS 」の値に1.35倍したものを半径とするためです。
このように定義したものを基準に計算した値を用いることで魔法陣の大きさが変わった場合でも外側の円は同じ比率で変更されるので便利です。
42行目
内側の円と外側の円の間に入るテキストを「 Text 」という変数に定義しています。
「 Time is money. 」 - 時は金なり –
43行目
線幅を「 1 」に戻しています。
以降にストロークを用いた描画が無いように思いますがデフォルトが「 1 」ですので念のためかな?
44行目
その42で勉強したフォントの指定を行なっています。
フォントの指定と同時にサイズも指示しています。
45行目
42行目で定義したテキストの長さ(文字数)を取得してその長さの分だけ繰り返し処理を行うようにしています。
以降の46~50行目までが繰り返し処理の内容となります。
46行目
現状の各スタイルを保存しています。
線幅やテキストの色、影といったものが含まれます。
47行目
描画するテキストを回転させています。その71の回転変形ですね。
繰り返し回数に応じて10度づつ回転させています。
28行目で基準点を画面中央にしていますのでその基準点を中心に回転しています。
ちなみになぜ10度づつなのかというと42行目のテキストがスペース含めて36文字なのです。
1文字ごとに10度づつ回転させていくと1回転しますね!
48行目
描画するテキストを移動させています。その70の移動変形です。
X座標は「 0 」と指示し、Y座標は「 -SHAPE_RADIUS*1.1
」と指示しています。
マイナス方向に「 SHAPE_RADIUS 」と定義した値に1.1倍したものを指示値としています。
「 128 * 1.1 = 140.8 」で「 140.8 」だけY座標をマイナス方向に移動させるということです。
49行目
その40で勉強したテキスト描画(塗りつぶし)で描画しています。
ですが定義したものをそのまま描画しているわけではありません。
パラメータに描画するテキストとして「 text[i]
」繰り返し回数に応じて定義したテキストから何番目の文字を抜き出すかを指示しています。
47・48行目と合わせて考えると1文字づつ抜き出し回転と移動を行う理由がなんとなくわかりますよね。
50行目
繰り返し処理の最後として保存していた状態を呼び出して終わっています。
何故このようなことを行うかというと、回転や移動といった変化している状態を変化していない状態にしたいからなのです。
回転や移動した状態に更に回転や移動を行うと変化している状態を基準としてしまうからです。
サンプルで言えば1文字目で10度回転させrestore
しなければ2文字目は10度+20度=30度とされてしまうのです。
そうなることを踏まえてプログラムしてもいいのですが、間違いやすくなってしまうのでサンプルのような方法をオススメします。
こういった処理のことを個人的に「 相対処理 」「 絶対処理 」と呼んでいます。
まぁ普通はこういったものに名前を付けたりしないと思いますが…