<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>点击事件
<script src="../build/three.min.js">
<script src="./js/controls/TrackballControls.js">
<script src="./js/libs/dat.gui.min.js">
<script src="./js/libs/stats.min.js">
<div id="WebGL-output">
<div id="Stats-output">
<div id="label">
<script type="module">
import {GUI }from './jsm/libs/dat.gui.module.js';
var stats =initStats();
var scene, camera, renderer, controls, light, selectObject;
// 场景
function initScene() {
scene =new THREE.Scene();
}
// 相机
function initCamera() {
camera =new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.set(0, 400, 600);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
// 渲染器
function initRenderer() {
renderer =new THREE.WebGLRenderer({antialias:true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x050505);
document.body.appendChild(renderer.domElement);
}
// 初始化模型
function initContent() {
var helper =new THREE.GridHelper(1200, 50, 0xCD3700, 0x4A4A4A);
scene.add(helper);
var cubeGeometry =new THREE.BoxGeometry(100, 100, 100);
var cubeMaterial =new THREE.MeshLambertMaterial({color:0x9370DB});
var cube =new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.y =50;
cube.name ="cube";
scene.add(cube);
var sphereGeometry =new THREE.SphereGeometry(50, 50, 50, 50);
var sphereMaterial =new THREE.MeshLambertMaterial({color:0x3CB371});
var sphere =new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x =200;
sphere.position.y =50;
sphere.name ="sphere";
// sphere.position.z = 200;
scene.add(sphere);
var cylinderGeometry =new THREE.CylinderGeometry(50, 50, 100, 100);
var cylinderMaterial =new THREE.MeshLambertMaterial({color:0xCD7054});
var cylinder =new THREE.Mesh(cylinderGeometry, cylinderMaterial);
cylinder.position.x = -200;
cylinder.position.y =50;
cylinder.name ="cylinder";
// cylinder.position.z = -200;
scene.add(cylinder);
}
// 鼠标双击触发的方法
function onMouseDblclick(event) {
// 获取 raycaster 和所有模型相交的数组,其中的元素按照距离排序,越近的越靠前
var intersects =getIntersects(event);
// 获取选中最近的 Mesh 对象
if (intersects.length !=0 && intersects[0].objectinstanceof THREE.Mesh) {
selectObject = intersects[0].object;
changeMaterial(selectObject);
}else {
alert("未选中 Mesh!");
}
}
// 获取与射线相交的对象数组
function getIntersects(event) {
event.preventDefault();
// 声明 raycaster 和 mouse 变量
var raycaster =new THREE.Raycaster();
var mouse =new THREE.Vector2();
// 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
mouse.x = (event.clientX / window.innerWidth) *2 -1;
mouse.y = -(event.clientY / window.innerHeight) *2 +1;
//通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
raycaster.setFromCamera(mouse, camera);
// 获取与射线相交的对象数组,其中的元素按照距离排序,越近的越靠前
var intersects = raycaster.intersectObjects(scene.children);
//返回选中的对象
return intersects;
}
// 窗口变动触发的方法
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// 键盘按下触发的方法
function onKeyDown(event) {
switch (event.keyCode) {
case 13:
initCamera();
initControls();
break;
}
}
// 改变对象材质属性
function changeMaterial(object) {
var material =new THREE.MeshLambertMaterial({
color:0xffffff * Math.random(),
transparent: object.material.transparent ?false :true,
opacity:0.8
});
object.material = material;
}
// 初始化轨迹球控件
function initControls() {
controls =new THREE.TrackballControls(camera, renderer.domElement);
// controls.noRotate = true;
controls.noPan =true;
}
// 初始化灯光
function initLight() {
light =new THREE.SpotLight(0xffffff);
light.position.set(-300, 600, -400);
light.castShadow =true;
scene.add(light);
scene.add(new THREE.AmbientLight(0x5C5C5C));
}
// 初始化 dat.GUI
function initGui() {
// 保存需要修改相关数据的对象
const gui =new GUI();
// 属性添加到控件
var guiControls =new GUI();;
}
// 初始化性能插件
function initStats() {
var stats =new Stats();
stats.domElement.style.position ='absolute';
stats.domElement.style.left ='0px';
stats.domElement.style.top ='0px';
document.body.appendChild(stats.domElement);
return stats;
}
// 更新控件
function update() {
stats.update();
controls.update();
controls.handleResize();
}
// 初始化
function init() {
initScene();
initCamera();
initRenderer();
initContent();
initLight();
initControls();
initGui();
addEventListener('dblclick', onMouseDblclick, false);
addEventListener('resize', onWindowResize, false);
addEventListener('keydown', onKeyDown, false);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
update();
}
init();
animate();