页面上的按钮与场景中的物体实现交互
实际开发的时候,往往会通过前端的 HTML、CSS 代码创建按钮等交互界面,用来与 3D 场景交互
如果你是用 vue 或 react 开发 web3d 项目,也可以不用 HTML、CSS 自己写,也可以使用 UI 组件库
点击页面上的按钮改变 Mesh 颜色
html
<div id="red">红色</div>
<div id="green">绿色</div>
通过按钮与 3D 场景交互,改变 mesh 颜色
js
document.getElementById('red').addEventListener('click', () => {
Model.material.color.set(0xff0000);
});
document.getElementById('green').addEventListener('click', () => {
Model.material.color.set(0x00ff00);
});
完整代码
index.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="left">1</div>
<div class="right">
<div class="top">2</div>
<div id="red">红色</div>
<div id="green">绿色</div>
<div class="bottom" id="three"></div>
</div>
</div>
<script type="importmap">
{
"imports": {
"three": "../../build/three.module.js",
"three/addons/": "../../examples/jsm/"
}
}
</script>
<script src="./index.js" type="module"></script>
</body>
</html>
<style>
* {
margin: 0;
padding: 0;
overflow: hidden;
}
.container {
display: flex;
height: 100vh;
}
.container .left {
width: 200px;
background-color: blue;
}
.container .right .top {
width: calc(100vw - 200px);
height: 100px;
background-color: red;
}
.container .right .bottom {
height: calc(100vh - 100px);
background-color: gray;
width: calc(100vw - 200px);
}
#red,
#green {
position: absolute;
color: #fff;
top: 75%;
width: 50px;
height: 30px;
background-color: brown;
text-align: center;
line-height: 30px;
border-radius: 10px;
padding: 5px 10px;
cursor: pointer;
}
#red {
left: 50%;
}
#green {
left: 57%;
}
</style>
index.js
js
import * as THREE from 'three';
import Model from './model.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const width = window.innerWidth - 200;
const height = window.innerHeight - 100;
const scene = new THREE.Scene();
scene.add(Model);
const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 1000);
camera.position.set(300, 300, 300);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
const render = () => {
renderer.render(scene, camera);
window.requestAnimationFrame(render);
};
render();
new OrbitControls(camera, renderer.domElement);
document.getElementById('three').appendChild(renderer.domElement);
document.getElementById('red').addEventListener('click', () => {
Model.material.color.set(0xff0000);
});
document.getElementById('green').addEventListener('click', () => {
Model.material.color.set(0x00ff00);
});
window.onresize = () => {
const width = window.innerWidth - 200;
const height = window.innerHeight - 100;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
};
model.js
js
import * as THREE from 'three';
const geometry = new THREE.BoxGeometry(50, 50, 50);
const material = new THREE.MeshBasicMaterial({
color: 0x0000ff,
});
const mesh = new THREE.Mesh(geometry, material);
export default mesh;