当前位置: 首页 > wzjs >正文

pc官方网站做网站公司

pc官方网站,做网站公司,做网站开发需要什么,网站图片上字体动态怎么做的系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…

请添加图片描述

系列文章目录

Three.js 快速入门教程【一】开启你的 3D Web 开发之旅
Three.js 快速入门教程【二】透视投影相机
Three.js 快速入门教程【三】渲染器
Three.js 快速入门教程【四】三维坐标系
Three.js 快速入门教程【五】动画渲染循环
Three.js 快速入门教程【六】相机控件 OrbitControls
Three.js 快速入门教程【七】常见几何体类型
Three.js 快速入门教程【八】常见材质类型
Three.js 快速入门教程【九】光源类型
Three.js 快速入门教程【十】常见的纹理类型
Three.js 快速入门教程【十一】天空盒的多种实现方式
Three.js 快速入门教程【十二】外部模型加载
Three.js 快速入门教程【十三】外部模型加载后常见的处理操作
Three.js 快速入门教程【十四】使用Stats.js监控渲染帧率和性能优化
Three.js 快速入门教程【十五】交互神器DragControls使用详解,实现对物体或模型拖拽
Three.js 快速入门教程【十六】调试神器 gui.js使用详解,可视化面板控制场景参数提高开发效率
Three.js 快速入门教程【十七】射线拾取模型——射线与射线投射器Raycaster介绍
Three.js 快速入门教程【十八】射线拾取模型——鼠标点击屏幕选中模型或物体
Three.js 快速入门教程【十九】CSS2D渲染器介绍,实现场景中物体或设备标注标签信息
Three.js 快速入门教程【二十】三维模型优化实战:使用gltf-pipeline与Draco对模型进行压缩,提高加载速度和流畅性


文章目录

  • 系列文章目录
  • 一、前言
  • 二、CSS2DRenderer(CSS2D渲染器)介绍
  • 三、CSS2DObject(CSS2D模型对象)
  • 四、使用CSS2DRenderer渲染标签
    • Canvas画布事件失效修复
    • 把标签添加到网格模型中
  • 五、实战开发——点击显示模型中设备标签
  • 六、总结


一、前言

      在 Three.js 中构建 3D 场景时,有时我们需要为场景中的设备或对象添加标签标注,以提供更多的信息。本文将讲解如何使用 CSS2DRenderer 在 Three.js 场景中实现设备标签标注


二、CSS2DRenderer(CSS2D渲染器)介绍

CSS2DRenderer 是 Three.js 提供的一个非常有用的工具,它允许我们使用 CSS 和 HTML 来创建 2D 元素,并将它们渲染到 3D 场景中,使其能够跟随场景中的对象移动和旋转,同时保持 2D 界面的灵活性和易操作性。

与传统DOM叠加方案相比,Three.js提供的CSS2DRenderer具有独特优势:

  • 完美保持CSS布局能力

  • 自动同步3D世界坐标

  • 原生支持DOM事件

  • 高性能的标签渲染


三、CSS2DObject(CSS2D模型对象)

在 Three.js 里,CSS2DObject 是一个很实用的类,可以把一个HTML元素转化为一个类似threejs网格模型的对象,并添加到3D场景中以 2D 的形式展示。这在你想要给 3D 场景中的对象添加标签、工具提示等 2D 界面元素时非常有用。

(1) 首先创建一个HTML元素:

<div id="tag">标签</div>

也可以通过js代码生成:

// 创建一个HTML元素作为标签
const tagElement = document.createElement('div');
tagElement.textContent = '标签';

(2) 创建CSS2DObject并将标签元素添加到其中


import { CSS2DObject} from "three/addons/renderers/CSS2DRenderer.js";const tagElement=document.getElementById('tag')
const tagObject= new CSS2DObject(tagElement);
tagObject.position.set(0, 0, 0); // 设置标签在3D场景中位置
scene.add(tagObject);//添加到3D场景中

此过程html标签转换为CSS2D模型对象并添加到3D场景中,它跟网格模型一样可以通过position设置位置。但在界面中还无法显示,因为CSS2D模型对象还未被渲染到页面中。接下去需要使用特定渲染器CSS2DRenderer把CSS2D模型对象渲染到页面。


四、使用CSS2DRenderer渲染标签

普通三维场景我们使用的是WebGLRenderer渲染器,而CSS2DRenderer专门用来渲染HTML标签,CSS2DRenderer和WebGLRenderer用法几乎一样,也包括.domElement属性和setSize(),.render()等方法

我们知道WebGLRenderer渲染三维场景会生成一个canvas画布并插入到页面显示。
CSS2DRenderer同样会生成一个外层为div,子元素为插入的CSS2D模型对象对应的html元素(标签),该div和canvas为相邻的兄弟节点,我们可以通过设置css属性使得div叠加到canvas上面,因为背景透明大小一样,标签看起来就像在canvas三维场景中。

// 引入CSS2渲染器CSS2DRenderer
import { CSS2DRenderer } from 'three/addons/renderers/CSS2DRenderer.js';// 创建WebGLRenderer渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建 CSS2DRenderer
const cssRenderer = new CSS2DRenderer();
cssRenderer.setSize(window.innerWidth, window.innerHeight);//设置画布尺寸
cssRenderer.domElement.style.position = 'absolute';//设置画布布局方式
cssRenderer.domElement.style.top = "0"; //设置画布位置
cssRenderer.domElement.style.left = "0";
document.body.appendChild(cssRenderer.domElement);//画布插入页面// 渲染循环动画function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);//重新渲染cssRenderer.render(scene, camera);}// 执行动画animate();

查看元素节点:
在这里插入图片描述

运行效果:
在这里插入图片描述

改变标签位置观察变化

tagObject.position.set(0, 5, 0); // 设置标签在3D场景中位置

在这里插入图片描述

Canvas画布事件失效修复

由于cssRenderer.domElement绝对定位到canvas上面导致canvas相关事件失效,像画布射线拾取、OrbitControls控制器等操作都无效。可通过改变cssRenderer.domElement 的css属性,把pointerEvents 值设置为none取消其对鼠标事件的响应。

  cssRenderer.domElement.style.pointerEvents="none"

把标签添加到网格模型中

上述示例我们把标签模型对象(CSS2D模型)添加到scene中,设置的位置相对于整个三维场景的世界坐标。当我们需要给场景中每个物体标注标签(实际开发中常见于给工厂设备贴标签),就需要把标签模型对象添加到网格模型(设备)中,设置的位置相对于网格模型局部坐标。

示例如下:

import { onMounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
import {CSS2DRenderer,CSS2DObject,
} from "three/addons/renderers/CSS2DRenderer.js";// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x333333);
//坐标辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
// 创建相机
const camera = new THREE.PerspectiveCamera( // 透视相机75, // 视角 角度数window.innerWidth / window.innerHeight, // 宽高比 占据屏幕0.1, // 近平面(相机最近能看到物体)3000 // 远平面(相机最远能看到物体)
);
camera.position.set(2, 5, 10);
// 创建WebGLRenderer渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//加入点光源
let pointLight = new THREE.PointLight(0xffffff, 15, 1000, 1);
pointLight.position.set(3, 3, 3);
scene.add(pointLight);// 创建一个立方体作为设备对象
const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const boxMaterial = new THREE.MeshLambertMaterial({ color: 0x1678e2 });
const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
//设置立方体位置
boxMesh.position.set(2, 2, 2);
scene.add(boxMesh);// 创建一个 HTML 元素作为标签
const labelElement = createLabelElement("立方体");
// 创建 CSS2DObject 并将标签元素添加到其中
const label = new CSS2DObject(labelElement);
// 设置标签相对于设备对象的位置
label.position.set(0, 1, 0);
//标签添加到立方体
boxMesh.add(label);//创建一个CSS2渲染器
const css2Renderer = new CSS2DRenderer();
css2Renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(css2Renderer.domElement);
css2Renderer.domElement.style.position = "absolute";
css2Renderer.domElement.style.top = 0;
css2Renderer.domElement.style.pointerEvents = "none";//创建标签Dom
function createLabelElement(text) {const labelElement = document.createElement("div");labelElement.textContent = text;labelElement.style.backgroundColor = "white";labelElement.style.padding = "5px";labelElement.style.border = "1px solid black";labelElement.style.borderRadius = "5px";return labelElement;
}// 控制器
const control = new OrbitControls(camera, renderer.domElement);// 渲染循环动画
function animate() {requestAnimationFrame(animate);control.update();renderer.render(scene, camera);css2Renderer.render(scene, camera);
}// 执行动画
animate()

请添加图片描述


五、实战开发——点击显示模型中设备标签

在工业数字孪生开发场景中,我们常遇到这样的需求,通过点击外部模型中的设备显示对应设备名称,实现这个功能需要结合前面介绍的射线拾取模型技术来完成。

import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
//导入gltf加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 引入CSS2渲染器CSS2DRenderer和CSS2模型对象CSS2DObject
import {CSS2DRenderer,CSS2DObject,
} from "three/addons/renderers/CSS2DRenderer.js";// 创建场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x333333);
//坐标辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
// 创建相机
const camera = new THREE.PerspectiveCamera( // 透视相机75, // 视角 角度数window.innerWidth / window.innerHeight, // 宽高比 占据屏幕0.1, // 近平面(相机最近能看到物体)3000 // 远平面(相机最远能看到物体)
);
camera.position.set(2, 5, 10);
// 创建WebGLRenderer渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 1.8);
scene.add(ambientLight);//加入点光源
let pointLight = new THREE.PointLight(0xffffff, 15, 1000, 1);
pointLight.position.set(3, 3, 3);
scene.add(pointLight);//创建一个CSS2渲染器
const css2Renderer = new CSS2DRenderer();
css2Renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(css2Renderer.domElement);
css2Renderer.domElement.style.position = "absolute";
css2Renderer.domElement.style.top = 0;
css2Renderer.domElement.style.pointerEvents = "none";// 创建加载器实例
const loader = new GLTFLoader();// 异步加载模型
loader.load("model.gltf", //模型路径,根据实际修改(gltf) => {const model = gltf.scene;//射线拾取模型handleRaycaster(model);//模型添加到场景中scene.add(model);},(xhr) => {console.log(`已加载 ${(xhr.loaded / xhr.total) * 100}%`);},(error) => {console.error("加载失败:", error);}
);
/*** 射线拾取处理*  @param {*} model:模型对象*/
function handleRaycaster(model) {// 创建射线投射器const raycaster = new THREE.Raycaster();// 创建一个二维向量用于存储标准设备坐标const mouse = new THREE.Vector2();//渲染画布let canvas = renderer.domElement;// 添加画布点击事件canvas.addEventListener("click", function (event) {//屏幕坐标转标准设备坐标mouse.x = (event.offsetX / canvas.clientWidth) * 2 - 1; //标准设备坐标xmouse.y = -(event.offsetY / canvas.clientHeight) * 2 + 1; //标准设备坐标y// 通过鼠标位置和相机信息更新射线投射器raycaster.setFromCamera(mouse, camera);// 检测射线与设备相交情况const intersects = raycaster.intersectObject(model, true);//有选中设备if (intersects.length > 0) {//设备对象let object = intersects[0].object;//显示设备标签showLabel(object);}});
}//上一个显示标签的设备对象
let lastDeviceObj = null;
//上一个显示的标签对象
let lastLabelObj = null;
/*** 显示标签* @param {*} object:点击选中的设备对象*/
function showLabel(object) {// 清除上一个标签if (lastDeviceObj && lastLabelObj) {lastDeviceObj.remove(lastLabelObj);}// 创建一个 HTML 元素作为标签,内容为设备名称const labelElement = createLabelElement(object.name);// 创建 CSS2DObject 并将标签元素添加到其中const label = new CSS2DObject(labelElement);// 设置标签相对于设备对象的位置label.position.set(0, 1, 0);//标签添加到设备对象中object.add(label);//保存标签和设备lastDeviceObj = object;lastLabelObj = label;
}
//创建标签Dom
function createLabelElement(text) {const labelElement = document.createElement("div");labelElement.textContent = text;labelElement.style.backgroundColor = "white";labelElement.style.padding = "5px";labelElement.style.border = "1px solid black";labelElement.style.borderRadius = "5px";return labelElement;
}// 控制器
const control = new OrbitControls(camera, renderer.domElement);// 渲染循环动画
function animate() {requestAnimationFrame(animate);control.update();renderer.render(scene, camera);css2Renderer.render(scene, camera);
}// 执行动画
animate();

上述示例代码通过射线拾取获取到鼠标点击选中的设备,给设备对象添加标签模型就能显示对应的设备名称。

运行效果:

请添加图片描述


六、总结

        通过本篇文章,我们详细介绍了在 Three.js 中使用 CSS2DRenderer 的方法。从创建渲染器实例、添加 HTML 元素到处理交互以及与 3D 场景结合,CSS2DRenderer 为我们在 3D 场景中创建 2D 界面元素提供了便利的工具。希望这篇教程能够帮助你在 Three.js 项目中更好地应用这一特性,创造出更加丰富和交互性强的 3D 应用。

更多three.js入门知识点请关注该系列教程后续的更新。

http://www.dtcms.com/wzjs/44590.html

相关文章:

  • 淘宝网站开发框架山东一级造价师
  • 深圳网站建设制作网络公司什么是搜索推广
  • 汕头老城区图片seo研究中心好客站
  • 网站开发费用摊销吗提交网址给百度
  • 福州企业免费建站百度seo关键词优化电话
  • 网站的开发设计的技术合肥seo公司
  • 网站开发 合作协议旅游景点推广软文
  • 搭建一个网站需要多久南京百度推广
  • 做网站和制作网页的区别产品推广
  • wordpress 网站积分打赏sem是什么测试
  • 黄骅港天气哪里能搜索引擎优化
  • 专业做网站的公司有哪些南京seo圈子
  • 做网站总费用独立站怎么搭建
  • wordpress 文章循环在线seo短视频
  • 现在一般做网站用什么技术最有效的恶意点击软件
  • 做网站什么程序好女教师遭网课入侵直播录屏曝光视频
  • 自己做的网站如何放到微信网络运营工作内容
  • 网站的统计 怎么做推广网站都有哪些
  • 有哪些可以在网上做兼职的网站危机舆情公关公司
  • 建设银行的投诉网站首页云优化软件
  • 优品ppt模板免费下载官网重庆seo结算
  • 厦门网站推广的目标黄金网站软件免费
  • 怎么用手机做网站平台利尔化学股票最新消息
  • 网站建设网络公网页搜索排名提升
  • 昆明网站制作策划怎么注册域名
  • 如何提高网站索引量正规网络推广服务
  • 日产一区一区三区不卡排名优化哪家专业
  • 做网站需要公司么重庆seo排名方法
  • 什么叫网站的空间感新闻发稿软文推广
  • 保险公司网站建设方案写软文推广