Uniapp renderjs
东北小麦客 2023-06-13 UniApp学习笔记
!!! 该案例在 uniappX vue3
下进行 !!!
# 一、renderjs
的使用
在
Uniapp x
使用 cesium、 threejs 等需要操作DOM元素的框架,需要用到renderjs
# 1-1. 在Uniapp x
使用 cesium,编辑CesiumCom.vue
组件
<template>
<!-- #ifdef APP-PLUS || H5 -->
<view id="container"></view>
<!-- #endif -->
<!-- #ifndef APP-PLUS || H5 -->
<view>非 APP、H5 环境不支持</view>
<!-- #endif -->
</template>
<script module="Cesium" lang="renderjs">
const AccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5YzQ4ZWE5OC0yZDlhLTQyYmUtYWRhNy0wYTdlZDhjZmZiYmIiLCJpZCI6OTE3NjksImlhdCI6MTY1MTIyMzIwOX0.JENijAX01-Jwm5w2oPLmr-7eoarDChNBuDcfeqrn5QQ";
const widgetsUrl = 'https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Widgets/widgets.css';
const cesiumUrl = 'https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Cesium.js';
const datGuiUrl = 'https://cdn.bootcdn.net/ajax/libs/dat-gui/0.7.9/dat.gui.min.js';
let viewer;
export default {
data() {
return {
domlist: null, // 动态引入dom标签合集
// viewer: null, // 三维视窗
// tilesetData: null, // 三维数据
moduleHeight: 0 ,// 模型距离地表高度
}
},
mounted() {
this.initResources();
},
methods: {
// 初始化资源,加载后例化cesium
initResources() {
if (this.domlist) {
this.removeResource();
} else {
// 动态引入css文件
const linkDom = document.createElement('link');
linkDom.rel = "stylesheet";
linkDom.href = widgetsUrl;
document.head.appendChild(linkDom);
const cesiumS = this.requireResources('script', cesiumUrl, this.initCesium);
const datGuiS = this.requireResources('script', datGuiUrl);
this.domlist = [linkDom, cesiumS, datGuiS];
}
},
// 动态创建script引用第三方类库
requireResources(dom, src, callback) {
// 动态引入较大类库避免影响页面展示
const script = document.createElement(dom)
// view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
script.src = src;
document.head.appendChild(script);
callback && (callback instanceof Function) && (script.onload = callback.bind(this));
return script
},
// 移除动态添加的标签,避免重复添加标签
removeResource() {
if (this.domlist)
for (let i = 0; i < this.domlist.length; i++) {
document.head.removeChild(this.domlist[i])
}
},
initDatGui() {
const gui = new dat.GUI();
const items = gui.addFolder('Load 3dtiles');
const commonUpload = async (callback) => {
const res = await showDirectoryPicker();
const fileList = [];
// 递归获取文件结构
const detalAction = async (obj) => {
let res = {};
if (obj.entries) {
const dirs = obj.entries();
for await (const entry of dirs) {
res[entry[0]] = entry[1].entries ? { type: 'directory', children: await detalAction(entry[1]) } : { type: 'file', fileHandle: entry[1] };
}
}
return res;
}
const files = await detalAction(res);
const rootFile = await files['tileset.json'].fileHandle.getFile()
callback(URL.createObjectURL(rootFile), files);
};
items.add({
'select 3dtilsets': () => {
commonUpload((url, files) => {
Cesium.Cesium3DTileset.fromUrl(new Cesium.Resource({ url, localFiles: files })).then((tile) => {
tileset = viewer.scene.primitives.add(tile);
viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.3, 0.0));
});
});
}
}, 'select 3dtilsets');
},
// 初始化
initCesium() {
// console.log(window.Cesium.VERSION) // APP可运行
Cesium.Ion.defaultAccessToken = AccessToken;
viewer = new Cesium.Viewer('container', {
//需要进行可视化的数据源的集合
animation: false, //是否显示动画控件
shouldAnimate: true,
homeButton: false, //是否显示Home按钮
fullscreenButton: false, //是否显示全屏按钮
baseLayerPicker: false, //是否显示图层选择控件
geocoder: false, //是否显示地名查找控件
timeline: false, //是否显示时间线控件
sceneModePicker: false, //是否显示投影方式控件
navigationHelpButton: false, //是否显示帮助信息控件
infoBox: true, //是否显示点击要素之后显示的信息
requestRenderMode: true, //启用请求渲染模式
scene3DOnly: true, //每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
fullscreenElement: document.body, //全屏时渲染的HTML元素 暂时没发现用处
globe: false, // 不显示地球
//设置纯色背景
contextOptions: {
webgl: {
alpha: true,
}
},
})
viewer._cesiumWidget._creditContainer.style.display = 'none'; //隐藏版本信息
// viewer.scene.debugShowFramesPerSecond = true; // 显示帧数
viewer.scene.skyBox.show = false //关闭天空盒,否则会显示天空颜色
//背景透明
// viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0);
// 设置缩放级别
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 300;
// this.initDatGui();
// 请求3dtiles数据
this.load3dtileset();
},
load3dtileset() {
const tilesReq = new Cesium.Cesium3DTileset({
url: 'http://xiaomaike.space:6089/3dtiles/data/floor/tileset.json',
maximumScreenSpaceError: 2,
});
// 数据请求完成后加载
tilesReq.readyPromise.then((tile) => {
const tileset = viewer.scene.primitives.add(tile);
//获取3Dtlies的bounds范围
const boundingSphere = tileset.boundingSphere;
viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, -1, tileset.boundingSphere.radius * 0.5));
});
},
load3dtilesetByLocal(url) {
console.log('url', url);
// Cesium.Cesium3DTileset.fromUrl(new Cesium.Resource({ url, localFiles: files })).then((tile) => {
Cesium.Cesium3DTileset.fromUrl(new Cesium.Resource({ url })).then((tile) => {
const tileset = viewer.scene.primitives.add(tile);
//获取3Dtlies的bounds范围
const boundingSphere = tileset.boundingSphere;
viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, -1, tileset.boundingSphere.radius * 0.5));
});
},
},
beforeDestroy() {
this.removeResource()
},
}
</script>
<style>
#container {
width: 100%;
height: 100vh;
/* height: calc(100vh - 44px); */
/* background: #0ff; */
}
</style>
# 1-2. 在父组件进行使用
<template>
<view class="content">
<view class="btn">
<button @click="open" size="mini">文件选择</button>
</view>
<CesiumCom />
</view>
</template>
<script>
import CesiumCom from "./CesiumCom.vue"
// import { ref, onMounted } from "vue";
// // import { openFileModal } from "@/components/SelectFile.js"
// onMounted(() => {
// // const { ctx } = getCurrentInstance()
// console.log('$cesium', getCurrentInstance());
// })
// const fileUrl = ref('106');
// async function open() {
// const res = await openFileModal();
// console.log('path:', JSON.stringify(res));
// if(res.code === 'success') {
// const item = res.res[0] || {};
// fileUrl.value = item.pathHolp;
// }
// };
export default {
data(){
return {
fileUrl: '',
}
},
components: {
CesiumCom,
},
methods: {
async open() {
const res = await this.$openFileModal();
console.log('path:', JSON.stringify(res));
if(res.code === 'success') {
const item = res.res[0] || {};
this.fileUrl = item.pathHolp;
}
}
}
}
</script>
<style>
.content {
}
.btn {
position: fixed;
top: 10vh;
left: 50rpx;
z-index: 9;
width: 300rpx;
height: 50rpx;
}
</style>