こんにちは、KIKUCHIです。
最近巷のコーポレートサイトや採用サイトでよく見る、ページの背景でウニョウニョ動く謎のアニメーション。動画かな?と思いきや<canvas>タグを使用している...や、やだ、アタシ時代遅れ!?
今回はその Canvas について学び、実際に使ってみよう!時代の波に乗っていこう!という記事です。
※といっても、まずはCanvasの使い方を一から学ぶための超初心者用の内容となります
Canvasって...なに?
「canvas」とは、図形を描くために使用するタグです。<canvas>~</canvas> で領域を指定し、JavaScript を用いて線や画像を表示します。
引用 ... https://html-coding.co.jp/annex/dictionary/html5/canvas/
HTML5から導入されたブラウザ上で図形を描画するためのHTML要素なのですね。
ふんふん、あまりピンときませんか?わかります。
文章を読んでもあまりピンとこないタイプの自分はとりあえず使ってみるのみ!
1. 図を描画するための領域(紙)を作成
アナログで絵を描くには紙が必要ですね!紙!ペーパー!
ここでいう紙がCanvasってことですね!ということで、body内にCanvasを記述します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Canvasテスト</title> <style> body{background-color: #ddd;} canvas{background-color: #fff;} </style> </head> <body> <canvas id="paper">Canvas not supported!</canvas> <script src="script.js"></script> </body> </html>
Canvas(紙)をブラウザ上で見た時に分かりやすくするためにスタイルを指定しました。白い部分がCanvas(紙)ですね!
Canvasは図形を描画する領域をwidth属性とheight属性で指定でき、何も指定がない場合はデフォルトで幅300px、高さ150pxとなります。
<canvas>~</canvas>内には、Canvasに対応していない環境で表示される文言を指定できます。
2. Canvasを使うための準備
とりあえず図を描くための領域(紙)はできた。でもまだ以下の準備が必要なんだ...!
// Canvasに指定したidで要素を取得 var paper = document.getElementById('paper'); // idから要素を取得できなかったとき if (typeof paper.getContext === 'undefined') { return; } // コンテキストを取得 // 「2d」というのは、描画領域の種類のこと var context = paper.getContext('2d'); // Canvasの幅と高さを指定 paper.width = 400; paper.height = 200;
Canvasではコンテキストというオブジェクトを通じて図形を描画するため、そのオブジェクトを取得する必要があります。...ふんふん、あまりピンときませんね。
参考にした下記のスライド内では、コンテキストは「絵を描く人のような存在」とのこと。分かりやすい!
参考:https://www.slideshare.net/kimuranisei/canvas-32111057
↓
3. 正方形を描く
よっしゃ!紙も描く人も用意できたぞ!何か描くぞ!一番簡単に描けそうなのは四角形か!?
ということで、描き方はこちら
// スタイルは描画前に指定 // 塗りつぶしの色を指定 context.fillStyle = '#429955'; // 正方形を描く // fillRect(x, y, w, h) ... xyが座標、whは幅と高さ context.fillRect(50, 50, 100, 100);
Oh~~~~!Canvas(紙)に正方形描けたや~~~ん!
上記でサラッと書きましたが、描き方は以下のように指定できます。
- fillRect(x, y , w, h) ... 塗りつぶし
- strokeRect(x, y , w, h) ... 枠線
- clearRect(x, y , w, h) ... 透明(消しゴムみたいな感じ)
4. 線を描く
続いて線を描いてみようと思います。
線を描くには beginPath() で「今から線を描きますよ~!」と宣言し、 moveTo(x,y) で「この座標から描きますよ~!」と宣言し、 lineTo(x,y) で「この座標まで描きますよ~!」と宣言する必要があります。
ただ、ここまでの宣言だけでは線は描画されていません!(なんですって...)
path(軌跡)を引いただけなので、storoke() を宣言することで線が描かれます。
// 緑の正方形を描画 context.fillStyle = '#429955'; context.fillRect(50, 50, 100, 100); // 線を描きます宣言 context.beginPath(); // 線をどこから描くか宣言 context.moveTo(240,80); // 線をどこまで描くか宣言 context.lineTo(320,160); // 線の色を指定して、描画じゃ!!! context.strokeStyle = '#429955'; context.stroke();
5. 円を描く
円を描くときも線を描くときと同様に、 beginPath() で「円を描きます」と宣言し、moveTo(x,y) では「円の中心の座標」を宣言します。
そして .arc(x, y, radius, startAngle, endAngle, anticlockwise) で円弧の指定をします。
最後に .fill() でブラウザに描画します。
- x, y ... 円の中心
- radius ... 円の半径
- startAngle ... 円を描く開始地点
- endAngle ... 円を描く終了地点
- anticlockwise ... false:時計回り、true:反時計回り
// 円を描画 context.beginPath(); context.moveTo(200, 100); context.arc(200, 150, 50, 0, Math.PI*2, false); context.fillStyle = '#ff0000'; context.fill();
6. 動かしてみる
いよいよアニメーションのお時間です!先程作った日の丸が横に移動する動きをつけたいと思います!
動かすための手順
- 要素を削除
- 要素を描画
- 要素を動かす(動かす位置座標を再定義)
- 終了フラグが無ければ1.へ戻る
引用 ... https://qiita.com/nekoneko-wanwan/items/33afa5d20264c83b2bd1
function loop() { var paper = document.getElementById('paper'); if (typeof paper.getContext === 'undefined') {return;} var context = paper.getContext('2d'); // キャンバスの大きさ設定 paper.width = 400; paper.height = 200; var w = paper.width; var h = paper.height; // x軸の位置 var x = 0; // 移動速度 var speed = 2; (function render() { // 1. 要素を削除(キャンバス上の図形を削除) context.clearRect(0, 0, w, h); // 2. 要素を描画 context.beginPath(); context.arc(x, 150, 50, 0, 2*Math.PI, false); context.fillStyle = '#ff0000'; context.fill(); // 3. 要素を動かす if (x > paper.width + 50) { x = -50; } else { x += speed; } requestAnimationFrame(render); })(); } loop();
Oh~~~~!なめらかに動きました!ありがとうございます!
ん?動いたのはいいけど、 requestAnimationFrame() ってなんだ??
requestAnimationFrameはアニメーション向けの描写に特化したメソッドで、描画処理の実行に対して、ブラウザのアニメーションフレーム更新を適切に調節してくれます。
引用 ... https://noumenon-th.net/programming/2017/03/25/requestanimationframe/
なるほど難しい!この辺は改めて学ぶしかありませんね...。
最後に
今までなんとなく難しそう...と思って避けていたCanvas。今更ながら今回勉強してみて、初級の段階まではなんとか出来そうだなと思えました...!
JavaScriptを極めたらもっと高度なアニメーションが出来るのかしら...?勉強あるのみですね!
[今回参考にしたサイト]
- https://www.sejuku.net/blog/85550
- https://html5exam.jp/measures/dojo_1_05.html
- https://qiita.com/kyrieleison/items/a3ebf7c55295c3e7d8f0
前回のXDの記事で次回予告(XDの共有機能について)をしていましたが、(気が変わったため)ブログを書く時期に突然「Canvas」について学んでみたくなったので変更しました。まぁあくまでも「予定」だったので...スミマセン