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

news2025/2/22 4:16:33

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1055099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cinema 4D 2024更新, 比旧版速度更快!

Cinema 4D 2024 for Mac更新至v2024.0.2版本&#xff0c;其中Cinema 4D核心得到了全面优化&#xff0c;增强了可调的Pyro模拟、增强了真实镜头耀斑和色彩校正工作流程。 Cinema 4D 2024变得更加强大&#xff0c;在交互式播放方面有了巨大的性能改进&#xff0c;对刚性体模拟进行…

毛玻璃动画交互效果

效果展示 页面结构组成 从上述的效果展示页面结构来看&#xff0c;页面布局都是比较简单的&#xff0c;只是元素的动画交互比较麻烦。 第一个动画交互是两个圆相互交错来回运动。第二个动画交互是三角绕着圆进行 360 度旋转。 CSS 知识点 animationanimation-delay绝对定位…

CISSP学习笔记:PKI和密码学应用

第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统&#xff0c;从而产生了安全秘钥分发的问题非对称密码学使用公钥和私钥对&#xff0c;无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA&#xff08;兼具加密和数字签名&#xff09; RSA算法…

Minecraft我的世界部署教程

部署 费了老鼻子劲才搞懂如何部署&#xff0c;对新人实在是太不友好了。所以总结一下。 这里选用 PaperMC Veloity&#xff0c;使用 docker compose 部署。 结构 首先搞清楚服务器部署原理&#xff0c;有两个东西。 Minecraft 服务端Minecraft 服务代理 服务核心常见的主…

【算法挨揍日记】day09——704. 二分查找、34. 在排序数组中查找元素的第一个和最后一个位置

704. 二分查找 704. 二分查找 题目描述&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 解题思路&…

基于Java的网上摄影工作室网站设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

常见服务器运维管理面板整理汇总

随着云计算技术的发展和普及&#xff0c;越来越多的用户开始使用云服务器来部署和运行应用程序和服务。为了方便用户管理和操作云服务器&#xff0c;各种类型的服务器管理面板应运而生。本文将整理和汇总一些常见的服务器管理面板&#xff0c;供用户参考选择。 1、宝塔面板【官…

Go应用程序的安全最佳实践

在Go中预防漏洞、保护用户输入和防御代码注入和XSS攻击 在软件开发领域&#xff0c;安全性不是一个简单的事后考虑&#xff0c;而是建立强大和可信赖应用程序的基本基石。确保您的Go应用程序对潜在威胁具有韧性要求全面了解安全最佳实践。本指南深入探讨了您可以采取的重要措施…

【通意千问】大模型GitHub开源工程学习笔记(1)--依赖库

9月25日&#xff0c;阿里云开源通义千问140亿参数模型Qwen-14B及其对话模型Qwen-14B-Chat,免费可商用。 立马就到了GitHub去fork。 GitHub&#xff1a; GitHub - QwenLM/Qwen: The official repo of Qwen (通义千问) chat & pretrained large language model proposed b…

yolov5分割+检测c++ qt 中部署,以opencv方式(详细代码(全)+复制可用)

1&#xff1a;版本说明&#xff1a; qt 5.12.10 opencv 4.5.3 &#xff08;yolov5模型部署要求opencv>4.5.0&#xff09; 2&#xff1a;检测的代码 yolo.h #pragma once #include<iostream> #include<cmath> #include<vector> #include <opencv2/…

Spring的注解开发-非自定义Bean的配置

非自定义Bean注解开发 非自定义Bean不能象自定义Bean一样使用Component注解及其衍生注解进行管理&#xff0c;非自定义Bean要通过工厂的方式进行实例化&#xff0c;使用Bean标注即可&#xff0c;Bean的属性为beanName&#xff0c;使用Bean注解作用在方法中&#xff0c;通过定义…

一个高精度24位ADC芯片ADS1222的使用方法及参考电路程序成都控制器定制

前一段时间&#xff0c;在做单片机、PLC、电路板、控制器/箱、仪器仪表、机电设备或系统、自动化、工控、传感、数据采集、自控系统、控制系统&#xff0c;物联网&#xff0c;电子产品&#xff0c;软件、APP开发设计定制定做开发项目时&#xff0c;有要求用到24位的高精度ADC&a…

Flutter笔记 - 用于描述Align的Alignment、AlignmentDirectional、AlignmentTween类

Flutter笔记 用于描述Align的Alignment、AlignmentDirectional、AlignmentTween类 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_…

问题: 视频颜色问题,偏绿

参考 什么是杜比视界&#xff1f; - https://www.youtube.com/watch?vldXDQ6VlC7g 【哈士亓说】07&#xff1a;HDR、杜比视界究竟是个啥&#xff1f;为什么这个视频还不是HDR视频&#xff1f; - https://www.youtube.com/watch?vrgb9Xg3cJns 正文 视频应该是 杜比视界 电…

【C++漂流记】C++对象模型和this指针

C中对象模型和this指针是面向对象编程中的重要概念。对象模型描述了对象在内存中的布局和行为&#xff0c;包括成员变量和成员函数的存储方式和访问权限。this指针是一个隐含的指针&#xff0c;指向当前对象的地址&#xff0c;用于在成员函数中引用当前对象的成员变量和成员函数…

力扣 -- 416. 分割等和子集(01背包问题)

解题步骤&#xff1a; 参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:bool canPartition(vector<int>& nums) {int nnums.size();int sum0;for(const auto& e:nums){sume;}if(sum%21){return false;}int aimsum/2;//多开一行&#xff…

前端页面初步开发

<template><div><el-card class"box-card" style"height: 620px"><el-input v-model"query.name" style"width:200px" placeholder"请输入用户姓名"></el-input>&nbsp&nbsp&nbsp…

cesium 雷达扫描 (线行扩散效果)

cesium 雷达扫描 (线行扩散效果) 1、实现方法 使用ellipse方法加载圆型,修改ellipse中material方法来实现效果 2、示例代码 2.1、 <!DOCTYPE html> <html lang="en"><head><<

[Spring] Spring5——IOC 简介(二)

目录 六、工厂 Bean&#xff08;Factory&#xff09; 1、普通 bean 2、工厂 bean 3、示例 七、Bean 的作用域 1、单例和多例 2、如何设置为单实例或多实例 八、Bean 的生命周期 1、生命周期 2、生命周期示例 3、Bean 的后置处理器 4、后置处理器示例 九、XML 的自…

JavaScript设计模式

✨JavaScript设计模式 &#x1f380;设计模式 在 面向对象软件设计中针对特定问题的简洁而优雅的解决方案 &#x1f390;常见的设计模式 &#x1f384;1. 工厂模式 在JavaScript中&#xff0c;工厂模式的表现形式就是一个调用即可返回新对象的函数 // ------------- 工厂模…