Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >threejs记录选中变化纹理

threejs记录选中变化纹理

作者头像
tianyawhl
发布于 2023-12-11 01:45:20
发布于 2023-12-11 01:45:20
20900
代码可运行
举报
文章被收录于专栏:前端之攻略前端之攻略
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
  <div class="wrap">
    <div ref="container" id="container"></div>
    <div id="panel" v-if="isShowPanel" :style ="{left:left+'px',top:top+'px'}">
      <div>名称:{{panel.name}}</div>
      <div>温度:{{panel.temp}}</div>
      <div>使用情况:{{panel.use}}</div>
    </div>
  </div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import {CSS3DRenderer, CSS3DObject} from "three/examples/jsm/renderers/CSS3DRenderer.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { MeshBasicMaterial, TextureLoader } from 'three';

export default {
  name: "ThreeTest",
  data() {
    return {
      left:0,
      top:0,
      panel:{
        name:"",
        temp:"",
        use:""
      },
      isShowPanel:false,
      //纹理集合
      maps:[],
      // 机柜集合
      cabinets:[],
      //划入的当前机柜
      curcabinet:null
    };
  },
  mounted() {
    // this.getData();
    this.timer = null;
    this.myReq = null;
    this.container;
    this.scene;
    this.camera;
    this.renderer;
    this.labelRenderer;
    this.controls;
    this.initScene();
    this.initCamera();
    this.initRender();
    this.initModel();
    this.initControls();
    this.initLight()
    this.animate();
    window.onresize = this.onWindowResize;
    this.crtTexture("Cube-hover.png")
    document.addEventListener('mousemove', this.onClick, false);
  },

  methods: {
    onClick(event){
      this.selectCabinet(event.clientX,event.clientY)
    },
    selectCabinet(x,y){
      
        var raycaster = new THREE.Raycaster();
        var pointer = new THREE.Vector2();
        const {width,height} = this.renderer.domElement
        console.log(width)
         console.log(height)
        // canvas 坐标转裁剪坐标
        pointer.set((x/width)*2-1,-(y/height)*2+1)
        raycaster.setFromCamera(pointer,this.camera)
                console.log(this.cabinets)
        // 选择机柜
        const intersect = raycaster.intersectObjects(this.cabinets)[0]
        let intersectObject = intersect?intersect.object:null
        console.log(this.curcabinet)

        console.log(intersectObject)
        // 若之前已有机柜被选择,且不等于当前所选择的机柜,取消之前选择的机柜的高亮
        if(this.curcabinet && this.curcabinet!=intersectObject){
          const material = this.curcabinet.material
          material.setValues({
            map:this.getMapByName("Cube.png")
          })
        }

        if(intersectObject){
          this.onMouseMoveCabinet(x,y)
          if(intersectObject != this.curcabinet){
            this.curcabinet = intersectObject
             const material = this.curcabinet.material
             material.setValues({
                map:this.getMapByName("Cube-hover.png")
             })
             this.onMouseOverCabinet(intersectObject)
          }
        }else if(this.curcabinet){
          this.curcabinet = null
          this.onMouseOutCabinet()
        }
    },
    // 鼠标划入机柜的事件,参数为机柜对象
    onMouseOverCabinet(){
      this.isShowPanel = true
    },
    //在机柜上移动的事件,参数为坐标
    onMouseMoveCabinet(x,y){
     this.left= x
     this.top= y
    },
    // 鼠标划出机柜的事件
    onMouseOutCabinet(){
      this.isShowPanel = false
    },
    pushMap(imageName,curTexture){
      this.maps.push({name:imageName,map:curTexture})
    },
    getMapByName(name){
      let rusult
      for(let i=0;i<this.maps.length;i++){
        if(this.maps[i].name == name){
          rusult =  this.maps[i].map
          break
        }
      }
      return rusult
    },
    initScene() {
      this.scene = new THREE.Scene();
    },
    initCamera() {
      this.container = document.getElementById("container");
      this.camera = new THREE.PerspectiveCamera(
        70,
        this.container.clientWidth / this.container.clientHeight,
        1,
        1000
      );
      console.log(this.camera);
      this.camera.position.z = 20; //z设置小写会使图像变形小
      this.camera.position.y = 0
    },
    initRender: function () {
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(
        this.container.clientWidth,
        this.container.clientHeight
      );
      this.container.appendChild(this.renderer.domElement);
    },

    initLight() {
      this.scene.add(new THREE.AmbientLight(0xb9e1fb));
      this.light = new THREE.DirectionalLight(0xecfbb9,0.2);
      this.light.position.set(0, 0, 50);
      this.scene.add(this.light);
    },
    initModel() {
       let loader = new GLTFLoader()
       let gltScene
        loader.load("models/clickTest/threebox.gltf",(gltf)=>{
         for(let i=0;i<gltf.scene.children.length;i++){
           console.log(gltf.scene.children[i])
           let mesh = gltf.scene.children[i]
           if(mesh.type == "Mesh"){
             console.log(mesh)
             const {map,color} = mesh.material
             this.changeMat(mesh,map,color)
             if(mesh.name.includes("Cube")){
               this.cabinets.push(mesh)
             }

            //  this.scene.add(mesh)   会有问题。Mesh减少
           }
         }

         this.scene.add(...gltf.scene.children)
       })
    },
    // 修改材质
    changeMat(mesh,map,color){
      let index = map.image.currentSrc.lastIndexOf("/")
      let imageName = map.image.currentSrc.substring(index+1)
      console.log(imageName)
      if(map){
        // this.maps.push({name:mesh.name,map:this.crtTexture(map.name)})
        // console.log(this.maps)
        mesh.material = new MeshBasicMaterial({
          map:this.crtTexture(imageName)
          // map:new THREE.TextureLoader().load("/models/clickTest/Cube.png")
        })
      }else{
        mesh.material = new MeshBasicMaterial({color})
      }
    },
    // 建立纹理对象
    crtTexture(imgName){
      let curTexture = this.getMapByName(imgName)
      if(!curTexture){
        curTexture = new THREE.TextureLoader().load(`/models/clickTest/${imgName}`)
        curTexture.flipY = false
        curTexture.wrapS = 1000
        curTexture.wrapT = 1000
        this.pushMap(imgName,curTexture)
      }
      return curTexture
    },
    initControls(){
       this.controls = new OrbitControls( this.camera, this.renderer.domElement );
    },

    render() {
      this.renderer.render(this.scene, this.camera);
      // this.labelRenderer.render(this.scene, this.camera);
    },
    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;

      this.camera.updateProjectionMatrix();

      this.render();

      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
    },
    animate() {
      this.render();
      this.myReq = requestAnimationFrame(this.animate);
    },
  },
  beforeDestroy() {
    cancelAnimationFrame(this.myReq);
    clearInterval(this.timer);
    this.scene = null;
    // this.scene.dispose()
    this.camera = null;
    this.renderer = null;
    this.labelRenderer = null;
    this.controls = null;
  },
  watch: {},
  filters: {},
};
</script>

<style scope>
/deep/.label {
				color: #FFF;
				font-family: sans-serif;
				padding: 2px;
				background: rgba( 0, 0, 0, .6 );
			}
#panel{
  position:absolute;
  left:0;
  top:0;
  background: rgba( 0, 0, 0, .6 );
  padding:10px;
}

</style>

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
threejs 中加载gltf模型 循环Mesh会减少,暂时使用整体加入this.scene.add(...gltf.scene.children)
curTexture = new THREE.TextureLoader().load("/models/clickTest/Cube-export.png")
curTexture.flipY = false
curTexture.wrapS = 1000
curTexture.wrapT = 1000
上面的3个参数不加贴图不准确,有偏移

blender导出是图片和gltf分别单独导出

材质通过setValues重新设置值
material.setValues({
     map:this.getMapByName("Cube-hover.png")
})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
threejs 场景切换 优化性能
是实现2个场景的定时切换,由于是用在大屏系统,需要浏览器一直能正常运行,不能运行一段时间卡死
tianyawhl
2020/11/12
2.9K0
基于threejs实现中国地图轮廓动画
目前项目的中国地图是echarts画的,现在这想再次基础上增加一个中国地图描边动画。
星宇大前端
2022/05/06
3.3K0
基于threejs实现中国地图轮廓动画
vue.js + three.js轻松构建3d场景的动画图形
3d场景实现 实现彩色正方体旋转 <template lang="html"> <div class="charts-sequre"> <div id="container"> </div> </div> </template> <script> import * as Three from 'three' export default { data() { return { camera: null, scene: null, re
前端老鸟
2019/11/06
4.6K0
基于vue3+threejs实现可视化大屏
Three.js是一款基于原生WebGL封装通用Web 3D引擎,在小游戏、产品展示、物联网、数字孪生、智慧城市园区、机械、建筑、全景看房、GIS等各个领域基本上都有three.js的身影。
winty
2023/09/14
9320
基于vue3+threejs实现可视化大屏
Three.js的入门案例(上)
在Three.js的赋能下,WEB网页效果逐渐丰富起来,今天我们就来运用之前学习的Three.js基础知识,实现一个旋转的几何体-球体。
前端达人
2021/03/16
6.2K0
Three.js的入门案例(上)
Three.js的入门案例(下)
在上一篇案例中实现了几何体-球体旋转效果,今天继续丰富这个案例效果,在球体的周围添加光圈及旋转模块(图片+文字组成),均匀的分布在球体周围,围绕着球体逆时针旋转,最终效果如图:
前端达人
2021/03/16
2.8K0
Three.js的入门案例(下)
Vue3 + Three.js 商城可视化实战
链接:https://juejin.cn/post/7137192060045492231
winty
2024/04/03
2650
Vue3 + Three.js 商城可视化实战
.glb格式的模型怎么在three.js中展示
3D软件中导出的格式一般有.obj 和.glb ,下面是blender 2.8.2 生成模型并在three.js中展示的流程
tianyawhl
2020/11/24
15.9K2
.glb格式的模型怎么在three.js中展示
vue 中使用threejs
1、安装threejs  :npm install three --save 2、页面引入 :import * as THREE from "three"; 如果使用到 OrbitControls 和 CSS3DRenderer import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import { CSS3DRenderer,CSS3DObject } from "three/examples/j
tianyawhl
2020/07/21
6.7K2
Three.js实战—中国地图
这里涉及到一个知识点,墨卡托投影转换。墨卡托投影转换可以把我们经纬度坐标转换成我们对应平面的2d坐标。具体原理
阶钟
2024/12/03
1.6K0
Three.js实战—中国地图
threejs材质
从blender里面导出的贴图好的模型,在threejs中加载会变暗,如何解决,首先简单的介绍如何在blender中贴图与导出
tianyawhl
2022/09/23
2.1K0
threejs材质
Threejs进阶之一:基于vite+vue3+threejs构建三维场景
前面的章节我们都是通过HTML+JS的方式创建三维场景,从这一章节开始,我们后面将使用vite+vue3+threejs来构建三维场景。
九仞山
2023/04/30
7.8K1
Threejs进阶之一:基于vite+vue3+threejs构建三维场景
Three.js 基础纹理贴图
尽管 Three.js 文档已经比较详细了,但对于刚接触 Three.js 的工友来说,最麻烦的还是不懂如何组合。Three.js 的功能实在太多了,初学者很容易被大量的新概念冲晕。
德育处主任
2023/02/26
5.7K0
Three.js 基础纹理贴图
ThreeJS实现船行效果
解决方法: 官方提供了射线捕获的接口 raycaster.intersectObjects, 但是只能识别自建的Mesh模型, 对于导入的模型则无法捕获, 主要是因为导入的模型最外层包了一层, 没有把自己内部的Mesh暴露出来 所以我们需要在模型导入后, 在onProgress回调中对其进行递归获取子Mesh, 将所有Mesh存在一个全局数组中. 在鼠标事件触发时, 将全局数组提供给raycaster.intersectObjects, 即可识别 1. 递归函数
治电小白菜
2020/08/25
4.9K0
ThreeJS实现船行效果
三种前端实现VR全景看房的方案!说不定哪天就用得上!
事情是这样的,前几天我接到一个外包工头的新需求,某品牌要搭建一个在线VR展厅,用户可以在手机上通过陀螺仪或者拖动来360度全景参观展厅,这个VR展厅里会有一些信息点,点击之后可以呈现更多信息(视频,图文等)...
coder_koala
2021/07/08
2.7K0
三种前端实现VR全景看房的方案!说不定哪天就用得上!
threejs之显示Label-CSS2DRenderer
1、采用threeJs的精灵(Sprite),具体用法查看我另一篇博客https://my.oschina.net/u/2612473/blog/3038066 2、使用CSS2DRenderer
tianyawhl
2019/05/31
6.1K1
threejs 之 复制删除正方体 原
这是threejs官方的一个例子webgl_interactive_voxelpainter.html  查看效果 查看效果
tianyawhl
2019/05/31
1.2K0
XR-FRAME 开始
xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。
江拥羡橙
2023/11/28
9060
XR-FRAME 开始
Threejs入门之二十五:Threejs加载gltf文件
这一节我们来通过Threejs加载一个glft格式的三维模型文件,首先我们先简单了解下gltf文件
九仞山
2023/04/30
7.6K3
Threejs入门之二十五:Threejs加载gltf文件
微信小程序体验3D物理引擎-ammo.js
点击体验3D物理引擎bullet的javascript版本。源码参考了:https://github.com/THISISAGOODNAME/learn-ammojs,感谢原作者!
周星星9527
2020/05/31
3.5K0
相关推荐
threejs 场景切换 优化性能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验