three.js 添加html内容、文本
需求:
1、在场景内添加html元素并动态更新
2、html内容需跟随场景变化
方案:
新加方案:https://www.zhihu.com/question/49929467/answer/118602848
1、在场景内创建一个模型点(多个模型点最好分组,方便管理)
2、获取到模型点
3、创建html元素
4、将html元素绑定到模型位置(将场景的3D坐标转为2D)
5、实时计算元素位置 (显示隐藏)
animate() {
// 动画函数
this.render();
window.requestAnimationFrame(() => this.animate());
TWEEN.update();
this.orbitControls.update();
this.update(); // 更新点
},
LoadBox() {
// 创建点。
this.groups = new THREE.Group();
this.groups.name = "btnlist";
for (let index = 0; index < this.nowfloat.length; index++) {
const element = this.nowfloat[index].XYZ;
console.log(element);
let floorGeometry1 = new THREE.PlaneGeometry(1, 1, 1);
var sphereMaterial = new THREE.MeshFaceMaterial({
color: 0xff00ff,
// side: THREE.BackSide,
// visible: false,
});
var floorspheres = new THREE.Mesh(floorGeometry1, sphereMaterial);
floorspheres.position.set(
element.x,
element.y + element.s / 2,
element.z
);
floorspheres.name = this.nowfloat[index].id; //default
this.groups.add(floorspheres);
}
this.buffer_scene.add(this.groups);
// this.render()
},
update() {
// 更新css2D内容位置
let halfWidth = window.innerWidth/2 ;
let halfHeight = window.innerHeight/2;
var btnlist = this.buffer_scene.getObjectByName("btnlist");
if (!btnlist) return;
btnlist.traverse((e) => {
var vector = e.position.clone().project(this.buffer_camera);
var htmls = document.getElementsByClassName(e.name)[0];
if (htmls) {
var left = vector.x * halfWidth + halfWidth; // + halfWidth
var top = -vector.y * halfHeight + halfHeight; //+ halfHeight
// console.log(vector.x,vector.y)
if(vector.z >1){
htmls.style = 'display: none;';
}else{
htmls.style = `width:auto;display: flex;position: absolute;left:${
left
}px;top:${top}px`;
}
}
});
},
有几种方案
一、直接将文本P成为图片 然后在场景内加载 2D模型将该图片当作模型贴图处理
二、将html内容通过canvas 然后再以模型的方式加载进场景(不做详细解释)
1、创建
getTextCanvas(text){
// 创建贴图文字
var width=512, height=256;
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#008080';
ctx.fillRect(0, 0, width, height);
ctx.font = 50+'px " bold';
ctx.fillStyle = '#FFFFFF';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, width/2,height/2);
return canvas;
},
2、加载
var geometry = new THREE.PlaneGeometry(e.w, e.h, 30 );
var material = new THREE.MeshBasicMaterial(
{
// map:new THREE.CanvasTexture(this.getTextCanvas(e.content)), // canvas 画图方式
map:new THREE.TextureLoader().load(`${this.GLOBAL.service}img/043img/btn/${e.content}.png`),
} );
var introduce = new THREE.Mesh( geometry, material );
introduce.name= "model introduce"
// plane.location=i.location
introduce.modeltype= 3 //
introduce.position.set(x,y,z);
introduce.lookAt(0,y,0)
skyBox.add(introduce);
三、用CSS2DObject进行处理
1、增加渲染器 CSS2DRenderer
2、使用 three.js 的 CSS2DObject 模块 进行html内容转换 并绑定模型
一般需要这个功能的肯定都不是新手了,所以内容就不做介绍了,这里只需要关注几点
1、增加渲染器(原有的渲染器不动,新增一个CSS2DRenderer渲染器 ):
addhtml() {
// 场景渲染器
this.renderer = new THREE.WebGLRenderer();
this.renderer.shadowMapEnabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// this.renderer.gammaOutput = true;
this.renderer.gammaFactor = 2.2;
// this.renderer.setClearColor(new THREE.Color(0xcce0ff));
this.renderer.setSize(window.innerWidth*0.95, window.innerHeight*0.95);
document
.getElementById("container")
.appendChild(this.renderer.domElement);
// window.addEventListener("resize", () => this.onWindowResize());
this.labelRenderer = new CSS2DRenderer(); // 新增的渲染器
this.labelRenderer.setSize(window.innerWidth*0.95, window.innerHeight*0.95);
// this.labelRenderer.domElement.style.position = 'absolute';
// this.labelRenderer.domElement.style.top = 0;
this.labelRenderer.domElement.style="pointer-events: auto;position: absolute;top: 0px;" // 处理新的渲染器
document.getElementById("container").appendChild(this.labelRenderer.domElement);
},
animate() {
// 渲染
this.renderer.render(this.scene, this.camera);
this.labelRenderer.render(this.scene, this.camera);// 加载新渲染器
window.requestAnimationFrame(() => this.animate());
TWEEN.update();
},
注意:官网示例只适应于全屏的情况 不全屏的情况请自行调整
2、增加内容容器:
<template>
<div class="project">
<div id="text" style=" position: relative;width: 30%;
height: 100px;
color: #fff;">
{{modelnumber}}
</div>
<div id="container"> </div>
</template>
3、绑定模型(创建模型什么的这里就不解释了):
// 2D 文本
// let laberDiv = document.createElement('div');//创建div容器
let laberDiv = document.getElementById('text');//获取div容器
// laberDiv.innerHTML=`
// <div class="leftTip" style="">
// ${this.modelnumber}
// </div>
// `;
laberDiv.style.marginTop = '-1em';
let pointLabel = new CSS2DObject(laberDiv);
pointLabel.position.set(0,100,0); // 相对模型的位置
console.log(pointLabel)
skyBox.add(pointLabel); //绑定到模型
也看到了,你也可以选择直接新建一个容器、但是我尝试的时候内容无法动态变化、如果你不需要动态变化也可以直接新建
找资料的时候看到一个问题(没有尝试)、创建的这个容器切换场景不会消失、需要注意处理、这个创建出来的不在模型列表内、而是在dom里面、所以遇到这个情况、请尝试直接处理dom
效果:

注:
前面两种方式是直接在场景内加载一个模型、第三种方式是将元素绑定在模型上
three.js 添加html内容、文本的更多相关文章
- react修改app.js添加中文内容后中文部分乱码解决
[问题]:配置完react后修改app.js内容时添加中文出现如下乱码的中文. [A解决]文档——文本编码——转换文本编码,在弹出窗口修改,确定,搞定 [B解决]首先在EditPlus内:工具——首选 ...
- JS添加删除一组文本框并对输入信息加以验证
在做项目中遇到这样一个问题,就是我们需要添加几组数据到数据库,但是具体几组数据不确定,有客户来填写,比如我们需要添加打折策略,可能个策略有很多组方案,比如“满100打5折,满200打4折,满500打3 ...
- 用JS添加文本框案例代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 通过 js 修改 html 的文本内容或者样式
通过 js 修改 html 的文本内容 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- JS控制页面内容
JS操作页面内容 innerText:普通标签内容(自身文本与所有子标签文本)innerHTML:包含标签在内的内容(自身文本及子标签的所有)value:表单标签的内容outerHTML:包含自身标签 ...
- atitit.js的 字符串内容 转义 js处理html
atitit.js的 字符串内容 转义 js处理html 1. js处理html的问题 1 2. js的 字符串内容 转义 1 2.1. 处理流程 1 3. 下面的表格列出了其余的特殊字符,这些特殊 ...
- 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结
史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...
- JS 仿支付宝input文本输入框放大组件
input输入的时候可以在后边显示数字放大镜 <!doctype html> <html lang="en"> <head> <meta ...
- 解决UEditor编辑时,只添加视频内容,不添加文字,视频信息不能保存到数据库的问题
造成这个问题的原因是富文本保存内容时会筛除空标签,然后统计是否有内容,通过字数统计也可以看到,上传完视频后字数还是零,因为视频上传后是<video></video>标签,这个标 ...
随机推荐
- NOIP 模拟 $15\; \rm \text{玫瑰花精}$
题解 \(by\;zj\varphi\) 一道线段树题目 这道题可以通过维护一棵线段树,线段树上的每个节点维护 \(\rm l,r,len,p\) 分别表示这段区间最左边的花精,最右边的花精,被两只花 ...
- 【转】ps命令详解与使用
ps 概述 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态 ...
- 基于mysql和Java Swing的简单课程设计
摘要 现代化的酒店组织庞大.服务项目多.信息量大.要想提高效率.降低成本.提高服务质量和管理水平,进而促进经济效益,必须利用电脑网络技术处理宾馆酒店经营数据,实现酒店现代化的信息管理.本次课程设计运用 ...
- SpringCloud之网关zuul
1.微服务网关介绍和使用场景 1)什么是网关 API Gateway,是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求.鉴权.监控.缓存.限流等功能 统一接入 智 ...
- linux 常用命令(四)——(centos7-centos6.8)Vim安装
centos是默认安装了vi编辑器的,vim编辑器是没安装或者未完全安装的,个人习惯用vim,所以记录一下vim编辑器的安装: 1.查看vim相关软件信息: yum search vim 2.在线安装 ...
- CentOS7中apache的部署与配置
一.apache的部署 输入命令 yum list | grep httpd 查看可安装的软件包,选择"httpd.x86_64"安装. 输入命令 yum install http ...
- MySQL-存储引擎-Myisam
mysql> create table myisam_char(name char(10)) engine=myisam; Query OK, 0 rows affected (0.01 sec ...
- nios eclipse提示LED_PIO_BASE没有声明,怎么回事?
这是因为名字不一致引起的比如,在生成SOPC系统时,双击PIO(Parallel I/O)(在Avalon Modules -> Other 下),为系统添加输出接口,你没有把该组件改名成LED ...
- 剑指 Offer 32 - III. 从上到下打印二叉树 III
剑指 Offer 32 - III. 从上到下打印二叉树 III 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印, ...
- MyBatis学习总结(四)——字段名与实体类属性名不相同的冲突的解决
表中的字段名和表对应实体类的属性名称不一定都是完全相同的,这种情况下的如何解决字段名与实体类属性名不相同的冲突.如下所示: 一.准备演示需要使用的表和数据 CREATE TABLE my_user( ...