Three.js給模型添加點(diǎn)擊事件例子

<!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();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末醉者,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烂瘫,更是在濱河造成了極大的恐慌黔夭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溯祸,死亡現(xiàn)場離奇詭異肢专,居然都是意外死亡舞肆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門博杖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椿胯,“玉大人,你說我怎么就攤上這事剃根×ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵狈醉,是天一觀的道長廉油。 經(jīng)常有香客問我,道長舔糖,這世上最難降的妖魔是什么娱两? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮金吗,結(jié)果婚禮上十兢,老公的妹妹穿的比我還像新娘。我一直安慰自己摇庙,他們只是感情好旱物,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卫袒,像睡著了一般宵呛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夕凝,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天宝穗,我揣著相機(jī)與錄音,去河邊找鬼码秉。 笑死逮矛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的转砖。 我是一名探鬼主播须鼎,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼府蔗!你這毒婦竟也來了晋控?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姓赤,失蹤者是張志新(化名)和其女友劉穎赡译,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體模捂,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捶朵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年蜘矢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片综看。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡品腹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出红碑,到底是詐尸還是另有隱情舞吭,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布析珊,位于F島的核電站羡鸥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏忠寻。R本人自食惡果不足惜惧浴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奕剃。 院中可真熱鬧衷旅,春花似錦、人聲如沸纵朋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽操软。三九已至嘁锯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聂薪,已是汗流浹背家乘。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留藏澳,地道東北人烤低。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像笆载,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涯呻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容