户型图
效果图
核心代码
<script>
var vm = new Vue({
el: "#app",
data: {
test: "改变相机位置",
scene: '',
renderer: "",
camera: "",
controls: "", // 鼠标控件
fh: 2, // 地面高度
wallHeight: 12,
wallWeight: 1,
angle: 0,
roam: false, // 漫游 开启漫游状态时应该禁用一切
},
methods: {
// 初始化场景
initScene() {
this.scene = new THREE.Scene()
},
// 初始化相机
initCamera(w = 500, h = 500) {
var camera = new THREE.PerspectiveCamera(45, w / h, 0.1, 10000);
camera.position.set(100, 100, 100);
camera.lookAt(100,-200,800);
this.camera = camera
},
initRenderer(w = 500, h = 500) {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(w, h);
renderer.setClearColor(0x4682B4, 1.0);
document.getElementById("3dAPP").appendChild(renderer.domElement);
this.renderer = renderer
},
// 初始化灯光
initLight() {
var directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 模拟远处类似太阳的光源
directionalLight.color.setHSL(0.1, 1, 0.95);
directionalLight.position.set(0, 200, 0).normalize();
this.scene.add(directionalLight);
var ambient = new THREE.AmbientLight(0xffffff, 1); // AmbientLight 影响整个场景的光源
ambient.position.set(0, 0, 0);
this.scene.add(ambient);
},
// 初始化轨迹球控件 鼠标控件
initControls() {
var controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.5;
// 视角最小距离
controls.minDistance = 0;
// 视角最远距离
controls.maxDistance = 5000;
controls.enableKeys = true;
// 最大角度
// controls.maxPolarAngle = Math.PI / 2;
controls.target = new THREE.Vector3(10, 10, 10);
this.controls = controls
console.log(controls)
},
// 地面
createFloor() {
var loader = new THREE.TextureLoader();
var floor, floor1;
loader.load("./img/cz.jpg", (texture) => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(30, 30);
var floorGeometry = new THREE.BoxGeometry(100, 100, this.fh);
var floorMaterial = new THREE.MeshBasicMaterial({
map: texture,
});
floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.rotation.x = -Math.PI / 2;
floor.position.set(0, 0, 0)
floor.name = "地面";
this.scene.add(floor);
});
},
/**
* @param i 某一块墙
* @param wallHeight 墙高
*
*/
createwall(i,width=100, wallHeight = this.wallHeight, wallWeight = this.wallWeight) {
var Geometry = new THREE.BoxGeometry(width, wallHeight, wallWeight);
var mtl = []
for (let i = 0; i < Geometry.faces.length; i++) {
mtl.push(
new THREE.MeshBasicMaterial({
color: new THREE.Color(Math.random() * 0xffffff)
})
)
}
var mesh = new THREE.Mesh(Geometry, mtl)
/*
刚好在地面
模型自身高度 h0
地面高度 h1
(地面高度 + 模型高度) / 2 即 (h0+h1)/2
*/
mesh.name = `wall${i}`
switch (i) {
case 1:
mesh.position.set(0, (this.fh + wallHeight) / 2, 24.5)
break;
case 2:
mesh.position.set(0, (this.fh + wallHeight) / 2, -24.5)
break;
case 3:
mesh.rotation.y = Math.PI/2
mesh.position.set(41.5, (this.fh + wallHeight) / 2, 0)
break;
case 4:
mesh.rotation.y = Math.PI/2
mesh.position.set(-41.5, (this.fh + wallHeight) / 2, 0)
break;
case 5:
mesh.rotation.y = Math.PI/2
mesh.position.set(-24, (this.fh + wallHeight) / 2, 0)
break;
case 6:
mesh.position.set(-33, (this.fh + wallHeight) / 2, -2)
break;
case 7:
mesh.rotation.y = Math.PI/2
mesh.position.set(-11, (this.fh + wallHeight) / 2, -13)
break;
case 8:
mesh.position.set(-17.5, (this.fh + wallHeight) / 2, -12)
break;
case 9:
mesh.position.set(15, (this.fh + wallHeight) / 2, -2)
break;
case 10:
mesh.rotation.y = Math.PI/2
mesh.position.set(3, (this.fh + wallHeight) / 2, -13)
break;
case 11:
mesh.position.set(9, (this.fh + wallHeight) / 2, -12)
break;
case 12:
mesh.rotation.y = Math.PI/2
mesh.position.set(15, (this.fh + wallHeight) / 2, -18)
break;
case 13:
mesh.rotation.y = Math.PI/2
mesh.position.set(-11, (this.fh + wallHeight) / 2, 21)
break;
}
this.scene.add(mesh)
// console.log(Geometry)
},
// 模型
initContent() {
this.createFloor();
this.createwall(1, 84)
this.createwall(2, 84)
this.createwall(3, 50)
this.createwall(4, 50)
this.createwall(5, 50)
this.createwall(6, 18)
this.createwall(7, 23)
this.createwall(8, 13)
this.createwall(9, 53)
this.createwall(10,23)
this.createwall(11,13)
this.createwall(12,13)
this.createwall(13,8)
},
animate() {
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
this.update();
if(this.roam){
this.angle+=0.005
// 重新设置相机位置,相机在XOY平面绕着坐标原点旋转运动
this.camera.position.x=200*Math.sin(this.angle)
this.camera.position.z=200*Math.cos(this.angle)
this.camera.lookAt(0,0,0);
}
},
// 更新控件
update() {
// stats.update();
this.controls.update();
TWEEN.update();
},
init() {
this.initScene();
this.initCamera();
// 初始化渲染器
this.initRenderer(700, 700);
// 初始化模型
this.initContent();
// 初始化灯光
this.initLight();
this.initControls();
},
// changePOS() {
// this.camera.position.set(0, 300, 10)
// this.animate()
// }
},
mounted() {
this.init();
this.animate();
}
})
</script>