2020/05/22 20:01
Vue(Nuxt)でBlenderから書き出したglTFファイルを表示させるコーディング例
以前にgltfファイルをWP等で表示させる方法を書いたのですが、今回はVueバージョンです。
ちなみにNuxtを使った時の書き方になるので、生のVueとはちょっと違う点もあるかもしれません。
取り合えずこの方法で表示はできました!っていうコーディング例となります。
Nuxtの記述とかは割愛します
PHPerの私がいきなりVue関連の記事とかを上げるのはちょっと抵抗ありましたが、案件で仕方なくNuxtをさわっているついでで、以前にやったBlenderからglTFファイル書き出して表示させるっていうやり方のおさらいになったので。
ちなみにVueやNuxtについてのレクチャーは今回一切ありませんのでご了承ください。
ちなみに以前のgltfファイルを読み込ませる記事はコチラ
BlenderでglTFファイルとしてエクスポートしてWebGL(ThreeJS)を使ってサイト上に表示させる方法
https://phper.pro/483
Threejs系のモジュールのインストール
どれがいいのか分からなくて私は何種類かインストールしたんですが…
恐らくコレでいけるんじゃないかと。
【コマンドプロンプト】
npm i three
これでpackage.jsonにthreeナントカってのが何かしら追記されればOKかと思います。
Vueの記述例
後は以前の記事同様に「gltf」ファイルを用意して、それを読み込ませる記述を書いて、その他のアニメーションやらカメラやら照明やらの設定をすればOKです。
記述例はコチラ。
【〇〇.vue】
<template>
<div id="scene-container" ref="sceneContainer" />
</template>
<script>
import Vue from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
export default Vue.extend({
data () {
return {
container: null,
scene: null,
renderer: null,
camera: null,
controls: null,
url: null,
width: null,
height: null,
mouseX: 0,
rot: 0,
targetRot: null,
radian: null,
directionalLight: null
};
},
created () {
},
mounted () {
this.init();
},
methods: {
init () {
// set container
this.container = this.$refs.sceneContainer;
// add camera
this.width = this.container.clientWidth;
this.height = this.container.clientHeight;
if (this.width < 768) {
this.width = this.container.clientWidth;
this.height = this.container.clientHeight;
}
const fov = 45; // Field of view
const aspect = this.width / this.height;
const near = 0.001; // the near clipping plane
const far = 10000; // the far clipping plane
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 0);
this.camera = camera;
// create scene
this.scene = new THREE.Scene();
// light
const directionalLight = new THREE.DirectionalLight(0xFFFFFF);
directionalLight.position.set(1, 1, 1);
this.scene.add(directionalLight);
// add controls
this.controls = new OrbitControls(this.camera, this.container);
this.controls.enableDamping = true;
this.controls.dampingFactor = 0.2;
// create renderer
this.renderer = new THREE.WebGLRenderer({ alpha: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.gammaFactor = 2.2;
this.renderer.outputEncoding = THREE.sRGBEncoding;
this.renderer.physicallyCorrectLights = true;
this.container.appendChild(this.renderer.domElement);
// set aspect ratio to match the new browser window aspect ratio
this.camera.aspect = this.width / this.height;
this.camera.updateProjectionMatrix();
this.renderer.setSize(this.width, this.height);
const loader = new GLTFLoader();
const url = "http://localhost:3000/threejs/【ファイル】.gltf";
loader.load(url, (data) => {
const gltf = data;
const object = gltf.scene;
this.scene.add(object);
});
const eventHandler = () => {
this.mouseX = event.pageX;
};
// マウス座標はマウスが動いた時のみ取得できる
document.addEventListener("mousemove", eventHandler);
const tick = () => {
this.renderer.render(this.scene, this.camera);
this.targetRot = (this.mouseX / this.container.clientWidth) * 360;
this.rot += (this.targetRot - this.rot) * 0.02;
this.radian = (this.rot * Math.PI) / 180;
// 角度に応じてカメラの位置を設定
this.camera.position.x = 0.1 + 0.05 * Math.sin(this.radian);
this.camera.position.y = 0.00 + 0.05 * Math.sin(this.radian);
this.camera.position.z = 0.3 + 0.001 * Math.cos(this.radian);
this.scene.rotation.y += 0.005;
// camera.lookAt(new THREE.Vector3(0, 0, 0));
this.controls.update();
requestAnimationFrame(tick);
};
tick();
}
}
});
</script>
<style>
#scene-container {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
#scene-container canvas {
display: block !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate3d(-50%,-50%,0) perspective(0) !important;
margin: 0 !important;
padding: 0 !important;
z-index: 0;
}
</style>
なんせVue&Nuxt初心者なので書き方がどこまで合ってるのかは不明ですが、こんな感じで取り合えず表示させることはできました。
現場から以上です!
2141