見出し画像

Vue 3 と Three.js で3D空間にHTMLを表示(HTMLMesh編)

Vue3とThree.jsで作った3D空間に、HTMLエレメントを表示する方法です。
Vue3 + Three.js|NAYUTA株式会社 シリーズ記事の第4弾です。
https://github.com/NAYUTA-tech/tutorial-three-vue にソースコードも公開しています。

今回作るもの

前回記事の続きです。
今回は、これまで作成してきた3D空間に、HTMLエレメントを3Dオブジェクトとして表示します。

前回読み込んだの店舗等の手前に表示された、回転するLorem ipsumとボタン

弱点

HTMLMeshには大きな弱点がありますので、先に挙げておきます。

  • iframeなど、使えないHTMLエレメントが多い

  • CSSで使えないスタイルが多い

ざっくりまとめると、あまり凝ったことはできないということですね。

手順

まず以下の2つをimportして、


import { HTMLMesh } from 'three/examples/jsm/interactive/HTMLMesh.js'
import { InteractiveGroup } from 'three/examples/jsm/interactive/InteractiveGroup.js'

関数を作って、

data() {
  // 略

  this.htmlMesh = null

  // 略

  return {}
},

mounted() {
  this.init()
  this.addModels()
  this.addHtmlMesh()  // これを追加
  this.animate()
},

methods() {
  // 略

  addHtmlMesh() {
    this.htmlMesh = new HTMLMesh(this.$refs.modalRef)
    this.htmlMesh.position.set(0, 5, 5)
    this.htmlMesh.scale.setScalar(10)

    // HTMLMeshはInteractiveGroupを経由しないとボタンも押せない
    const group = new InteractiveGroup(this.renderer, this.camera)
    group.add(this.htmlMesh)

    this.scene.add(group)
  },

  onClick() {
    alert('hello')
  },

  // 略
},

animate() {
  // 略

  this.htmlMesh.rotation.x += 0.01

  // 略
}

templateを書きます

<template>
  <div>
    <canvas ref="canvasRef" class="fullscreen"></canvas>
    <div ref="modalRef" class="modal3d">
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing<br />
        elit. Possimus expedita necessitatibus, at magni<br />
        optio sequi cumque repellat fugit rem ratione <br />
        laudantium perferendis officiis eveniet alias atque<br />
        debitis, itaque qui. Repellendus!
      </p>
      <button @click="onClick">Hello</button>
    </div>
  </div>
</template>

<style scoped>
/* 略 */

.modal3d {
  width: 400px;
  height: 200px;
  padding: 20px;
  border-width: 10px;
  border-color: white;
  border-style: solid;
  background-color: bisque;
}
</style>

以上、たったこれだけで、HTMLエレメントを3D空間上に表示できました。
回転してますが、頑張ってボタンを押すと、"hello"とアラート表示されると思います。

他の方法

実はThree.jsで3D空間にHTMLを表示する方法はHTMLMesh以外にもあって、それぞれ一長一短あります。
次回以降でそれらの紹介ができたらと考えていますが、ちょっとだけ先出ししておきますと、CSS3DRendererを使う方法や、力技でHTML要素を変形する方法があります。