はじめに
HTML+JavaScript版:【メモ】Three.jsでObjectのTextureを切り替える
↑をVue.jsでやってみた。
プロジェクトセットアップ
$vue create change_texture_vue
$cd change_texture_vue
$npm install three
$npm run serve
今回はコントローラは使わない。
App.vueからHelloWorld部分を削除して、新しく TextureChange.vue
コンポーネントをインポートする。
ソースコード
基本的にはHTML+JavaScript版と同じ。ちょっとVue仕様に変更しただけ。
Sceneはbodyのchildとしてぶち込んでるけど、レイアウト綺麗にしたいならdivタグとかのchildにしたらいいのかも。
TextureChange.vue
<template>
<div>
<select @change="changeImage">
<option :value="logoURL" selected>Vue logo</option>
<option :value="goriURL">Gori</option>
</select>
</div>
</template>
<script>
import * as THREE from 'three'
export default {
name: 'textureChange',
data() {
const width = 600;
const height = 400;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
const cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
const logoURL = require('@/assets/logo.png'); // need require when local image
const goriURL = require('@/assets/gori128.png');
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
return {
width,
height,
scene,
camera,
cubeGeometry,
cube,
logoURL,
goriURL,
renderer,
}
},
mounted() {
this.initialize()
},
methods: {
initialize() {
// camera
this.camera.position.set(0, 0, 10)
// renderer
this.renderer.setSize(this.width, this.height);
this.renderer.setClearColor({ color: 0x000000 });
// cube
const cubeMaterial = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load(this.logoURL),
})
cubeMaterial.needsUpdate = true;
this.cube = new THREE.Mesh(this.cubeGeometry, cubeMaterial);
this.cube.name = 'cube'; // need name to find object afterwards
this.scene.add(this.cube);
this.renderer.render(this.scene, this.camera);
document.body.appendChild(this.renderer.domElement);
this.render();
},
render() {
this.cube.rotation.x += 0.1;
this.cube.rotation.y += 0.1;
requestAnimationFrame(this.render);
this.renderer.render(this.scene, this.camera);
},
changeImage(e) {
const image = e.target.value;
const object = this.scene.getObjectByName('cube'); // find obj by name
object.material.map = new THREE.TextureLoader().load(image);
object.material.needsUpdate = true;
},
},
}
</script>
結果
- Vueのロゴが表示される