五、3d场景的卡片展示的创建

        在我们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

  1. 将需要加入的标签加入,并创建CSS3DObject对象,
  2. 将css3dObject加入Scene

点击增加标签,判断是否已经存在,存在就不增加了

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 = `
    <div class="elementContent">
      <h3>实时监控${object3d.name + index}</h3>
      <div class="elementProgress">
      <div class="circle_process">
        <div class="wrapper right">
            <div class="circle rightcircle" style="transform:rotate(${percent < 50 ? deg1 : 45}deg)"></div>
        </div>
        <div class="wrapper left">
            <div class="circle leftcircle" style="transform:rotate(${percent < 50 ? 'none' : deg2}deg)"></div>
        </div>
        <div class="wrapper_num">
          <p>${percent}</p>
          <p>mg/m³</p>
        </div>
      </div>
        <div class="elementPm">
          <p>0.094<span>TSP</span></p>
          <p>0.044<span>PM2.5</span></p>
          <p>0.085<span>PM10</span></p>
        </div>
      </div>
    </div>
  `;
  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;}

以上就是两种创建标签的方法,如果还有更好的方法可能我还没有发现,如果有兴趣交流可以私信或者留言,看到会第一时间回复,下期我们说说如何让这个卡片一直面向观察摄像头。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

arguments_zd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值