<!DOCTYPE html>
<html lang="en">
? <meta charset="UTF-8">
? <title>點(diǎn)擊事件
? <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();
? }
// 相機(jī)
? 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);
? }
// 鼠標(biāo)雙擊觸發(fā)的方法
? function onMouseDblclick(event) {
// 獲取 raycaster 和所有模型相交的數(shù)組矢否,其中的元素按照距離排序骇两,越近的越靠前
? ? ? var intersects =getIntersects(event);
? ? ? // 獲取選中最近的 Mesh 對象
? ? ? if (intersects.length !=0 && intersects[0].objectinstanceof THREE.Mesh) {
selectObject = intersects[0].object;
? ? ? ? changeMaterial(selectObject);
? ? ? }else {
alert("未選中 Mesh!");
? ? ? }
}
// 獲取與射線相交的對象數(shù)組
? function getIntersects(event) {
event.preventDefault();
? ? ? // 聲明 raycaster 和 mouse 變量
? ? ? var raycaster =new THREE.Raycaster();
? ? ? var mouse =new THREE.Vector2();
? ? ? // 通過鼠標(biāo)點(diǎn)擊位置,計(jì)算出 raycaster 所需點(diǎn)的位置,以屏幕為中心點(diǎn),范圍 -1 到 1
? ? ? mouse.x = (event.clientX / window.innerWidth) *2 -1;
? ? ? mouse.y = -(event.clientY / window.innerHeight) *2 +1;
? ? ? //通過鼠標(biāo)點(diǎn)擊的位置(二維坐標(biāo))和當(dāng)前相機(jī)的矩陣計(jì)算出射線位置
? ? ? raycaster.setFromCamera(mouse, camera);
? ? ? // 獲取與射線相交的對象數(shù)組,其中的元素按照距離排序,越近的越靠前
? ? ? var intersects = raycaster.intersectObjects(scene.children);
? ? ? //返回選中的對象
? ? ? return intersects;
? }
// 窗口變動觸發(fā)的方法
? function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
? ? ? camera.updateProjectionMatrix();
? ? ? renderer.setSize(window.innerWidth, window.innerHeight);
? }
// 鍵盤按下觸發(fā)的方法
? function onKeyDown(event) {
switch (event.keyCode) {
case 13:
initCamera();
? ? ? ? ? ? initControls();
? ? ? ? ? ? break;
? ? ? }
}
// 改變對象材質(zhì)屬性
? 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() {
// 保存需要修改相關(guān)數(shù)據(jù)的對象
? ? ? 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();