DOMを乗せる
DOMを乗せるためのHTMLとCSSを作ります。
HTMLとCSSはPlayCanvasのAssetsから追加できます。
[+]ボタンをクリックし、該当する形式のファイルを選択します。
ファイル名は任意で構いませんが、以下にするとwebな感じですね。
- HTMLは「index」
- CSSは「style」
コードエディターからコードを書いて行きますが、
今回は事前に用意していますので、こちらをコピペして使用します。
[index.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]
/* --- reset.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%}}
/* --- style.css --- */
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%}}
style.cssはminifyされているため読めないかもしれません。
どうしても自分でここは変更したいという場合には、別途Projectにminifyしていないcssがありますのでご参照ください。
https://playcanvas.com/project/644378/overview/3dmodelviewer_playcanvassite
HTMLとCSSは作りましたが、このままではPlayCanvasにDOMを乗せられていません。
DOMを乗せるためにScriptsを作り、以下のコードをコピペします。
[index.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を追加
};
Index.prototype.swap = function(old) {};
attributes.add();という言葉がありますが、これは属性設定ができます。
PlayCanvasのEditorから任意のデータを登録してScripts内で使用することができます。この機能は今後よく使う機能になってきます。
ここでは追加するためのHTMLを登録しています。
しかし、作成してもScriptsは正しく動作するわけではありません。
Entityに該当するScriptsを登録する必要があります。
今回はEntityのRootにScriptsを登録します。
以下の画像のように、Rootを選択したらインスペクターからADD COMPONENTをクリックし、Scriptsを選択します。
SCRIPTSの項目が追加されたら、ADD SCRIPTをクリックし、indexを選択します。
これでindex.jsがEntityのRootに登録されました。
確認しましたら、登録されたindex.jsの名前の右のParseをクリックします。
Parseは登録されているjsを再度リロードしてくれます。
リロードすることで、attributes.add();で追加した属性設定の項目が表示されます。
baseHTMLという属性にはHTMLを選択することができますので、先ほど作成したHTMLを登録します。
これでHTMLは登録されましたが、CSSが登録されていませんので、HTMLと同じようにCSSも追加していきます。
setCss.jsというscriptを作って以下のコードをコピペします。
[setCss.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を登録します。
以下のようになりましたら問題ありません。
Lauchして確認してみますと、DOMが追加されたのが確認できたかと思います。
次はEntityを増やして、Vue.jsを使って3Dモデルを切り替えるようにします。
Vue.jsで3Dモデルを切り替える
現在は3Dモデルが一つだけしか確認することができないので、複数の3Dモデルを追加します。
ヒエラルキーからEntityを追加していきます。
ヒエラルキー上部の[+]ボタンか右クリックからAdd Entity → Entityを選択します。
「New Entity」という名前で追加されたと思います。
Entitiesなど任意の名前に変更などして差別化します。
Entitiesの中にModelを追加します。
ヒエラルキーのModelをDrag&DropでEntitiesの中に追加します。
3Dモデルを複数使用したいため、先ほどのModelを複製、またはPrimitiveなBoxなどを追加します。
複製はEntityを選択して、ヒエラルキー上部のDuplicate Entityをクリック。
Primitiveを追加するにはAdd EntityからPrimitiveを選択します。
上記の操作を行うと以下のようになります。
追加したモデルが重なり合っていますので、追加したEntities内のEntityのインペクターからEnabledのチェックを外し非表示にしておきます。
3Dモデルを追加できたら、次はVue.jsを使ってそれらを操作していきます。
Vue.jsを使うために、PlayCanvasにVue.jsのCDNを使います。
EXTERNAL SCRIPTSという項目がありますのでこちらから登録します。
Vue.js CDN : https://cdn.jsdelivr.net/npm/vue@2.6.14
Vue.jsを書いていく前に、Vue.jsがわからない人のために簡単に説明をします。
Vue.jsはプログレッシブフレームワークと言われるライブラリとフレームワークの中間のもので、フレームワークとは異なり適所に少しずつVueを適用することができます。
詳しく知りたい方はVue.jsの公式ページから参照いただけたらと思います。
https://jp.vuejs.org/
Vueを使って切り替えるために、index.jsをいかに書き換えます。
[index.js]
var Index = pc.createScript('index');
Index.attributes.add("baseHtml", {type:"asset", assetType:"html"}); // 登録したhtmlを取得
Index.attributes.add("target", {type:"entity"}); // 参照するEntityを登録
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を追加
var nowEntity = ""; // どのEntityが選択されているか保管
var app = new Vue({ // Vue呼び出し
el: '#app', // id名がappの要素を参照
data: { // 使用するdataを登録
clickFlag: false, // クリックされたか
entities: self.target.children // 属性で追加したEntityの子どもを参照
},
methods: { // イベントハンドラ作成
onEntityClick: function(target,index) { // Entityを選択された時
var v_self = this; // thisを保管
if(nowEntity){
nowEntity.enabled = false; // 今表示されているEntityを非表示に
}
target.enabled = true; // 選択したEntityを表示
nowEntity = target; // 選択したEntityを保管
}
}
});
};
Index.prototype.swap = function(old) {};
属性を追加したので、EntityのRootからindex.jsをParseします。
Parseしたら属性のtargetにEntitiesを登録します。
Vueを使ってイベントハンドラを作っていますので、これをHTML側で使用します。
index.htmlをいかに書き換えます。
[index.html]
<div id="app">
<header class="header">
<nav>
<ol>
<li v-for="(entity,index) in entities" @click="onEntityClick(entity,index)" ><span>{{entity.name}}</span></li>
</ol>
</nav>
</header>
<main class="main">
<div class="container">
<section>content01</section>
<section>content01</section>
<section>content01</section>
</div>
</main>
</div>
ここで、index.jsで呼び出したVueのdataが確認できます。
entitiesというのが、index.jsで属性追加したEntityです。
それをv-forを使って一つずつ呼び出しています。
呼び出すli要素にはonEntityClickを@clickのクリックイベントで呼び出すように書き加えています。
これでLaunchを確認すると、先ほど設定した属性要素のEntitiesの子要素であるEntityの名前が並んでいます。
これらをクリックするとクリックしたモデルに変更されるのが確認できます。
EditorからEntitiesにEntityを追加すると、PlayCanvasのリアルタイムレンダリングによりLaunchをリロードしなくても追加されます。
試しにEntitiesにPrimitiveを追加してみるとわかりやすいでしょう。
Vueを使って3Dモデルの切り替えができましたが、
パッと切り替わってしまうので見応えがありません。
そこで、切り替わる際にアニメーションを入れたいと思います。
コメント
0件のコメント
サインインしてコメントを残してください。