I want to inquire about vue.js import three.js. My family contains three.js. The screen is displayed, but the model and any errors do not appear. I don’t know why.
<template>
<div id="scene-container">
<header class="title-wrapper move-ctrl">
<h1 class="title">Psychedelic</h1>
<h1 class="title">paint</h1>
</header>
<div class="subitle move-ctrl">
<h1 class="title">rhinoceros</h1>
</div>
<div class="rhinoceros-info move-ctrl">
<ul class="info-title">
<li>Artist: Henri-Alfred Jacquemart</li>
<li>Period: 1878</li>
<li>Material: Plaster</li>
<li>Location: Dépôt des sculptures de la Ville de Paris</li>
</ul>
</div>
<footer class="footer-wrapper move-ctrl">
<div class="title">reflection out</div>
</footer>
<div class="footer-subitle move-ctrl">
<h1 class="footrt-title footrt-title-size">2020</h1>
<div class="footer-info">
<h2>25-28 working</h2>
<h2>Psychedelic + rhinoceros</h2>
</div>
</div>
<div class="footer-cop move-ctrl">
<h3>3d model design</h3>
<h3>#Psychedelic-r2020</h3>
</div>
</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import * as Stats from "stats-js";
import { GUI } from "dat.gui";
export default {
name: "three",
data() {
return {
container: null,
camera: null,
renderer: null,
controls: null,
scene: null,
mesh: null,
stats: null
};
},
methods: {
init() {
this.container = this.$el;
this.scene = new THREE.Scene();
// Background Color背景顏色
this.scene.background = new THREE.Color(0x000000, 0);
// function 函數整理
this.createCamera();
this.createControls();
this.createLight();
this.meangerProgress();
this.loader();
this.createRenderer();
this.onWindowResize();
this.createGui();
this.regenerate();
},
// Create a Camera 建立相機
createCamera() {
this.camera = new THREE.PerspectiveCamera(
75, //FOV
window.innerWidth / window.innerHeight, //aspect
0.1, //near
1500 //far
);
this.camera.position.set(0, 0, 1000); // x,y,z
},
// Create a Controls 建立控制器
createControls() {
this.controls = new OrbitControls(this.camera, this.container);
this.controls.enableDamping = true;
this.controls.campingFactor = 0.25;
this.controls.enableZoom = true;
},
// Create a Lights 建立光源組
createLight() {
this.ambient = new THREE.AmbientLight(0xffffff);
this.keyLight = new THREE.DirectionalLight(
new THREE.Color("hsl(313, 100%, 83%)"),
3
);
this.keyLight.position.set(-100, 0, 200);
this.fillLight = new THREE.DirectionalLight(
new THREE.Color("hsl(181, 54%, 76%)"),
1
);
this.fillLight.position.set(100, 100, -500);
this.backLight = new THREE.DirectionalLight(0xffffff, 3.0);
this.backLight.position.set(100, 150, -150).normalize();
this.light1 = new THREE.PointLight(0xa2e2e3, 300, 1000);
this.light1.position.set(100, 230, 200);
this.light2 = new THREE.PointLight(0xa2e2e3, 200, 1000);
this.light2.position.set(100, -100, -300);
this.light3 = new THREE.PointLight(0xffffff, 100, 1000);
this.light3.position.set(-60, -100, 50);
this.light4 = new THREE.PointLight(0xfca4d3, 400, 1000);
this.light4.position.set(0, 180, 50);
this.light5 = new THREE.PointLight(0xa2e2e3, 400, 1000);
this.light5.position.set(250, 200, -150);
this.light6 = new THREE.PointLight(0xa2e2e3, 800, 1000);
this.light6.position.set(-200, 250, -350);
this.scene.add(
this.ambient,
this.light1,
this.light2,
this.light3,
this.light4,
this.light5,
this.light6
);
// pointLightHelper 輔助
this.sphereSize = 50;
this.pointLightHelper = new THREE.PointLightHelper(
this.light1,
this.sphereSize
);
this.pointLightHelper2 = new THREE.PointLightHelper(
this.light2,
this.sphereSize
);
this.pointLightHelper3 = new THREE.PointLightHelper(
this.light3,
this.sphereSize
);
this.pointLightHelper4 = new THREE.PointLightHelper(
this.light4,
this.sphereSize
);
this.pointLightHelper5 = new THREE.PointLightHelper(
this.light5,
this.sphereSize
);
this.pointLightHelper6 = new THREE.PointLightHelper(
this.light6,
this.sphereSize
);
this.scene.add(
this.pointLightHelper,
this.pointLightHelper2,
this.pointLightHelper3,
this.pointLightHelper4,
this.pointLightHelper5,
this.pointLightHelper6
);
},
meangerProgress() {
this.onProgress = function(xhr) {
if (xhr.lengthComputable) {
this.percentComplete = (xhr.loaded / xhr.total) * 100;
console.log(Math.round(this.percentComplete, 2) + "% downloaded");
}
};
this.onError = function() {};
this.manager = new THREE.LoadingManager();
},
loader() {
this.mtlLoader = new MTLLoader(this.manager);
this.mtlLoader.setResourcePath("../../public/models");
this.mtlLoader.setPath("../../public/models");
this.mtlLoader.load("rhinoceros-Psychedelic.mtl", function(materials) {
this.materials.preload();
this.objLoader = new OBJLoader(this.manager);
this.objLoader.setMaterials(materials);
this.objLoader.setPath("../../public/models");
this.objLoader.load(
"rhinoceros-Psychedelic.obj",
function(object) {
this.mesh = object;
this.scene.add(this.mesh);
},
this.onProgress,
this.onError
);
});
},
// Creat the Renderer 建立渲染器
createRenderer() {
this.renderer = new THREE.WebGLRenderer({ alpha: true });
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.gammaFactor = 2.2;
// this.renderer.gammaOutput = true;
this.renderer.physicallyCorrectLights = true;
this.container.appendChild(this.renderer.domElement);
this.stats = new Stats();
this.container.appendChild(this.stats.dom);
},
// animate 動畫執行
animate() {
requestAnimationFrame(this.animate);
this.render();
this.stats.update();
},
// render 渲染
render() {
// 物體旋轉 model rotation
if (this.mesh) {
this.mesh.rotation.y += this.Data.speed;
}
this.renderer.render(this.scene, this.camera);
window.addEventListener("resize", this.onWindowResize);
},
// RWD 螢幕偵測
onWindowResize() {
// console.log( '你調整瀏覽器大小了' );
this.camera.aspect = window.innerWidth / window.innerHeight;
// update the camera's frustum 相機錐角
this.camera.updateProjectionMatrix();
// update the size of the renderer AND the canvas
this.renderer.setSize(window.innerWidth, window.innerHeight);
},
createGui() {
// GUI Display
this.gui = new GUI();
// GUI Data 參數
this.Data = {
color: "#ffffff",
speed: -0.01
};
this.Folder = this.gui.addFolder("Rhinoceros");
// GUI Light
this.Folder.addColor(this.Data, "color")
.onChange(this.regenerate)
.name("Color");
this.Folder.add(this.Data, "speed", -0.01, -0.05).name("Speed");
this.Folder.open();
},
regenerate() {
this.keyLight = new THREE.DirectionalLight(this.Data.color, 1);
this.scene.add(this.keyLight);
}
},
mouted() {
this.init();
this.animate();
this.loader();
}
};
</script>
<style lang="scss" scoped>
#scene-container {
box-sizing: border-box;
position: relative;
width: 100%;
height: 100%;
.title {
font-size: 60px;
color: #fff;
font-family: "Bungee Outline", cursive;
}
.info-title {
font-size: 20px;
color: #fff;
}
.footrt-title-size {
font-size: 90px;
color: #fff;
font-family: "Bungee Outline", cursive;
letter-spacing: 20px;
}
.move-ctrl {
position: absolute;
}
.title-wrapper {
display: flex;
justify-content: space-between;
width: 97%;
margin: 110px 25px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
.subitle {
display: flex;
justify-content: flex-end;
width: 97%;
margin: 110px 25px;
top: 60px;
border-bottom: 1px solid #fff;
letter-spacing: 30px;
}
.rhinoceros-info {
margin: 110px 25px;
top: 150px;
ul {
li {
margin-bottom: 1rem;
}
}
}
.footer-wrapper {
display: flex;
justify-content: flex-end;
margin: 0 25px;
bottom: 200px;
width: 97%;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
letter-spacing: 10px;
}
.footer-subitle {
margin: 0 25px;
bottom: 110px;
width: 97%;
border-bottom: 1px solid #fff;
display: flex;
.footrt-title {
display: flex;
position: relative;
&:after {
content: "";
position: absolute;
top: 15px;
left: 350px;
width: 1px;
height: 60px;
background-color: #fff;
}
}
.footer-info {
display: flex;
flex-direction: column;
justify-content: center;
font-size: 40px;
color: #fff;
margin-left: 50px;
letter-spacing: 10px;
}
}
.footer-cop {
display: flex;
justify-content: space-between;
margin: 0 25px;
bottom: 50px;
width: 97%;
font-size: 40px;
color: #fff;
}
}
</style>