PlayCanvasでDOMを扱う手引き [DOM追加しよ編]

最近…ということもなく、前々からですが、
私キドとゲーム畑出身さん（仮称Aさん）と話しているとこんなことが…

---

キド（私）「PlayCanvasで**DOMを追加してPlayCanvasのコンテンツと連携できる**よ」

Aさん「へー**どうやってDOM入れるの？**」

キド「まず、JavaScriptのアセットから`document.createElement("div")`でDOM作って…」

(中略)

キド「……最後にbodyタグにappendChild()とかでDOMは追加することができるよ」

Aさん「日本語でおk」


---

JavaScriptに縁のない人にはHTML上にJavaScriptでDOMを追加するまでが出来ず、
やりたいことが出来なかったりするらしい。

そんな訳で今回はそんなMさんやDOMの追加方法を知りたい人のために自分なりに解説します。

#PlayCanvasのProject作成しよ
まずはPlayCanvasのProjectを新しく作って準備。
私は「Model Viewer Starter Kit」のテンプレートを使ってやります。
<img width="1680" alt="スクリーンショット 2019-12-15 22.26.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/d81d98a6-04e8-1e0a-6534-0c124c196fb8.png">

##canvas要素確認しよ
Launchすると、canvas要素にPlayCanvasのコンテンツがレンダリングされているのがわかります。
canva要素自体を知らない人はHTML5をまず知る必要があるので、[HTMLクイックリファレンスさん](http://www.htmq.com/html5/)からタグの意味だけでも知っておくとなんのための要素なのか学べます。
これだけでもWebについて知ることに繋がるので良い機会かと。
<img width="832" alt="スクリーンショット 2019-12-15 22.28.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/8a4d3025-e204-4b6d-a96f-0b86134e5f5a.png">
このcanvas要素がどこにあるのか確認できたらおkです。


#Script
PlayCanvasでは各EntityにScriptを追加することで実行することができたりします。

##新規作成しよ
canvas要素の場所を確認できたらDOMを追加するためのScriptを作ります。
Entityはなんでも良いですが、私はよくRootに作ります。
<img width="780" alt="スクリーンショット 2019-12-15 22.34.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/6cc34d13-1a7d-4ec2-88ff-9808f3383dd0.png">

今回は`addHTML.js`というScriptを作りました。
これを使ってDOMを追加していきます。

##initializeしか使わん
Scriptは以下のようなテンプレートが用意されていますが、一度だけ読み込むinitializeしか使わないので他は消しちゃいましょ。
<img width="760" alt="スクリーンショット 2019-12-15 22.40.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/c3a57f13-0cca-1e60-443e-9acb829f4907.png">

```js
var AddHtml = pc.createScript('addHtml');

AddHtml.prototype.initialize = function() {
    
};
```

##DOMをCreateしよ

JavaScriptでDOMを作るには`createElement()`を使います。
`var`というのが変数を宣言するものなのですが、これを解説するのは苦なので割愛します。

```js
var AddHtml = pc.createScript('addHtml');

AddHtml.prototype.initialize = function() {
    var domContent = document.createElement("div"); // div要素を作成
};
```

`createElement()`はその名の通りElement（要素）をcreate(作る)ことができます。
今回は`div`要素を作りました。
divはなんの意味を持たないblockレベルの要素ですが、この解説も割愛します。

##DOMをbodyタグに追加しよ
bodyタグに作ったDOMを追加するためには、JavaScriptでbodyタグがどこにいるのか取得しないといけない。
取得方法は基本的に
`document.getElementsByTagName("body")[0];`
か
`document.body`
を使うことでbodyタグを取得することができます。
今回は後者を使ってコードを書きます。

```js
var AddHtml = pc.createScript('addHtml');

AddHtml.prototype.initialize = function() {
    var domContent = document.createElement("div");
    document.body.appendChild(domContent); // bodyタグに追加
};
```
bodyタグにDOMを追加するために`appendChild()`を使います。
ここでのappendChildはbodyタグに対してdomContentを追加することができます。
これらのDOMのオブジェクトはノードと言います。
HTMLの文書内容を表してくれるオブジェクトがノードで、それらがツリー構造で構築されたものをDOMツリーと言ったり…
まぁ、この辺りはHTML自体の解説なので割愛します。知りたい方はググってみましょう。

##class名をつけよ
追加したDOMをLaunchから見てみるとちゃんとdiv要素が追加されています。
青くフォーカスされているのが追加されたdivですが、他にもdiv要素があっていまいち追加されたのかわかりづらいですね
<img width="643" alt="スクリーンショット 2019-12-15 23.11.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/047eae28-37b1-653b-fc0e-687d9994a432.png">

見分けつくようにclass名をつけてみましょう。
class名はいわば名前のようなもので、その要素が何なのかを教えるための名前です。
例えば、今回はDOMのコンテンツを作るので、「content」という名前にしてみます。

```js
var AddHtml = pc.createScript('addHtml');

AddHtml.prototype.initialize = function() {
    var domContent = document.createElement("div");
    domContent.classList.add("content");
    
    document.body.appendChild(domContent);
};
```

作成したdiv要素にclass名をつけるために、`classList.add()`を使いました。
このclassListは、そのノード(今回はdomContent)に付与されているclass属性を参照することができます。
class属性を追加するには、classListのメソッドで`add`を使います。
また、削除したい場合には`remove`を使ったりします。
この辺りはMDNをみた方が詳しいの参照してみましょう。
https://developer.mozilla.org/ja/docs/Web/API/Element/classList

Launchでまた確認すると、先ほどのdivにcontentというclass名が付与されました。
<img width="585" alt="スクリーンショット 2019-12-15 23.13.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/e41f84b4-472a-4210-3265-1c4b12b995fa.png">

これでDOMの追加ができました。

---

そんなこんなでDOMは追加するまで解説しましたが…

「DOMは追加したけど、**テキストとか装飾とかはどうしたらいいの？**」

なんて声が聞こえてきそうです……


も、もちろん、**CSSでスタイルをつける**ところまで解説しますよ！
~~ですが、今回の解説はここまで。~~
~~**スタイルについては次回の記事で！**~~

~~お楽しみに！~~

[次記事はこちら！](https://qiita.com/sutobu000/items/017bc70f556e835e57a2)