赞
踩
在 three.js 中,可以通过添加事件监听器来实现点击交互事件。具体步骤如下:
javascript
scene.traverse(function(object) {
if (object instanceof THREE.Mesh) {
object.addEventListener('click', function() {
// 处理点击事件
});
}
});
function handleClick(event) { var mouse = new THREE.Vector2(); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; var raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, camera); var intersects = raycaster.intersectObjects(scene.children, true); if (intersects.length > 0) { var clickedObject = intersects[0].object; // 处理被点击的物体对象 } }
var renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
var material = new THREE.MeshBasicMaterial({
color: 0xffffff,
polygonOffset: true,
polygonOffsetFactor: 1,
polygonOffsetUnits: 1
});
<template> <div class="hello"> <div class="tip"> <canvas id="three"></canvas> </div> <Mabtn @cocorbtn="cocorbtn" @caizhibtn="caizhibtn" @btnopen="btnopen"/> </div> </template> <script> import Mabtn from "../components/mabtn.vue"; import * as THREE from 'three' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' // 添加轨道控制器 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer" import {RenderPass} from "three/examples/jsm/postprocessing/RenderPass" import {OutlinePass} from "three/examples/jsm/postprocessing/OutlinePass" import {ShaderPass} from "three/examples/jsm/postprocessing/ShaderPass" import {FXAAShader} from "three/examples/jsm/shaders/FXAAShader" import {setcolor} from '../../public/setColor' var OBJ = '' export default { name: 'HelloWorld', components:{ Mabtn }, data(){ return{ renderer:null, nameNode:null, composer:null, outlinePass:null, renderPass:null, scene:null, camera:null, gltfscene:null, bujian:'', faguang:false, } }, mounted() { this.initThree() // this.render() }, methods: { btnopen(){ // document.querySelector('#three').style.height='100%' }, cocorbtn(b){ console.log(b); console.log(this.faguang); if (!this.faguang) { if (this.nameNode.children.length>0) { //点击颜色 let img = setcolor(b) // 更换纹理贴图 var texture = new THREE.TextureLoader().load(img + '.png'); OBJ.material.map = texture for (let i = 0; i < this.nameNode.children.length; i++) { this.nameNode.children[i].material.color.set(b) } }else{ this.nameNode.material.color.set(b) } } }, caizhibtn(a){//点击部件 console.log(a); this.bujian=a this.nameNode=this.gltfscene.getObjectByName(a) if (this.nameNode.children.length>0) { //点击颜色 this.outlineObj([this.nameNode.children[0]]) OBJ = this.nameNode.children[0] console.log(this.nameNode.children[0]); }else{ this.outlineObj([this.nameNode]) OBJ = this.nameNode } this.faguang=!this.faguang }, initThree() { let that = this this.scene = new THREE.Scene() // 创建一个scene this.scene.background = new THREE.Color('#eee') // 背景颜色 const canvas = document.querySelector('#three') // 渲染器锯齿属性.antialias that.renderer = new THREE.WebGLRenderer({ canvas, antialias: true }) // 创建一个WebGLRenderer,将canvas和配置参数传入 // 引入3D模型 gltf放置public目录 const gltfLoader = new GLTFLoader() gltfLoader.load('/ShoeOne/ShoeOne.gltf', (gltf) => { let model = gltf.scene // 递归遍历所有模型节点批量修改材质 gltf.scene.traverse(function(obj) { if (obj.isMesh) {//判断是否是网格模型 // console.log('模型节点',obj); // console.log('模型节点名字',obj.name); // console.log('gltf默认材质',obj.material); } }); console.log(gltf.scene) this.gltfscene = gltf.scene // 设置模型离中心点的位置 // gltf.scene.scale.set(40,40,40) // gltf.scene.position.x = 0 // gltf.scene.position.y = -80 // gltf.scene.position.z = 0 // console.log(nameNode); // for (let i = 0; i < nameNode.children.length; i++) { // nameNode.children[i].material.color.set(0xff0000) // nameNode.children[i].position.x = 0 // nameNode.children[i].position.y = -10 // nameNode.children[i].position.z = 0 // } // const nameNode = gltf.scene.getObjectByName("内里"); // nameNode.material.color.set(0xff0000);//改变Mesh材质颜色 this.scene.add(model) }) that.renderer.domElement.addEventListener('click', that.modelMouseClick, false) //设置点击方法 that.renderer.setSize(window.innerWidth, window.innerHeight) const hemLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 1) hemLight.position.set(0, 48, 0) this.scene.add(hemLight) //平行光 (这里可以用点光源PointLight和环境光AmbientLight没有特定方向,整体改变场景的光照明暗) const dirLight = new THREE.DirectionalLight(0xffffff, 1) //光源等位置 dirLight.position.set(-10, 8, -5) //使用PerspectiveCamera(透视摄像机):透视相机用来模拟人眼所看到的景象,物体的大小会受远近距离的影响,它是3D场景的渲染中使用得最普遍的投影模式。 this.camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 ) // camera.position.z = 10 // 正方位 this.camera.position.set(3, 4, 3); const controls = new OrbitControls(this.camera, that.renderer.domElement) // 阻尼感 controls.enableDamping = true // 动画循环函数 function animate() { controls.update() that.renderer.render(that.scene, that.camera) requestAnimationFrame(animate) if (resizeRendererToDisplaySize(that.renderer)) { const canvas = that.renderer.domElement that.camera.aspect = canvas.clientWidth / canvas.clientHeight that.camera.updateProjectionMatrix() } if (that.composer) { that.composer.render() } } animate() // 物理像素分辨率与CSS像素分辨率 function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement var width = window.innerWidth var height = window.innerHeight var canvasPixelWidth = canvas.width / window.devicePixelRatio var canvasPixelHeight = canvas.height / window.devicePixelRatio const needResize = canvasPixelWidth !== width || canvasPixelHeight !== height if (needResize) { renderer.setSize(width, height, false) } return needResize } }, // 窗口监听函数 onWindowResize() { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize(window.innerWidth, window.innerHeight); }, // 模型的点击事件 modelMouseClick( event ) { let raycaster = new THREE.Raycaster(); let mouse = new THREE.Vector2(); // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1) mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 0.8; raycaster.setFromCamera(mouse, this.camera); const intersects = raycaster.intersectObjects(this.scene.children); // if (intersects[0].object) { if (this.nameNode==intersects[0].object) { console.log('jin1'); this.faguang=!this.faguang }else{ console.log('jin2'); this.faguang=false } // } console.log(this.faguang,'001'); this.nameNode= intersects[0].object // 根据它来判断点击的什么,length为0即没有点击到模型 console.log(intersects.length ? intersects[0].object.name : intersects, 'intersects----->>>') // 获取选中最近的 Mesh 对象 if (intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) { this.outlineObj([intersects[0].object] ) } // if(intersects.length){ // } }, //高亮显示模型(呼吸灯) outlineObj (selectedObjects) { console.log(selectedObjects); // let that = this // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。 this.composer = new EffectComposer(this.renderer) // 新建一个场景通道 为了覆盖到原理来的场景上 this.renderPass = new RenderPass(this.scene, this.camera) this.composer.addPass(this.renderPass); // 物体边缘发光通道 this.outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), this.scene, this.camera, selectedObjects) console.log(this.faguang,'002'); if (!this.faguang) { this.outlinePass.selectedObjects = selectedObjects }else{ this.outlinePass.selectedObjects =[] } console.log('显示',this.faguang); this.outlinePass.edgeStrength = 15.0 // 边框的亮度 this.outlinePass.edgeGlow = 2// 光晕[0,1] this.outlinePass.usePatternTexture = false // 是否使用父级的材质 this.outlinePass.edgeThickness = 1.0 // 边框宽度 this.outlinePass.downSampleRatio = 1 // 边框弯曲度 this.outlinePass.pulsePeriod = 0 // 呼吸闪烁的速度 this.outlinePass.visibleEdgeColor.set(parseInt(0x0000FF)) // 呼吸显示的颜色 this.outlinePass.hiddenEdgeColor = new THREE.Color(0x0000FF) // 呼吸消失的颜色 this.outlinePass.clear = true this.composer.addPass(this.outlinePass) // 自定义的着色器通道 作为参数 let effectFXAA = new ShaderPass(FXAAShader) effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight) effectFXAA.renderToScreen = true this.composer.addPass(effectFXAA) }, } } </script> <style scoped> .tip{ width: 100%; height: 80%; position: fixed; top: 0; left: 0; } #three { width: 100% !important; height: 100% !important; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。