在three场景中,我们会添加很多建筑模型,增加了模型,意味着需要标识这些属于何种身份,道路,信号灯,银行、大厦等,这里我们一般通过添加图片的方式,进行标识
1、模拟批量创建建筑
// 创建若干个建筑物
const buildCount = 50;
const group = new THREE.Group();
for (let i=0; i<buildCount; i++) {
const x = randWidth(20);
const y = randWidth(100);
const z = randWidth(10);
const boxGeometry = new THREE.BoxBufferGeometry(x, y ,z);
const positionX = 300 - randWidth(600);
const positionZ = 300 - randWidth(600);
boxGeometry.translate(positionX, y / 2 ,positionZ);
const material = new THREE.MeshBasicMaterial( { color: 0x5588aa } );
const mesh = new THREE.Mesh(boxGeometry, material);
mesh.isBuild = true;
group.add(mesh);
}
scene.add(group);
复制代码
在前面文章中,我创建了若干个随机建筑物,现在就需要给每个建筑物添加图标展示
// 创建精灵函数,传入父对象
function createLableSprite_jcy(group, x, y, z) {
var spriteMaterial = new THREE.SpriteMaterial({
map: new THREE.TextureLoader().load("./textures/icon-build.png"), //设置精灵纹理贴图
transparent: true, //开启透明(纹理图片png有透明信息)
});
// 创建精灵模型对象,不需要几何体geometry参数
var sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(10, 10, 10); //精灵大小
sprite.position.set(x, y, z)
// 把精灵模型插入到模型对象的父对象下面
group.add(sprite);
// 父对象group位置变化,网格模型及其对象的标签同样发生变化
group.position.set(group.position.x, group.position.y, group.position.z);
// 表示标签信息的精灵模型对象相对父对象设置一定的偏移
sprite.translateY(y+10);
return group;
}
复制代码
上面代码是添加雪碧图后,添加到模型的父对象中,使用到group的方法
2、添加图标sprite
代码示例
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cubeA = new THREE.Mesh( geometry, material );
cubeA.position.set( 100, 100, 0 );
const cubeB = new THREE.Mesh( geometry, material );
cubeB.position.set( -100, -100, 0 );
//create a group and add the two cubes
//These cubes can now be rotated / scaled etc as a group
const group = new THREE.Group();
group.add( cubeA );
group.add( cubeB );
scene.add( group );
复制代码
从官网的代码示例中,可以看到group类似html中的div,当我们需要对一部分标签包裹的时候,就会外套一个div 命名为wrap;
所以我们最后只需要将createLableSprite_jcy在for循环中调用,传入建筑以及建筑的坐标即可,
createLableSprite_jcy(mesh, positionX, y / 2 ,positionZ);
以上的group是将50个柱形建筑整体打包成一体,所以后续针对小车添加图标,我们需要另外声明一个group
3、移动的图标
小车需要图标,但是小车是运动的,坐标是实时变化的,所以我们需要将小车和 图标绑定在一起,包裹
const carGroup = new THREE.Group();
复制代码
之前对小车mesh旋转调整的,现在需要针对carGroup
carGroup.rotation.y = - Math.PI / 2;
复制代码
把雪碧图和小车模型都添加到group
let spriteMaterial = new THREE.SpriteMaterial({
// 设置精灵纹理贴图
map: new THREE.TextureLoader().load("./textures/icon-car.png"),
transparent: true, //开启透明(纹理图片png有透明信息)
});
carGroup.add(carModel);
// 创建精灵模型对象,不需要几何体geometry参数
const sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(10, 10, 10); //精灵大小
// sprite.position.set(-1.6721884850946012, -1.368973127897772e-13, 360.53068686806284)
// 把精灵模型插入到模型对象的父对象下面
carGroup.add(sprite);
carGroup.position.set(-1.6721884850946012, -1.368973127897772e-13, 360.53068686806284);
sprite.translateY(carGroup.position.y + 20);
scene.add( carGroup );
复制代码
因为雪碧图和小车同时运动,所以最后运动的是carGroup ,
let progress = 0;
function moveCamera() {
if (progress <= 1 - 0.00004 * 20){
const point = curve.getPointAt(progress) //获取样条曲线指定点坐标,作为相机的位置
const pointBox = curve.getPointAt(progress + 0.00004 * 20) //获取样条曲线指定点坐标
if (carGroup) {
carGroup.position.set(pointBox.x, pointBox.y, pointBox.z);
carGroup.lookAt(point.x, point.y, point.z);
}
progress += 0.00004
} else {
progress = 0
}
}
复制代码
参考链接:
Threejs使用精灵Sprite作为标签,鼠标悬浮精灵上时鼠变小手blog.csdn.net/baidu_29701…
我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!