チュートリアル - Vue.jsでPlayCanvas製3Dモデルビュワーサイトを作る 2 / 4

[前回](https://qiita.com/sutobu000/items/818835230a90104e2c79)はチュートリアルの前説と新しいプロジェクトを作るまでを行いました。
今回はPlayCanvasにDOMを追加するまでを行います。



##DOMを乗せる
DOMを乗せるためのHTMLとCSSを作ります。

HTMLとCSSはPlayCanvasのAssetsから追加できます。
[+]ボタンをクリックし、該当する形式のファイルを選択します。
ファイル名は任意で構いませんが、以下にするとwebな感じですね。
- HTMLは「index」
- CSSは「style」

![6398187B4ABCCE17A21401FE59135126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/7fed122b-857b-6403-ebaa-8c3eeb827f29.png)


コードエディターからコードを書いて行きますが、
今回は事前に用意していますので、こちらをコピペして使用します。

[index.html]

```html
<div id="app">
    <header class="header">
        <nav>
            <ol>
                <li><span>content01</span></li>
                <li><span>content02</span></li>
                <li><span>content03</span></li>
            </ol>
        </nav>
    </header>
    <main class="main">
        <div class="container">
            <section>content01</section>
            <section>content01</section>
            <section>content01</section>
        </div>
    </main>
</div>
    

```

[style.css]

```css
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,main,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;box-sizing:border-box;background:transparent;font-size:0;line-height:0;letter-spacing:0;vertical-align:baseline}html,body{font-size:100%;line-height:1}main,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}nav ul,li{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}a{margin:0;padding:0;background:transparent;color:transparent;font-size:100%;vertical-align:baseline}ins{background-color:#ff9;color:#000;text-decoration:none}mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold}del{text-decoration:line-through}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}table{border-collapse:collapse;border-spacing:0}hr{display:block;height:1px;margin:1em 0;padding:0;border:0;border-top:1px solid #cccccc}input,select{vertical-align:middle}input[type="text"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;border:none;border-radius:0;outline:none;background:none}input[type="radio"],input[type="chackbox"]{display:none}input[type="radio"]:checked+label,input[type="chackbox"]:checked+label{background:transparent}select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:none;background:transparent}textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;resize:none;padding:0;border:0;outline:none;background:transparent}button,input[type="submit"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;border:none;outline:none;background:transparent}input[type="submit"]::-webkit-search-decoration,input[type="button"]::-webkit-search-decoration{display:none}input[type="submit"]::focus,input[type="button"]::focus{outline-offset:-2px}html,body{width:100%;height:100%}body{color:#333;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-family:Roboto,Arial,Helvetica,sans-serif;font-size:16px;line-height:1.5}a{outline:none;text-decoration:none}.wrapper__bg{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#246}main.main .color-base{color:#642}main.main .color-sub{color:#246}main.main .color-fontBase{color:#333}main.main .bgcolor-base{background-color:#642}main.main .bgcolor-base-1{background-color:rgba(102,68,34,0.1)}main.main .bgcolor-base-2{background-color:rgba(102,68,34,0.2)}main.main .bgcolor-base-3{background-color:rgba(102,68,34,0.3)}main.main .bgcolor-base-4{background-color:rgba(102,68,34,0.4)}main.main .bgcolor-base-5{background-color:rgba(102,68,34,0.5)}main.main .bgcolor-base-6{background-color:rgba(102,68,34,0.6)}main.main .bgcolor-base-7{background-color:rgba(102,68,34,0.7)}main.main .bgcolor-base-8{background-color:rgba(102,68,34,0.8)}main.main .bgcolor-base-9{background-color:rgba(102,68,34,0.9)}main.main .bgcolor-base-10{background-color:#642}main.main .bgcolor-sub{background-color:#246}main.main .bgcolor-sub-1{background-color:rgba(34,68,102,0.1)}main.main .bgcolor-sub-2{background-color:rgba(34,68,102,0.2)}main.main .bgcolor-sub-3{background-color:rgba(34,68,102,0.3)}main.main .bgcolor-sub-4{background-color:rgba(34,68,102,0.4)}main.main .bgcolor-sub-5{background-color:rgba(34,68,102,0.5)}main.main .bgcolor-sub-6{background-color:rgba(34,68,102,0.6)}main.main .bgcolor-sub-7{background-color:rgba(34,68,102,0.7)}main.main .bgcolor-sub-8{background-color:rgba(34,68,102,0.8)}main.main .bgcolor-sub-9{background-color:rgba(34,68,102,0.9)}main.main .bgcolor-sub-10{background-color:#246}main.main .bgcolor-fontBase{background-color:#333}main.main .bgcolor-fontBase-1{background-color:rgba(51,51,51,0.1)}main.main .bgcolor-fontBase-2{background-color:rgba(51,51,51,0.2)}main.main .bgcolor-fontBase-3{background-color:rgba(51,51,51,0.3)}main.main .bgcolor-fontBase-4{background-color:rgba(51,51,51,0.4)}main.main .bgcolor-fontBase-5{background-color:rgba(51,51,51,0.5)}main.main .bgcolor-fontBase-6{background-color:rgba(51,51,51,0.6)}main.main .bgcolor-fontBase-7{background-color:rgba(51,51,51,0.7)}main.main .bgcolor-fontBase-8{background-color:rgba(51,51,51,0.8)}main.main .bgcolor-fontBase-9{background-color:rgba(51,51,51,0.9)}main.main .bgcolor-fontBase-10{background-color:#333}main.main section{width:100%;padding:1rem}main.main section+section{margin-top:2rem}main.main article{width:100%;height:100%}main.main article+article{margin-top:1rem}main.main h1{font-size:36px;font-size:2.25rem;line-height:1.2;letter-spacing:.05em}main.main h2{font-size:32px;font-size:2rem;line-height:1.2;letter-spacing:.05em}main.main h3{font-size:28px;font-size:1.75rem;line-height:1.2;letter-spacing:.05em}main.main h4{font-size:24px;font-size:1.5rem;line-height:1.2;letter-spacing:.05em}main.main h5{font-size:20px;font-size:1.25rem;line-height:1.2;letter-spacing:.05em}main.main h6{font-size:16px;font-size:1rem;line-height:1.2;letter-spacing:.05em}main.main p{font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main span{font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main a{color:#642;font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em;transition:color .1s}main.main a:hover{color:#246}main.main a[target="_blank"]{text-decoration:underline}main.main a[target="_blank"]:after{content:"*"}main.main ul ul,main.main ul ol{padding-left:1rem}main.main ul>li:before{content:"・";position:absolute;top:0;left:0}main.main ol{counter-reset:item}main.main ol ol,main.main ol ul{padding-left:1rem}main.main ol>li:before{content:counter(item) ".";counter-increment:item;position:absolute;top:0;left:0}main.main li{position:relative;padding-left:1em;font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main .tableWrap{width:100%}main.main table{width:100%;border:1px solid #333}main.main th,main.main td{padding:.5em 0;font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main th{text-align:center}main.main td{text-align:center}main.main dt{display:inline-block;vertical-align:top;font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main dt:after{content:":"}main.main dd{display:inline-block;vertical-align:top;font-size:12px;font-size:.75rem;line-height:1.2;letter-spacing:.05em}main.main figure{display:inline-block;vertical-align:top}main.main figure img{display:block;width:100%;height:auto}main.main figure figcaption{text-align:center}.container{max-width:1280px;margin:0 auto}@media screen and (max-width: 767px){body{font-size:8px;font-size:2.13333vw}main.main section+section{margin-top:4rem}main.main article+article{margin-top:2rem}main.main h1{font-size:21px;font-size:2.625rem}main.main h2{font-size:19px;font-size:2.375rem}main.main h3{font-size:17px;font-size:2.125rem}main.main h4{font-size:15px;font-size:1.875rem}main.main h5{font-size:13px;font-size:1.625rem}main.main h6{font-size:11px;font-size:1.375rem}main.main p{font-size:8px;font-size:1rem}main.main span{font-size:8px;font-size:1rem}main.main a{font-size:8px;font-size:1rem;transition:none}main.main a:hover{color:#642}main.main li{font-size:8px;font-size:1rem}main.main .tableWrap{width:100%;overflow:auto;-webkit-overflow-scrolling:touch}main.main .tableWrap table{width:auto}main.main th,main.main td{padding:1em;font-size:8px;font-size:1rem}main.main dt{font-size:8px;font-size:1rem}main.main dd{font-size:8px;font-size:1rem}.container{max-width:100%}}
body.is-open .pcCanvas{left:0 !important;width:100% !important;pointer-events:none !important}body.is-open .header{left:-30%}body.is-open .detailBtn{opacity:0;pointer-events:none}body.is-open .main{width:100%;opacity:1;pointer-events:auto}canvas.pcCanvas{position:fixed !important;top:0 !important;left:15% !important;z-index:-2 !important;width:100% !important;height:100% !important;transition:width .3s, left .3s !important}.wrapper{position:fixed;top:0;left:0;z-index:1;width:0;height:100%;background-color:#ccc;transition:width .3s}.navBtn{display:none}.header{position:fixed;top:0;left:0;width:30%;height:100%;background-color:#aaa;transition:width .3s, left .3s}.header nav{padding:10% 3%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.header nav ol{text-align:center}.header nav li{position:relative;padding:5% 2%}.header nav li:after,.header nav li:before{content:"";position:absolute;top:0;left:0;z-index:-1;width:0;height:100%}.header nav li:after{background-color:#642;transition:width 0.2s;transition-delay:.1s}.header nav li:before{background-color:#fff;transition:width .2s}.header nav li span{position:relative;color:#fff;font-size:20px;font-size:1.25rem;line-height:1.2;word-break:break-all;cursor:pointer}.header nav li span:before{content:"";position:absolute;left:50%;bottom:-5px;transform:translateX(-50%);width:0;height:1px;background-color:#fff;transition:width .2s}.header nav li+li{margin-top:10%}.header nav li:hover span:before,.header nav li.is-current span:before{width:120%}.header nav li.is-current:after,.header nav li.is-current:before{width:100%}.header nav li.is-current span:before{width:0}main.main{position:fixed;top:0;right:0;width:70%;height:100%;background-color:rgba(153,153,153,0.5);overflow:hidden;opacity:0;pointer-events:none;transition:width .3s, opacity .3s}.container{position:absolute;top:50%;right:-20px;width:40%;height:80%;padding-right:20px;overflow:auto;-webkit-overflow-scrolling:touch;transform:translateY(-50%)}.closeBtn{position:absolute;top:0;right:0;width:50%;height:10%}.closeBtn:before{content:"";position:absolute;top:50%;right:0;width:100%;height:2px;transform:translateY(-50%);background-color:#642}.closeBtn:after{content:"";position:absolute;top:50%;left:10px;width:2px;height:50%;transform:translateY(-50%);background-color:#642;transition:left .2s}.closeBtn:hover:after{left:30px}.detailBtn{position:fixed;bottom:10%;right:10%;width:15%;height:10%;transition:opacity .2s}.detailBtn:before{content:"";position:absolute;top:50%;right:0;width:100%;height:2px;transform:translateY(-50%);background-color:#642}.detailBtn:after{content:"";position:absolute;top:50%;right:10px;width:2px;height:50%;transform:translateY(-50%);background-color:#642;transition:right .2s}.detailBtn:hover:after{right:30px}@media screen and (max-width: 767px){body.is-open .wrapper{height:100%}body.is-open .header{left:0}body.is-nav .wrapper{height:100%}body.is-nav .header{height:100%}canvas.pcCanvas{left:0% !important;z-index:1 !important}.wrapper{position:fixed;top:0;left:0;z-index:2;width:0;height:0;overflow:hidden;background-color:#ccc;transition:width .3s}.navBtn{display:block;position:fixed;top:10px;right:10px;width:50px;height:50px;cursor:pointer}.navBtn:before{content:"";position:absolute;top:50%;left:0;width:100%;height:2px;background-color:#642}.navBtn:after{content:"";position:absolute;top:0;left:50%;width:2px;height:100%;background-color:#642}.header{width:100%;height:0;overflow:hidden;transition:width .3s, left .3s, height .3s}.header nav li span{font-size:13px;font-size:1.625rem}main.main{width:100%}.container{right:50%;width:80%;height:80%;padding-right:0;transform:translate(50%, -50%)}.closeBtn{position:absolute;top:0;right:auto;left:0;width:50%;height:10%}}
```

HTMlとCSSは作りましたが、このままではPlayCanvasにDOMを乗せられていません。
DOMを乗せるためにScriptsを作り、以下のコードをコピペします。

[index.js]

```js
var Index = pc.createScript('index');

Index.attributes.add("baseHtml", {type:"asset", assetType:"html"}); // 登録したhtmlを取得

Index.prototype.initialize = function() {
    var self = this; // this書き換え
    var canvas = document.getElementsByTagName("canvas")[0]; // canvasを取得
    canvas.classList.add("pcCanvas"); // canvasにclass名を指定
    var wrapper = document.createElement("div"); // div作成
    wrapper.classList.add("wrapper"); // 作成したdivにwrapperというclass名を指定
    wrapper.innerHTML = self.baseHtml._resources[0]; // 事前に登録していたhtmlをwrapperに流し込み
    document.body.appendChild(wrapper); // bodyにwrapperを追加
};
```

attributes.add();という言葉がありますが、これは属性設定ができます。
PlayCanvasのEditorから任意のデータを登録してScripts内で使用することができます。この機能は今後よく使う機能になってきます。
ここでは追加するためのHTMLを登録しています。

しかし、作成してもScriptsは正しく動作するわけではありません。
Entityに該当するScriptsを登録する必要があります。
今回はEntityのRootにScriptsを登録します。
以下の画像のように、Rootを選択したらインスペクターからADD COMPONENTをクリックし、Scriptsを選択します。

![D02BF065344EDE22949CF183FC689D7E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/87966068-cacd-a1ae-8430-fee2534addb0.png)

SCRIPTSの項目が追加されたら、ADD SCRIPTをクリックし、indexを選択します。
![45B2F5719EB760DC234C267E0F69D1A1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/04a1440c-dbeb-10bd-0320-bf4f48bc10e3.png)

これでindex.jsがEntityのRootに登録されました。
確認しましたら、登録されたindex.jsの名前の右のParseをクリックします。
Parseは登録されているjsを再度リロードしてくれます。
リロードすることで、attributes.add();で追加した属性設定の項目が表示されます。
![66E93CD1E5BD8CC7C3ADA9B9C1A1C099.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/25b683b6-a8a3-56f7-159f-1518bb9fdde6.png)

baseHTMLという属性にはHTMLを選択することができますので、先ほど作成したHTMLを登録します。
これでHTMLは登録されましたが、CSSが登録されていませんので、HTMLと同じようにCSSも追加していきます。

setCss.jsというscriptを作って以下のコードをコピペします。

[setCss.js]

```js
var SetCss = pc.createScript('setCss');

SetCss.attributes.add("setCSS", {type:"asset", assetType:"css"});

SetCss.prototype.initialize = function() {
    var css = document.createElement("style");
    css.innerHTML = this.setCSS._resources[0];
    
    document.head.appendChild(css);
};

```

scriptを作ったら、先ほどと同じようにEntityのRootにScriptを登録してParseしてCSSを登録します。
以下のようになりましたら問題ありません。
![D2A69C9449814695FC7837E6324434B0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109168/ca3006fa-5772-ce74-20ac-d28c8a884e4d.png)


Lauchして確認してみますと、DOMが追加されたのが確認できたかと思います。

[次からEntityを増やして、Vue.jsを使って3Dモデルを切り替えるようにします。](https://qiita.com/sutobu000/items/2589db19a66d8deb8637)