在我们3d的开发中,对某一些建筑和物体进行解释说明是非常常见的现象,那么就不得不说卡片的展示了,卡片展示很友好的说明了当前物体的状态,一目了然,下面就是效果图。
它主要有两个方法来实现,大量的图片建议使用canvas来实现,少量的可以使用标签实现。
1.canvas
思路:
1将需要展示的内容画到canvas上。
2将canvas生成为图片材质,创建一个Mesh对象放入场景中。
实现代码
gltf.scene.traverse((child) => {
if (child.type == 'Mesh') {
child.toggle = (child) => {
this.toppip(
120,
60,
child.position.x,
child.rotation.y + 160,
child.position.z,
child.name,
);
};
}
});
// 提示框的创建
toppip (w, h, px, py, pz, text) {
//用canvas生成图片
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
var devicePixelRatio = window.devicePixelRatio || 1;
var backingStoreRatio = ctx.webkitBackingStorePixelRatio || 1;
var dpr = devicePixelRatio / backingStoreRatio;
canvas.width = Math.round(w * dpr);
canvas.height = Math.round(h * dpr);
canvas.style.width = w + 'px';
canvas.style.height = h + 'px';
ctx.scale(dpr, dpr);
//制作矩形
ctx.fillStyle = 'gray';
ctx.fillRect(0, 0, w, h);
//设置文字
ctx.fillStyle = 'blue';
ctx.font = '6px "楷体"';
// ctx.fillText('这个平面将被贴在正方体前表面', 0, 20)
let textWord = text;
//文字换行
let len = parseInt(textWord.length / 10);
for (let i = 0; i < len + 1; i++) {
let space = 10;
if (i === len) {
space = textWord.length - len * 10;
}
let word = textWord.substr(i * 10, space);
ctx.fillText(word, 2, 4 * (i + 1));
}
//生成图片
let url = canvas.toDataURL('image/png');
let texture = new THREE.TextureLoader().load(url);
//将图片构建到纹理中
let geometry1 = new THREE.PlaneGeometry(w, h);
let material1 = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
opacity: 1,
transparent: true,
});
let rect = new THREE.Mesh(geometry1, material1);
rect.rotation.y = Math.PI;
rect.position.set(px, py, pz);
this.scene.add(rect);
return rect;
}
2.div标签法
思路:1.在主页面创建一个空的DIV
点击增加标签,判断是否已经存在,存在就不增加了
eventHub.on('spriteClick', (ele) => {
var isCreateTag = false
floor2Tags.forEach(p => {
if (p.name == (ele.event.name + ele.i)) {
isCreateTag = true
}
})
if (!isCreateTag) {
const css3dObject = createTag(ele.event, ele.i);
css3dObject.visible = true;
floor2Tags.push(css3dObject)
scene.add(css3dObject)
}
})
创建标签
//添加标签和视频
function createTag (object3d, index) {
// 创建各个区域的元素
const element = document.createElement("div");
var perNum = index * 10 + 10
var percent = Math.ceil((perNum / 100) * 100);
var deg1 = ((45 + 135) * percent) / 50 - 135;
var deg2 = ((45 + 135) * (percent - 50)) / 50 - 135;
element.className = "elementTag";
element.innerHTML = `
实时监控${object3d.name + index}
${percent}
mg/m³
0.094TSP
0.044PM2.5
0.085PM10
`;
const objectCSS3D = new CSS3DObject(element);
//加载视频
objectCSS3D.name = object3d.name + index
objectCSS3D.position.set(
object3d.position.x / 5 + 20,
100,
object3d.position.y / 5 - 10,
);
objectCSS3D.scale.set(0.2, 0.2, 0.2);
return objectCSS3D;}
以上就是两种创建标签的方法,如果还有更好的方法可能我还没有发现,如果有兴趣交流可以私信或者留言,看到会第一时间回复,下期我们说说如何让这个卡片一直面向观察摄像头。