
xhackの初心者向けJavaScript勉強会に初めて参加してみた話
こんにちは。
初めまして、りゅーそうと申します。
プログラミングを独学で勉強し始めて、半年ほどになります。
今回は初めて、xhackさんの松田さんが主催するJSの勉強会に参加してきたので、その内容をアウトプットも兼ねてまとめていきたいと思います。
こちら今回参加した勉強会リンクです。↓↓
本当に参加してよかったと思えた勉強会だったので、「この勉強会よ、全駆け出しエンジニアに届け」という気持ちでnoteを書きます。
初めてのnote投稿で拙いところが多々あると思いますが、お付き合いいただけるとありがたいです!
xhack勉強会との出会い
(勉強会の内容だけを知りたい方、この章は飛ばしてください!)
私はこれまで、独学でプログラミングを勉強してきました。Progateをやったあとに、RubyやRailsなどをRailstutorialなどでやっていたのですが、ものの見事に挫折しました。その後は1ヶ月ほど勉強を一切しなくなりました。
楽しいと思って始めたプログラミングでしたが、いつの間にか教材をコピペする作業だけになってしまっていました。元々鬱病もちだったので、なかなかしんどかったです。。。
今考えれば、ネットの情報にかき乱されて、自分の身の丈にあっていない勉強をしてしまっていたんだと思います。
そんなとき見かけたのがxhack松田信介さんのアカウントでした。
松田さんのツイートをみていて、もう一度基礎からプログラミングをやって見ようと思い、ドットインストールのJavaScriptでいろんなものを作ったり、JavaScriptコードレシピ集という本で、色々動かしてみたりしていました。
その結果、MDNでこのようなものが作れるようになりました。
できました。 pic.twitter.com/xgWXq7l2wv
— りゅーそう🌐エンジニア(を目指してる人) (@ryusou_mtkh) July 19, 2019
「自分で書いたコードで何かものを作れるのは楽しい!」と思えた瞬間でした。
この時書いたコードをしっかり理解したい!JavaScriptの基礎を理解して、コードをかけるようになりたい!という気持ちでこの勉強会に参加しました。
勉強会のゴール
以下のようなアートをJavaScriptのコードだけで書きます。フレームワークなどは一切使いません。
こんなやつをJavaScriptで書きます〜 pic.twitter.com/aWIptNzwxc
— 松田信介@有言大実行の人 (@XHACK20) March 11, 2019
JavaScriptだけでこんなアートが作れるなんて、すごいです。
松田さんもおっしゃっていましたが、この講座はアートを書くことが目的ではなく、「アートを描くことを通じて、JavaScriptの本質・基礎を学習する」ことが目的です。
とても勉強になったので、以下に勉強になったことをまとめます。
①Canvas APIの使い方
まずは、図形を書くAPI「Canvas API」の使い方について。
基本的なコードはこちら。
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(20, 20, 150, 100);
</script>
</body>
</html>
<実行結果>
上のコードの解説です。
Canvas APIを使うにはまず、
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
</canvas>
のようにCanvas にidを設定します。styleの値を変えると、図形の大きさや色が変化したりするので試してみてください。
では、<script>の部分のコードをみていきます。
まずは、一行目、
var c = document.getElementById("myCanvas");
「document」というのは「HTML文書」のことを示します。
ですので、このコードは直訳すると、「HTMLの(myCanvas)というidを持った要素を取得してください。」
という意味になります。このようにJavaScriptはHTML要素を取得したりすることができます。
また、このようにすれば。。。
var element = document.createElement('div');
HTMLにdiv要素を追加することができます!
このようにHTMLを書かなくても、JavaScriptだけでHTML要素を取得したり、追加したりすることができます。(HTMLを書かなくても、JavaScriptだけで表現できるってこと)
これをJavaScriptのDOM操作って言ったりします。
では,アートをブラウザで表現するためにはどうしたらいいのか?
絵は点の集まりであり、JavaScriptで点を打つ場所を指定できれば、ブラウザ上に絵を描くことができるようになります。
このためのツールが次の行
var ctx = c.getContext("2d");
です。
getContext("2d")とは絵を書く道具だとイメージすれば良いとのことです。これをctxという変数に与えてあげることで、ブラウザ上に静止画を描くのです。詳しくはこちら ↓↓
では残りの行です。
ctx.fillStyle = "#FF0000";
ctx.fillRect(20, 20, 150, 100);
ctx.fillStyleの「 . 」はどのような意味なのでしょうか?
これは、「ctx」という変数に「fillStyle」というオブジェクトを渡しているという意味です。fillStyleとは
こちらを見ればわかるように、要素の色を操作するオブジェクトですね。
先ほどから、何気なくリンクを張っていますが、こちらは「MDN」というサイトでJavaScriptをやっている人にとってはおなじみかもしれませんが、わからないコードが出てきたら、このようにMDNで調べる癖をつけると良いらしいです。
また、チュートリアルもとてもとても充実しているので、一度チャレンジしてみましょう!
ちなみに最後のfillRectはRectangle(矩形)を描画する関数で、順番に(x,y座標 width height) を定めることで描写することができます!
(fillRectについても調べてみてくださいね〜)
②Consoleでの実行
まずは色の指定方法について、先ほどの基本的なコードにも出てきましたが、色の指定方法は3種類。
①色の名前で指定する
color: red;
②16進数RGBで指定する
color: #FF0000;
③色をRGBで直接指定する
color: rgb(255, 0, 0);
です!色をランダムで取得できれば、様々な色のアートが表現できそうです。そのためには③の方法を使います。
ランダムな数値を返してくれるメソッドは、、、
Math.random()
です!このメソッド0 ~ 1 の間のランダムな数値を返してくれます。
ランダムな色を取得してみます。
//0〜255のランダムな数を取得する
function getRandomNumber() {
return Math.floor(Math.random() * 256)
}
//ランダムな色を取得する
function getRandomColor() {
let red = getRandomNumber();
let green = getRandomNumber();
let blue = getRandomNumber();
return `rgb(${red},${green},${blue})`
}
これで、ランダムな色を取得することができます。最後の式展開の仕方は覚えておくといいらしいです。
return `rgb(${red},${green},${blue})`
ちなみにこのようなメソッドがどのように実行するのか、簡単に試したい場合はconsole.logを使うと良いらしいです。
macだったら、ブラウザを開いて option + command + J を押すと開きます。
このように、0〜255の値を取得していることがわかります。consoleはよく使うテクニックなので、使ったことがない人はconsoleを使って様々なメソッドを試してみると勉強になるとのことでした。開発にも使うそうです。
③デバック実行
では先ほどの知識を使って、画面いっぱいに四角形を表示させてランダムに色を表示させてみます!全コードはこちら!
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function getRandomNumber()
{
return Math.floor(Math.random() * 256);
}
function getRandomColor()
{
let r = getRandomNumber();
let g = getRandomNumber();
let b = getRandomNumber();
return `rgb(${r},${g},${b})`
}
var data = {
name: 'hoge',
x: 0,
y: 0,
width: 0,
height: 0,
color: "#FF0000",
setData: function(_x, _y, _width, _height, _color) {
this.x = _x;
this.y = _y;
this.width = _width;
this.height = _height;
this.color = _color;
},
draw: function() {
ctx.fillStyle = getRandomColor();
ctx.fillRect(this.x, this.y, this.width, this.height);
}
};
function drawRect(_num){
for (let i = 0; i < _num; i++) {
for (let j = 0; j < _num; j++) {
let obj1 = new Object(data);
obj1.setData(50*i, 50*j, 50, 50, "#2EF1D5");
obj1.draw();
}
}
}
drawRect(6);
</script>
<実行結果>
こちらをご覧ください。
xhack成果1 pic.twitter.com/CWNnHDmQz3
— りゅーそう🌐エンジニア(を目指してる人) (@ryusou_mtkh) July 31, 2019
このコードの中で重要なのは、var data = { }のオブジェクトです。
name, x, y, width, height, colorのオブジェクト
さらに setData, draw という関数が格納されています。このようにオブジェクトは関数も保持できるというのは重要なポイントです。
次のコードをみてください。
function drawRect(_num){
for (let i = 0; i < _num; i++) {
for (let j = 0; j < _num; j++) {
let obj1 = new Object(data);
obj1.setData(50*i, 50*j, 50, 50, "#2EF1D5");
obj1.draw();
}
}
この関数drawRect()のなかで、先ほどの関数 setData,drawが実行されていることがわかります。
さらにfor構文の中にforを入れ子構造にすることで、行・列の移動を一つの関数として実行してみます。
では、これをデバック実行してみます!
1.コンソール(option + command + J)を開いて、sourceタブをクリックします。
2.55行目のコード(obj.draw();)の左側をチェックして、ブレイクポイントを設定
3. リロードして実行
動画は以下をご覧ください
xhack成果2 pic.twitter.com/pPOcl3KOVQ
— りゅーそう🌐エンジニア(を目指してる人) (@ryusou_mtkh) July 31, 2019
このデバック実行を行うことで、書いたコードが実際にどのような挙動をしているか確認することができます。
デバック実行は開発でも使うテクニックだそうなので、早い段階で身につけると勉強効率が上がるそうなので、しっかりマスターしたい所です。
では関数drawRect(); を時間ごとに連続で実行できるようにしてみます。
setIntervalというメソッドを使います。
最後の行に
setInterval(drawRect, 33, 10);
//(実行するオブジェクト, 実行する時間(ミリ秒),オブジェクトの引数)
を追加してください。
第一引数の実行するオブジェクト(この場合はdrawRect)がなぜdrawRect()のようにカッコをつけないのでしょうか?
それは以下のような違いがあるからだそうです。
drawRect() → 関数drawRectの実行結果が渡されてしまう
drawRect → 関数drawRectがそのまま実行される
という違いがあるそうです。関数オブジェクト(?)の具体的な例ですね。
④ボールをバウンドさせる。
ボールをバウンドさせるコードです。
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
let color = 'red';
let x = 20;
let y = 20;
let speedX = 10;
let speedY = 10;
let size = 30;
function drawCircle() {
ctx.fillStyle = "rgba(8, 8, 12, 1)"
ctx.fillRect(0, 0, 300, 300);
x = x + speedX;
y = y + speedY;
if (x > 300 || x < 0) {
speedX = -speedX;
}
if (y > 300 || y < 0) {
speedY = -speedY;
}
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(x, y, size, 0, Math.PI*2, false);
ctx.fill();
}
drawCircle()
setInterval(drawCircle, 20);
<実行結果>
xhack3成果物
— りゅーそう🌐エンジニア(を目指してる人) (@ryusou_mtkh) July 31, 2019
すいません、note投稿用です。 pic.twitter.com/GyobC3ysZl
ここで、松田さんは
「ボールを画面からはみ出さないようにするにはどういった処理をしたら良いですか?」
と質問しました。
別の参加者の方は、
「ボールのx座標がwidthの値を超えるところで、逆向きに動く実装をし、y座標がheightの値を超えるところで逆向きの実装をする」
と答えました。
僕は単純に「そんな答えられるなんてすごいなあ」と思いました。
このように、実装がイメージできるようになるということも大切なことなのかなあと実感した瞬間でした。
この力をつけるためにはどんどんアウトプットしていろんなものを作らないとなあ。
上を実装したのがif文のコードになります。
そのあとにarcメソッドを使って、円を描いています。
もちろん、MDNで調べます。
先ほどのコードと同様にsetIntervalを使って実行して完成です。
setIntervalの第1引数には関数を渡す!setIntervalの第1引数には関数を渡す!(大事なことなので2回いってみました)
⑤アートを描く(やっと)
ここまでの説明で講座のほとんどの時間を費やしていました。(もちろん当noteにかけていないことも多数あります)
この講座はアートを描くというよりも、JavaScriptの基本について学ぶ講座だというのはこういうことだったのですね。
(むしろ松田さんもJavaScriptの説明をしすぎて、アートを描く時間少なくなっちゃいましたと笑っていました。笑)
では、最後にアートの全コードです。(さすがに疲れた。笑)
上のコードが理解できていれば、だいたい読めるようになると思います。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Canvas tutorial template</title>
<script type="text/javascript">
const NUM = 500;
const WIDTH = 800;
const HEIGHT = 800;
const PI_2 = Math.PI * 2;
var speedX = new Array(NUM);
var speedY = new Array(NUM);
var locX = new Array(NUM);
var locY = new Array(NUM);
var radius = new Array(NUM);
var r = new Array(NUM);
var g = new Array(NUM);
var b = new Array(NUM);
var ctx;
function init(){
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
ctx = canvas.getContext('2d');
for(var i = 0; i < NUM; i++){
speedX[i] = Math.random() * 8.0 - 4.0;
speedY[i] = Math.random() * 8.0 - 4.0;
locX[i] = WIDTH / 2;
locY[i] = HEIGHT / 2;
radius[i] = Math.random() * 45.0 + 1.0;
r[i] = Math.floor(Math.random() * 96);
g[i] = Math.floor(Math.random() * 96);
b[i] = Math.floor(Math.random() * 96);
}
setInterval(draw, 33);
}
}
function draw(){
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(8,8,12,.2)";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
ctx.globalCompositeOperation = "lighter";
for(var i = 0; i < NUM; i++){
//位置を更新
locX[i] += speedX[i];
locY[i] += speedY[i];
if(locX[i] < 0 || locX[i] > WIDTH){
speedX[i] *= -1.0;
}
if(locY[i] < 0 || locY[i] > HEIGHT){
speedY[i] *= -1.0;
}
//更新した座標で円を描く
ctx.beginPath();
ctx.fillStyle = 'rgb(' + r[i] + ',' + g[i] + ',' + b[i] + ')';
ctx.arc(locX[i], locY[i], radius[i], 0, PI_2, true);
ctx.fill();
}
}
</script>
<style type="text/css">
canvas { background-color:#000; border: 1px solid #999; }
</style>
</head>
<body onload="init();">
<canvas id="tutorial" width="800" height="800"></canvas>
</body>
</html>
読めるぞ!嬉しい!
globalCompositeOperationなど初見のメソッドもありますが、もうMDNでググれそうです。
⑥まとめ
今回学んだこと
・Canvas APIの使い方
・consoleでの実行
・デバック実行
・JavaScriptの基本構文、メソッド
Xhackの勉強会に参加するメリット
・講師の人のテクニックが知れる
デバックの方法やググり方などの手法を学ぶことができました。MDNの参照方法が知れる。
・参加した方と繋がれる
単純に知り合いになれるという意味ではもちろんですが、こういう風に勉強してるんだ。実務経験を重ねている人でも悩みを抱えてるんだと励みになります。
・プログラミングが楽しいと思える!
松田さん、参加者の人がめちゃくちゃ楽しそうにコードを書いている。
これが僕の中で一番のメリットだったかなあと思います。
Xhackの勉強会参考になりました。本当に参加してよかったと心から思います。また、参加したいなあと思います。
勉強会で会う機会ありましたら、気軽に声かけていただけると嬉しいです。
また、ここまで読み進めてくださった方ありがとうございました。
拙い文章ですいません。笑
良いアウトプットになったので、皆さんもぜひnote等書いてみてください。自分もnoteでのアウトプットは続けていこうかなと思ってます。
今後ともよろしくお願いいたします。