1 环境光AmbientLight
//颜色会直接作用物体的当前颜色上
// 环境光会均匀的照亮场景中的所有物体。环境光不能用来投射阴影,因为它没有方向。
// AmbientLight( color : Integer, intensity : Float )
// color - (参数可选)颜色的rgb数值。缺省值为 0xffffff。
// intensity - (参数可选)光照的强度。缺省值为 1。
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
this.scene.add(ambientLight)
2 平行光(DirectionalLight)
var light = new THREE.DirectionalLight(0xffffff, 0.5)
// 光源位置
// light.position.set(100, 200, 150)
light.position.set(10, 15, 15)
this.scene.add(light)
3 聚光灯SpotLight
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.shadow.mapSize.set(2048, 2048)
spotLight.position.set(-20, 60, 0)
// spotLight.position.set(0, 60, 0)
// 开启投影
spotLight.castShadow = true
this.scene.add(spotLight)
4 地面
// 创建一个平面
var planeGeometry = new THREE.PlaneGeometry(100, 100)
var planeMaterial = new THREE.MeshLambertMaterial({ color: 0x999999 })
var plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.receiveShadow = true
// rotate and position the plane
plane.rotation.x = -0.5 * Math.PI
plane.position.x = 0
plane.position.y = -8
plane.position.z = 0
this.scene.add(plane)
5.导入obj和 mtl
const that = this
const objLoader = new OBJLoader()
const mtlLoader = new MTLLoader()
mtlLoader.load('/modules/电除尘设备.mtl', function (materials) {
// materials.preload();
objLoader.setMaterials(materials)
objLoader.load(
'/modules/电除尘设备.obj',
function (obj) {
that.obj = obj
that.obj.position.set(0, 0, 0)
that.obj.scale.set(0.005, 0.005, 0.005)
that.obj.rotateY(-Math.PI / 4)
// 设置可以投影
that.obj.children.forEach((item) => {
item.castShadow = true
item.receiveShadow = true
})
that.scene.add(obj)
},
// called while loading is progressing
// eslint-disable-next-line no-unused-vars
function (xhr) {
if (xhr.lengthComputable) {
const percentComplete = (xhr.loaded / xhr.total) * 100
console.log(percentComplete, 'percentComplete')
if (percentComplete === 100) {
that.loading = false
}
}
// console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
},
// called when loading has errors
function (error) {
console.log(error, 'An error happened')
}
)
})
6 相机位置 值越小,相机距离就约近, 物体就越大
//获取场景2种方式
//把场景存起来,用全局变量
//给盒子设置name 获取是 this.scene.getObjectByName(name)
Const sky = new Mesh(skyboxGeometry,skyboxMaterials)
Sky.name = ‘aaa’
this.scene.getObjectByName(‘aaa’
)
7.PerspectiveCamera
// 透视投影照相机(for,aspect,near,far)
// 视野角:fov 这里视野角(有的地方叫拍摄距离)越大,场景中的物体越小,视野角越小,场景中的物体越大
// 纵横比:aspect (3d物体的宽/高比例)
// 相机离视体积最近的距离:near
// 相机离视体积最远的距离:far
this.camera = new THREE.PerspectiveCamera(45, aspect, 1, 2000)
Aspect = 当前canvas的宽 / 当前canvas的高
8三位坐标轴
x红 向右代表正数,向左代表负数
y绿 向上代表正数,向下代表负数
z蓝 靠近我们代表正数,远离我们代表负数
注意 y在纵轴上
性能插件 stats
跳跃旋转
dat.gui 自定义方法和属性
元素设置 name
获取元素 var obj = scene.getObjectByName(‘name’,false)
False:仅在调用者的子元素中查找
True:在调用者的所有后代对象中查找
移除场景中的元素
需要检查该元素是否为mesh对象
If (obj instanceof Mesh){
Scene.remove(obj )
}
用dat.gui去封装函数
Var ctrlObj = new function(){
This.removeFingCube = function(){
If (obj instanceof Mesh){
Scene.remove(obj )
}
}
}
Var ctrl = new dat.GUI();
Ctrl.add(ctrlObj ,removeFingCube )
Scene.traverse 场景中所有物体旋转
Scene.traverse(function(obj){
//plane 是当前地板对象
If (obj instanceof Mesh && obj!=plane){
Obj.roration.x +=0.01
Obj.roration.y +=0.01
Obj.roration.z+=0.01
}
})
场景雾化 fog fogExp2
第一种雾化
Scene.fog = new fog(0xffffff,0.01,100)
第一个参数是雾化的颜色;第二个参数雾化近处的值,第三个参数是雾化远处的值
第二种雾化
Scene.fog = new fogExp2(0xffffff,0.01)
第一个参数是雾化的颜色;第二个参数雾化的浓度,
场景材质OverrideMaterial
强制场景中所有物体使用相同的材质
Scene.OverrideMaterial = new meshLamberMaterial({color:0x0000ff})
圆环
Var torusgeo= new TorusGeometry(8,8,8,10)
Var torusmaterial = = new meshLamberMaterial({color:0xff2288})
Var torus= new mesh(geometry ,material )
torus.castShadow = true
torus.position.x = 4
torus.position.y = 8
torus.position.z = 10
Scene.add(torus)
TorusGeometry 第一个参数 圆环的半径默认值是1 第二个参数 管道半径默认0.4
第三个参数 圆环的分段数 默认8 第四个参数 管道的分段数 默认是6
第五个 圆环的圆心角 默认 math.pi*2
gltf 点击同材质的,颜色均被改变
const loader = new GLTFLoader(),
path = 'modules/1234.gltf'
//解压 gltf 因为 gltf被压缩了一次
var dracoLoader = new DRACOLoader()
//解压路径
dracoLoader.setDecoderPath('js/draco/')
loader.setDRACOLoader(dracoLoader)
loader.load(
path,
(gltf) => {
that.obj = gltf.scene
//重点---------------------
that.obj.children.map((v, i) => {
//克隆材质 防止材质一样 点击同材质颜色都改变了
if (v.material) {
v.material = that.obj.children[i].material.clone()
}
})
threejs 删除标签
//第一步 给标签设置一个名字
let pointLabel = new CSS2DObject(laberDiv)
pointLabel.position.set(vector.x, vector.y, vector.z)
pointLabel.name = item.name
//第二步 场景中根据名字找到节点 用父节点去删除
const rm = this.scene.getObjectByName(item.name)
if (rm) rm.parent.remove(rm)
//注意: 尝试直接用 this.scene.remove(rm) 有一个标签始终删除不掉 我有点不明白哦
创建标签
【1】导入标签
import {
CSS2DObject,
CSS2DRenderer,
} from 'three/examples/jsm/renderers/CSS2DRenderer'
【2】在初始化里面Renderer挂载 CSS2DRenderer
// 渲染到那个容器
const Lable2d = document.getElementById('autoLable') // threeJS挂载位置
//添加canvas
this.labelRenderer = new CSS2DRenderer()
this.labelRenderer.setSize(this.w, this.h)
this.labelRenderer.domElement.style.position = 'absolute'
this.labelRenderer.domElement.style.top = 0
Lable2d.appendChild(this.labelRenderer.domElement)
【3】创建标签
// 新建标签
createLableObj(item, vector) {
let laberDiv = document.createElement('div') //创建div容器
const sbjData = {
name: item.name,
data: {
T0: item.T0.value + '℃',
T1: item.T1.value + '℃',
T2: item.T2.value + '℃',
p: item.P.value + 'kPa',
off: item['0O5'].value != 0.0 ? '正常' : '异常',
status: item.sgType,
},
}
const s = 'bg-' + sbjData.data.status
laberDiv.className = 'gltf-box rm' + s
const str = `
<div class="lgb-title status-${sbjData.data.status}">
${sbjData.name}
</div>
<div class="lgb-main">
<div class="lgb-item">
<span class="lgb-item-left">T0温度:</span
><span class="lgb-item-num">${sbjData.data.T0}</span>
</div>
<div class="lgb-item">
<span class="lgb-item-left">T1温度:</span
><span class="lgb-item-num">${sbjData.data.T1}</span>
</div>
<div class="lgb-item">
<span class="lgb-item-left">T2温度:</span
><span class="lgb-item-num">${sbjData.data.T2}</span>
</div>
<div class="lgb-item">
<span class="lgb-item-left">P压力:</span
><span class="lgb-item-num">${sbjData.data.p}</span>
</div>
<div class="lgb-item">
<span class="lgb-item-left">料位开关:</span
><span>${sbjData.data.off}</span>
</div>
</div>
`
laberDiv.innerHTML = str
let pointLabel = new CSS2DObject(laberDiv)
pointLabel.position.set(vector.x, vector.y, vector.z)
pointLabel.name = item.name
return pointLabel
},
【4】调用
//自动弹窗
autoMessage() {
// 我需要自动弹窗 所以我是循环创建的 标签
this.autoDatas.forEach((item) => {
//if (this.changeLableDatas[item.name]) {
let pointLabel = this.createLableObj(
item,
this.lableDatas[this.changeLableDatas[item.name]]
)
// this.lableDatas[this.changeLableDatas[item.name] 为标签的三维坐标值
this.scene.add(pointLabel)
//}
})
},
【5】自动旋转里面 加入标签旋转
// 自动旋转
animate() {
this.labelRenderer.render(this.scene, this.camera)
this.renderer.render(this.scene, this.camera)
this.requestId = requestAnimationFrame(this.animate)
//更新控制器
this.controls.update()
},
【补充】坐标变量
//gltf 自动弹窗位置 我获取不到单个点坐标 获取都是(0,0,0) ,目前是根据模型位置写死的
lableDatas: {
灰斗Aq: { x: 2, y: 12, z: -12 },
灰斗Bq: { x: -8, y: 12, z: 5 },
灰斗A121: { x: 10, y: 12, z: -1 },
灰斗A122: { x: 14, y: 12, z: 5 },
灰斗A123: { x: 10, y: 12, z: 7 },
灰斗A124: { x: 12, y: 12, z: 9 },
灰斗B121: { x: 8, y: 12, z: 11 },
灰斗B122: { x: 4, y: 12, z: 13 },
灰斗B123: { x: 0, y: 12, z: 16 },
灰斗B124: { x: -4, y: 12, z: 19 },
灰斗A111: { x: 14, y: 12, z: -10 },
灰斗A112: { x: 10, y: 12, z: -8 },
灰斗A113: { x: 7, y: 12, z: -4 },
灰斗A114: { x: 4, y: 12, z: 0 },
灰斗B111: { x: 0, y: 12, z: 4 },
灰斗B112: { x: -4, y: 12, z: 7 },
灰斗B113: { x: -6, y: 12, z: 11 },
灰斗B114: { x: -9, y: 12, z: 14 },
},
//后端返回跟设计名字不一样,暂时做了映射
changeLableDatas: {
灰斗Aq: '灰斗Aq',
灰斗Bq: '灰斗Bq',
灰斗121A: '灰斗A121',
灰斗122A: '灰斗A122',
灰斗123A: '灰斗A123',
灰斗124A: '灰斗A124',
灰斗121B: '灰斗B121',
灰斗122B: '灰斗B122',
灰斗123B: '灰斗B123',
灰斗124B: '灰斗B124',
灰斗111A: '灰斗A111',
灰斗112A: '灰斗A112',
灰斗113A: '灰斗A113',
灰斗114A: '灰斗A114',
灰斗111B: '灰斗B111',
灰斗112B: '灰斗B112',
灰斗113B: '灰斗B113',
灰斗114B: '灰斗B114',
},