ztwcom
v1.0.13
Published
优化
Readme
目录
1. three.js 加载速度优化工具loadModel
1.1 背景
加载大量或者体积大的3D模型时,页面会出现加载缓慢问题,本插件目的在于解决此种问题。
1.2 优化逻辑
1.使用浏览器indexedDB浏览器缓存机制,模型缓存到浏览器内,只有首次进行后台接口加载,其余都存缓存中取,只消耗页面渲染的时间,节省资源调用的时间。 2.通过时间参数进行计算,超过时间进行接口调用自动更新模型,保证模型是最新状态。 3.可以在控制台Application中,indexedDB中查看缓存的模型文件。
1.3 准备
由于本插件暂时只支持以three.js为基础的底层逻辑,所以务必请使用three.js渲染3D模型,不适用于其他插件,暂时只支持加载GLB模型文件。
1.4 参数设置
loadModel(db,glbUrl, GLTFLoader, timestamp = 1000 * 60 * 60 * 24)
|属性|说明|类型|默认值| |-|-|-|-| |db|数据库名称|Object|| |glbUrl|GLB模型路径|String|| |GLTFLoader|import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";引入||| |timestamp|模型更新时间戳(毫秒)|Number|1000 * 60 * 60 * 24|
1.5 返回值
此函数为Promise返回,返回值为模型的属性。
1.6 调用案例
1.通过 npm i ztwcom 下载依赖 2.使用 import {loadModel} from "ztwcom" 引入插件 3.引入three.js 和 GLTFLoader 4.调用 loadModel 5.具体调用实例
import { loadModel } from "ztwcom"
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; // 引入glb文件格式
let db = {
tdb: "time", // 时间库
mdb: "modeldb" // 模型库
}
loadModel(db,'/static/mainMap/测试模型.glb',new GLTFLoader,1000 * 60 * 60 *1).then((res)=>{
console.log(res.model,res.gltf)
})1.7 实际效果
首次加载模型文件加载耗时168ms
缓存加载模型文件未进行加载,直接调用缓存,无耗时
1.8 优化效果
1.优化后模型首次加载时间不变,缓存加载未调用模型资源,文件体量越大,文件数量越多,优化效果越明显,呈爆炸性增长效果显著。 2.拿本项目举例,首次消耗总时间199ms,二次消耗时间14ms,消耗时间为之前的十四分之一,效率提高了14倍。
1.9 不足
1.暂时只支持three.js中GLB文件格式。 2.首次加载依旧需要调用接口。
1.10 浏览器兼容性
1.11 indexedDB优势
1.优化效果显著。 2.大容量存储,通常没有存储容量的限制,对比cookie和localStorage。 3.支持复杂数据结构。 4.支持离线。
2. OBJ文件转成GLB文件(3D模型后台支撑)
2.1 背景
项目上需要展示3D矿图效果,当时前端框架选用了three.js进行渲染引擎,成功的满足了需求进行效果展示,但在后期一直有性能问题的困扰,前端同学做了一些优化,包括分布加载、采用nginx请求头缓存配置、浏览器缓存等机制。 在实践中,我们发现glb格式要比obj格式的文件小一些,此外,obj在加载的过程也容易丢失样式、纹理等文件,由于obj模型文件通常为一组格式mlt(纹理、样式)、png(贴图),因此在做前端浏览器缓存时,也存在问题,后来和前端同学商量后,我们决定将obj转成glb进行尝试。
2.2 两种文件格式简介
obj文件格式:
obj文件专注于存储3D模型的几何数据(顶点、纹理坐标、法线等),通过纯文本描述模型结构,是一组可读的文本语句,eg:v表示顶点定义模型;ojb会依赖外部文件,材质信息需客外MTL文件存储,不支持动画功能,支持贴图文件,png/jpeg
glb文件格式:
glb是GLTF标准的二进制版本,全称为“GL传输格式二进制文件”,将3D模型、纹理、材质、动画甚至场景光源打包为单一二进制文件。是一体化封装文件,所有资源饭知JSON元数据、纹理等都可以整合一体,其设计目标就是快速加载与高效解析,适配WEB和移动端
|对比维度|OBJ|GLB| |-|-|-| |文件大小|文本格式冗余,所以文件相对大|二进制压缩,相对小| |功能支持|无动画/场景支持|支持动画、光照、相机视角| |文件可读性|文本格式易上手|二进制文件难理解难编辑| |兼容性|广泛支持(3D打印/建模软件)|主流引擎/WebGL原生支持| |材质管理|需额外的MLT、PNG|内嵌纹理与材制裁|
2.3 转换案例
1.选用Node插件进行转换,首先可以用npm install obj2gltf安装插件,然后通过命令进行转换
# 安装node插件
npm install obj2gltf
# 格式转换命令
obj2gltf -i 源文件.obj -o 目标文件.glb
# 示例如下所示:
obj2gltf -i D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb 2.这个搞定了,剩的工作就简单了,如何动达转换呢,我们可以通过Java程序监听指定目录的新增、修改操作,然后对其变化的文件执行脚本调用,进行转换,思路有了,来码代码,先容我再啰嗦两句,把步骤描述如下所示: (1) obj2gltf是通过npm install obj2gltf安装的插件,用于模型格式转换操作 (2) 包下的node_module是将npm install 时产生的所有npm依赖都copy进去了。否则缺少依赖; (3) application.yml 中需要配置脚本文件的绝对路径,需引用obj2gltf下的bin下的obj2gltf.js (4) java引入Pom依赖 (5) java调用IO包中的Process类执行命令脚本 代码结果如下所示:
obj2gltf -i D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb
2.4 模型转换工具类
写了一个转换工具类,参数如下所示:
pom.xml依赖
<dependency>
<groupId>de.javagl</groupId>
<artifactId>jgltf-model</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/de.javagl/obj -->
<dependency>
<groupId>de.javagl</groupId>
<artifactId>obj</artifactId>
<version>0.3.0</version>
</dependency>Util工具类
package com.zhanglu.test.handle.util;
import com.zhanglu.test..handle.obj2gltf.ConvertObjToGltf;
import com.zhanglu.test..handle.obj2gltf.obj.BufferStrategy;
import com.zhanglu.test..handle.obj2gltf.obj.GltfWriteType;
import com.zhanglu.test..handle.obj2gltf.obj.IndicesComponentType;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@Slf4j
@SuppressWarnings("all")
public class NodeJsExcutorUtil {
public static void convertObjToGlb(String objPath,String glbPath,String scriptPath) {
BufferedReader reader = null;
try {
// 构建命令(根据安装方式调整)
String[] command = {
"node", //本地windows启动不加这个命令,不然会报错
scriptPath, // 局部安装使用 npx
"-i", objPath.trim(),
"-o", glbPath.trim()
};
ProcessBuilder builder = new ProcessBuilder(command);
System.out.println(builder.command());
builder.redirectErrorStream(true); // 将错误输出和标准输出合并,便于读取
Process process = builder.start();
reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"utf-8"));
String line;
while ((line = reader.readLine()) != null) {
log.info(line);
}
process.waitFor(); // 等待进程结束
log.info("【glb文件】转换成功");
} catch (Exception err) {
err.printStackTrace();
log.error("【glb文件】转换失败:{}",err.getMessage());
}finally {
try {
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
//本地如果是windows环境用以下脚本
String scriptPath = "D:\\web\\node_modules\\.bin\\obj2gltf.cmd";
//如果是Linux脚本用以下脚本
// String scriptPath = "scriptPath: /data/webapp/calamity/handle/obj2gltf/bin/obj2gltf.js";
String objPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷.obj";
String glbPath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj";
String glbFilePath="D:\\data\\mainMap\\主要系统巷道\\主要大巷.3dmobj\\主要大巷_1.glb";
NodeJsExcutorUtil.convertObjToGlb(objPath,glbFilePath,scriptPath);
}
}
Linux环境脚本引用说明
1.Linux环境脚本路径node安装obj2gltf包下的:obj2gltf/bin/obj2gltf.js; 2.命令:node /脚本实际路径/obj2gltf.js -i objFile.obj -o glbFile.glb

windows环境脚本引用说明
1.Windows 环境脚本路径node安装obj3gltf包下:node_modules\.bin\obj2gltf.cmd 2.命令: /脚本实际路径/obj2gltf.cmd -i objFile.obj -o glbFile.glb

感谢张璐组长技术支持,转自https://blog.csdn.net/xuxiannian/article/details/148792172
3. 页面自适应终极解决方案v-scale-screen
3.1 背景
大部分页面有2种自适应方式: 1.支持拉伸,长宽自适应,浏览器始终充满,图片可能会被异形屏(带鱼屏)拉扯变形。 2.固定比例宽高,如1920*1080,始终按照本比例自适应,修改窗口尺寸会出现空白,但图片不会被异常拉伸变形。 根据项目不同可能会选择对应的自适应方式,故需要一款能适应两种情况的自适应方案。
3.2 插件优势
1.v-scale-screen 插件基于vue.js,实现页面自适应,兼容PC端和移动端。 2.上述2种自适应方式都能满足,且更改方便。 3.无需转换单位,按照UI图px值即可自适应。
3.3 配置项
|属性|说明|类型|默认值| |-|-|-|-| |width|大屏宽度|Number or String|1920| |height|大屏高度|Number or String|1080| |autoScale|自适应配置,配置为 boolean 类型时,为启动或者关闭自适应,配置为对象时,若 x 为 true,x 轴产生边距,y 为 true 时,y 轴产生边距,启用 fullScreen 时此配置失效|Boolean or {x:boolean,y:boolean}|true| |delay|窗口变化防抖延迟时间|Number or String|500| |fullScreen|全屏自适应,启用此配置项时会存在拉伸效果,同时 autoScale 失效,非必要情况下不建议开启|Boolean|false| |boxStyle|修改容器样式,如居中展示时侧边背景色,符合 Vue 双向绑定 style 标准格式|Object|| |wrapperStyle|修改自适应区域样式,符合 Vue 双向绑定 style 标准格式|Object|| |bodyOverflowHidden|启用后 body 的样式会自动设置为 overflow: hidden|Boolean|true|
3.4 调用案例
1.安装 npm i v-scale-screen。 2.在起始页面中引入 import VScaleScreen from "v-scale-screen"。 3.在components中注入组件。 4.最外层添加 VScaleScreen 标签。 5.传入相关配置项即可。
App.vue(template)
<template>
<VScaleScreen :width="scaleScreen.width" :height="scaleScreen.height" :autoScale="scaleScreen.autoScale"
:fullScreen="scaleScreen.fullScreen" :boxStyle="scaleScreen.boxStyle">
<div id="app" :style="`width: ${scaleScreen.width}px; height: ${scaleScreen.height}px`">
<router-view></router-view>
</div>
</VScaleScreen>
</template>App.vue(script)
import VScaleScreen from 'v-scale-screen'
data () {
return {
scaleScreen: {
width: 1920, // ui画布尺寸
height: 1080, // ui画布尺寸
autoScale: {
x: true,
y: true
},
fullScreen: true, // 是否拉伸(固定1920*1080带白边用false,拉伸长宽满屏用true)
boxStyle: {
background: 'blue' // 背景色
}
}
}
}
components: {
VScaleScreen
},3.5 实际效果
固定1920*1080(窗口全屏)
固定1920*1080(特异尺寸窗口)
固定1920*1080(F11全屏)
拉伸1920*1080(窗口全屏)
拉伸1920*1080(特异尺寸窗口)
拉伸1920*1080(F11全屏)
3.6 v-scale-screen优势
1.适配各种需求的大屏。 2.只需修改一个参数fullScreen即可更改适配模式。 3.不用转换单位直接用px。 4.以1920*1080基础进行适配,虽有变形但为宽高等比形变。
3.7 分辨率,调度大屏相关问题
1.页面清晰度与显示器分辨率有关系,显示器分辨率越高,页面越清晰,投到调度室大屏越清晰。 2.页面清晰度与元素尺寸有关系,尺寸越大,字号越大,字重越小,页面越清晰,投到调度室大屏越清晰。(与页面缩放无关,页面缩放感觉清晰了,根本原因是元素尺寸变大了) 3.已有自适应的页面投到大屏后模糊与前端逻辑无关,优化方向着重UI,以及硬件设备显示器的分辨率。
4. 语音播报封装speaker
4.1 背景
1.本插件以原生SpeechSynthesisUtterance为基础封装。 2.众多项目对语音播报功能需求量大。 3.语音播报功能重新开发功能复杂不稳定,复用之前的代码会出现代码冗余性高。
4.2 准备
1.本插件出于简化逻辑,便于使用,提供语音按顺序循环播放,消除播放,暂停播放,恢复播放。
4.3 参数设置
speakMsg(soundDataMap,interval=2000) cancel() resume() pause()
|属性|说明|类型|默认值| |-|-|-|-| |soundDataMap|语音播报数据|Map|| |interval|每条播报之间的时间间隔|Number|2000|
4.5 调用案例
1.通过 npm i ztwcom 下载依赖 2.使用 import {speakMsg, cancel,resume,pause} from "ztwcom" 引入插件 3.调用 speakMsg, cancel,resume,pause 4.具体调用实例
import { speakMsg, cancel } from "ztwcom"
let msg = {
test1:"语音播报测试数据1",
test2:"语音播报测试数据2",
test3:"语音播报测试数据3",
}
speakMsg(msg,3000) // 语音开启播报
cancel() // 语音播报取消
resume() // 语音播报恢复
pause() // 语音播报暂停4.6 排查语音播报失效原因
1.保障谷歌浏览器,360极速浏览器最新版本
2.保障计算机声音为开启状态
![]()
如果计算机能发出任何声音,此处就能判断为开启状态(包含不限于视频声音,会议声音,语音声音)
3.查看浏览器是否开启声音 (1)点击浏览器右上角设置
(2)点击隐私与安全->点击网站设置。
(3)查找即使项目的网址,下方声音选择允许。
4.查找是否有中文语音包 (1)按下win+R (2)输入regedit
(3)一级一级查找路径 【计算机/HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens】
CN为中文语音包,查看文件是否完整,若不完整则系统少装了TTS中文语音包,需要单位运维人员协助,安装符合公司版本需求的语音包。
4.7 不足
语音播报无返回值

缓存加载模型文件未进行加载,直接调用缓存,无耗时


obj2gltf -i D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷_offset.obj -o D:\data\mainMap\主要系统巷道\主要大巷.3dmobj\主要大巷.glb
固定1920*1080(特异尺寸窗口)
固定1920*1080(F11全屏)

拉伸1920*1080(特异尺寸窗口)
拉伸1920*1080(F11全屏)


如果计算机能发出任何声音,此处就能判断为开启状态(包含不限于视频声音,会议声音,语音声音)
(2)点击隐私与安全->点击网站设置。
(3)查找即使项目的网址,下方声音选择允许。

(3)一级一级查找路径
【计算机/HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens】
CN为中文语音包,查看文件是否完整,若不完整则系统少装了TTS中文语音包,需要单位运维人员协助,安装符合公司版本需求的语音包。