Javascript 在Vuetify.js组件中加载三个.js场景
我正在尝试将一个基本的Javascript 在Vuetify.js组件中加载三个.js场景,javascript,vue.js,vuejs2,three.js,vuetify.js,Javascript,Vue.js,Vuejs2,Three.js,Vuetify.js,我正在尝试将一个基本的Three.js场景加载到Vuetifyv-app组件中,但我似乎无法让它工作 使用vue、vue路由器和three js,因此消除Vuetify我在“Hello World”类型场景中加载时没有任何问题。如果您感兴趣,可以在此处找到此工作vuetify less尝试的代码 我已经尝试使用路由检测器在检测到试图加载/viewer时消除v-app组件(在组件中使用v-if),但结果最好是劣质的(与3D查看器重叠的ui,一个不分大小的3D查看器,每次重新加载的结果基本上不同)
Three.js
场景加载到Vuetifyv-app
组件中,但我似乎无法让它工作
使用vue
、vue路由器
和three js
,因此消除Vuetify我在“Hello World”类型场景中加载时没有任何问题。如果您感兴趣,可以在此处找到此工作vuetify less尝试的代码
我已经尝试使用路由检测器在检测到试图加载/viewer
时消除v-app
组件(在组件中使用v-if
),但结果最好是劣质的(与3D查看器重叠的ui,一个不分大小的3D查看器,每次重新加载的结果基本上不同)
我的当前代码由Navbar.vue
组件、App.vue
和Viewer.vue
视图组成。我还启用了vue路由器
,该路由器按预期工作。
我目前正在使用的最小项目,试图让vuetify与Three.js一起工作:
Viewer.vue
<template>
<div id="container"></div>
</template>
<script>
import * as THREE from "three";
export default {
name: "ThreeTest",
data() {
return {
cube: null,
renderer: null,
scene: null,
camera: null,
};
},
methods: {
init: function () {
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
this.renderer = new THREE.WebGLRenderer();
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement);
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
this.cube = new THREE.Mesh(geometry, material);
this.scene.add(this.cube);
this.camera.position.z = 5;
},
animate: function () {
requestAnimationFrame(this.animate);
this.cube.rotation.x += 0.01;
this.cube.rotation.y += 0.01;
this.renderer.render(this.scene, this.camera);
},
},
mounted() {
this.init();
this.animate();
},
};
</script>
从“三”中导入*作为三;
导出默认值{
名称:“三个测试”,
数据(){
返回{
多维数据集:null,
渲染器:null,
场景:空,
摄像机:空,
};
},
方法:{
init:函数(){
this.scene=新的三个.scene();
this.camera=新的3.perspective相机(
75,
window.innerWidth/window.innerHeight,
0.1,
1000
);
this.renderer=new THREE.WebGLRenderer();
this.renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(this.renderer.doElement);
const geometry=新的3.BoxGeometry(1,1,1);
const material=new THREE.MeshBasicMaterial({color:0x00ff00});
this.cube=新的三个网格(几何体、材质);
this.scene.add(this.cube);
这个.camera.position.z=5;
},
设置动画:函数(){
requestAnimationFrame(this.animate);
这个.cube.rotation.x+=0.01;
这个.cube.rotation.y+=0.01;
this.renderer.render(this.scene,this.camera);
},
},
安装的(){
this.init();
这个。动画();
},
};
导航栏
<template>
<div>
<v-app-bar app clipped-left flat dark>
<v-toolbar-title>
<span class="first-word font uppercase">stp</span>
<span class="second-word font uppercase">upload</span>
</v-toolbar-title>
<v-spacer></v-spacer>
</v-app-bar>
<v-navigation-drawer app clipped flat dark expand-on-hover>
<v-list>
<v-list-item class="px-2">
<v-list-item-avatar>
<v-img src="https://randomuser.me/api/portraits/men/11.jpg"></v-img>
</v-list-item-avatar>
<v-list-item-title>
<span class="username">{{ username }}</span>
</v-list-item-title>
</v-list-item>
<v-list-item v-for="item in navbarlist" :key="item.route" :to="item.route">
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>{{ item.text }}</v-list-item-content>
</v-list-item>
</v-list>
<template v-slot:append>
<v-list>
<v-list-item @click="logout()">
<v-list-item-icon>
<v-icon color="red">mdi-logout</v-icon>
</v-list-item-icon>
<v-list-item-content>Logout</v-list-item-content>
</v-list-item>
</v-list>
</template>
</v-navigation-drawer>
</div>
</template>
<script>
export default {
data: () => ({
drawer: true,
navbarlist: [
{ icon: "mdi-view-dashboard", text: "Dashboard", route: "/" },
{ icon: "mdi-upload", text: "Upload", route: "/upload" },
{ icon: "mdi-video-3d", text: "Viewer", route: "/viewer" },
],
username: "",
}),
created: function () {
this.username = this.$store.state.userProfile.name;
},
methods: {
logout() {
this.$store.dispatch("logout", {});
},
},
};
</script>
<style>
.font {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
.uppercase {
text-transform: uppercase;
}
.first-word {
font-weight: 400;
}
.second-word {
font-weight: 200;
color: grey;
}
.item-tile-icon {
color: black;
}
.username {
color: whitesmoke;
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
font-weight: lighter;
letter-spacing: 0.001em;
}
</style>
stp
上传
{{username}}
{{item.icon}
{{item.text}
mdi注销
注销
导出默认值{
数据:()=>({
抽屉:是的,
导航栏列表:[
{图标:“mdi视图仪表板”,文本:“仪表板”,路径:“/”},
{图标:“mdi上传”,文本:“上传”,路由:“/upload”},
{图标:“mdi-video-3d”,文本:“查看器”,路径:“/Viewer”},
],
用户名:“”,
}),
已创建:函数(){
this.username=this.$store.state.userProfile.name;
},
方法:{
注销(){
这是.store.dispatch(“注销”{});
},
},
};
.font{
字体系列:-苹果系统、BlinkMacSystemFont、“Segoe UI”、机器人、氧气、,
Ubuntu,坎塔雷尔,“开放式Sans”,“Helvetica Neue”,无衬线;
}
.大写字母{
文本转换:大写;
}
.第一个字{
字体大小:400;
}
.第二个字{
字号:200;
颜色:灰色;
}
.项目平铺图标{
颜色:黑色;
}
.用户名{
颜色:白烟;
字体系列:“富兰克林哥特式中”、“Arial窄”、Arial、无衬线;
字体重量:较轻;
字母间距:0.001em;
}
App.vue
<template>
<div>
<v-app>
<Navbar v-if="showNavBar"/>
<v-main>
<router-view></router-view>
</v-main>
</v-app>
</div>
</template>
<script>
import Navbar from "./components/Navbar";
export default {
name: "App",
components: {
Navbar,
},
data: () => ({
showNavBar: true,
app: true
}),
mounted() {
}
};
</script>
从“/components/Navbar”导入导航栏;
导出默认值{
名称:“应用程序”,
组成部分:{
导航栏,
},
数据:()=>({
showNavBar:是的,
app:true
}),
安装的(){
}
};
如果我积极帮助用户,我不知道为什么人们会热衷于删除我的答案。如果我不能评论,我不能评论,我的规则不是我必须有声誉才能发表评论,而是必须写一个答案
关于这个问题:
您需要将dom元素不是附加到document.body,而是附加到vue组件中的实际div
因此,不是:
document.body.appendChild(this.renderer.domElement);
请使用:
document.getElementById('container').appendChild(this.renderer.domElement);