赞
踩
- <script setup>
-
- import { ref, getCurrentInstance, onMounted, beforeUnmount } from 'vue'
-
- import * as BABYLON from '@babylonjs/core/Legacy/legacy' // 全部引入
-
- import '@babylonjs/loaders' // 模型加载loader
-
- import * as GUI from '@babylonjs/gui/2D' // 交互组件
-
- const { proxy } = getCurrentInstance()
-
- const emit = defineEmits(['customChange'])
-
- let engine = ref(null)
-
- let scene = ref(null)
-
- let camera = ref(null)
-
-
-
- // 模型加载进度百分比
-
- let progress = ref(0)
-
- // 是否完成模型渲染
-
- let isRendering = ref(false)
-
- // 是否展示视频
-
- let showVideo = ref(false)
-
-
-
- // 自适应渲染
-
- const engineResize = ()=> {
-
- engine.resize();
-
- }
-
- // 重置模型
-
- const reset = ()=> {
-
- scene.activeCamera.restoreState();
-
- }
-
- onMounted(() => {
-
- let canvas = document.getElementById('canvas');
-
- // 初始化 BABYLON 3D engine
-
- engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, disableWebGL2Support: false });
-
- // 自定义loading加载效果
-
- function customLoadingScreen() {
-
- console.log('customLoadingScreen creation');
-
- }
-
- customLoadingScreen.prototype.displayLoadingUI = function() {
-
- console.log('customLoadingScreen loading')
-
- };
-
- customLoadingScreen.prototype.hideLoadingUI = function() {
-
- window.document.getElementById('loadingScreen').style.display = 'none';
-
- };
-
- engine.loadingScreen = new customLoadingScreen();
-
- // 初始化一个场景 scene
-
- scene = new BABYLON.Scene(engine);
-
- // 设置背景色透明
-
- scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
-
- // 初始化相机 camera
-
- camera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 0, new BABYLON.Vector3(0, 0, 0), scene);
-
- /*
- * 天空盒
- */
-
- // 创建天空盒
-
- const skybox = BABYLON.Mesh.CreateBox('skyBox', 21000, scene),
-
- skyboxMaterial = new BABYLON.StandardMaterial('skyboxMaterial', scene);
-
- // 关闭掉材质的背面剔除(在盒子内部也可以看到盒子)
-
- skyboxMaterial.backFaceCulling = false;
-
- // 删除盒子上的反射光(天空不会反射太阳)
-
- skyboxMaterial.disableLighting = true;
-
- // 载入天空贴图(CubeTexture是贴图加载器,只能被应用到reflectionTexture)
-
- skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture('textures/sky', scene);
-
- // 修改贴图模式(reflectionTexture是反射贴图,但我们需要天空盒贴图)
-
- skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
-
- skybox.material = skyboxMaterial;
-
- // 设置天空盒跟随相机位置移动(盒子不会收缩)
-
- skybox.infiniteDistance = true;
-
- /*
- * 3D模型
- */
-
- // 引入外部obj模型
-
- BABYLON.SceneLoader.Append('babylon/1/', 'model.glb', scene, (object) => {
-
- // 设置默认相机和灯光
-
- scene.createDefaultCameraOrLight(true, true, true);
-
- const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(1, 1, 1));
-
- // 设置灯光亮度
-
- light.intensity = 1;
-
- // 镜面反射 漫反射 环境光颜色调整
-
- light.diffuse = new BABYLON.Color3(1, 1, 1);
-
- light.specular = new BABYLON.Color3(1, 1, 1);
-
- // 渲染模型后调整相机角度、位置、观察对象的三维坐标
-
- scene.activeCamera.alpha = 0.0239;
-
- scene.activeCamera.beta = 1.51;
-
- scene.activeCamera.radius = 51.9;
-
- scene.activeCamera.setPosition(new BABYLON.Vector3(51.85, 4.32, 4.45));
-
- scene.activeCamera.setTarget(new BABYLON.Vector3(0.04, 1.4, 3.2));
-
-
-
- // 设置横向旋转角度上下限
-
- scene.activeCamera.upperBetaLimit = Math.PI * 0.5;
-
- scene.activeCamera.lowerBetaLimit = 0;
-
- // 设置镜头到目标位置距离半径的最大值
-
- scene.activeCamera.upperRadiusLimit = 102;
-
- // 设置鼠标滚轮灵敏度(数值越小灵敏度越高)
-
- scene.activeCamera.wheelPrecision = 10;
-
- // 控制鼠标平移相机镜头灵敏度(数值越小灵敏度越高|为0的时候取消平移操作)
-
- scene.activeCamera.panningSensibility = 200;
-
- // 存储当前相机状态
-
- scene.activeCamera.storeState();
-
- // 关闭自定义loading效果、展示标题、展示按钮
-
- setTimeout(() => {
-
- engine.hideLoadingUI();
-
- emit('showTitle', true);
-
- isRendering = true;
-
- });
-
- }, (progressEvent) => {
-
- // 设置模型加载进度百分比
-
- progress = (progressEvent.loaded / progressEvent.total).toFixed(0) * 100;
-
- });
-
- // 注册渲染循环 runRenderLoop
-
- engine.runRenderLoop(() => {
-
- scene.render();
-
- });
-
- // 在 DOM 更新后执行回调
-
- nextTick(() => {
-
- console.log('DOM 已更新');
-
- // 注册resize监听事件
-
- window.addEventListener('resize', engineResize);
-
- });
-
- })
-
-
-
- beforeUnmount(() => {
-
- // 离开页面销毁resize监听事件
-
- window.removeEventListener('resize', engineResize, false);
-
- })
-
- </script>
-
-
-
- <template>
-
- <div :class="isRendering ? 'containor bg' : 'containor'">
-
- <div id="loadingScreen" class="flex_column_center">
-
- <span class="loading"></span>
-
- <span class="progress">{{ progress }}%</span>
-
- <span class="text">3D模型加载中...</span>
-
- </div>
-
- <canvas id="canvas"></canvas>
-
- <div class="btn_list flex_middle" v-if="isRendering">
-
- <el-button type="warning" size="small" @click="reset"><i class="el-icon-refresh"></i> 重置</el-button>
-
- </div>
-
- </div>
-
- </template>
-
-
-
- <style lang="scss" scoped>
-
- /*scrollbar styles*/
-
- ::-webkit-scrollbar {
-
- width: 12px;
-
- height: 12px;
-
- // border-radius: 100px;
-
- }
-
- ::-webkit-scrollbar-thumb {
-
- // border-radius: 100px;
-
- background: var(--color-ref-kl-primary10);
-
- }
-
- ::-webkit-scrollbar-track-piece {
-
- // border-radius: 100px;
-
- background: transparent;
-
- }
-
- ::-webkit-scrollbar-corner {
-
- background: transparent;
-
- }
-
- /*scrollbar styles*/
-
- #app {
-
- height: 100%;
-
- color: #4b4b4b;
-
- font-size: 13px;
-
- font-family: 'Microsoft YaHei';
-
- -webkit-font-smoothing: antialiased;
-
- -moz-osx-font-smoothing: grayscale;
-
- }
-
- .flex {
-
- display: flex;
-
- }
-
- .flex_center {
-
- @extend .flex;
-
- align-items: center;
-
- }
-
- .flex_left {
-
- @extend .flex_center;
-
- justify-content: flex-start;
-
- }
-
- .flex_right {
-
- @extend .flex_center;
-
- justify-content: flex-end;
-
- }
-
- .flex_middle {
-
- @extend .flex_center;
-
- justify-content: center;
-
- }
-
- .flex_column {
-
- @extend .flex;
-
- flex-direction: column;
-
- justify-content: center;
-
- }
-
- .flex_column_center {
-
- @extend .flex_column;
-
- align-items: center;
-
- }
-
- .public_radius {
-
- border-radius: 8px;
-
- }
-
- .echarts {
-
- height: 100%;
-
- overflow: hidden;
-
- }
-
- .containor {
-
- position: relative;
-
- width: 100%;
-
- height: 100%;
-
- overflow: hidden;
-
- &.bg {
-
- background-color: #8ecbe3;
-
- }
-
- #loadingScreen {
-
- position: absolute;
-
- width: 100%;
-
- height: 100%;
-
- .loading {
-
- display: inline-block;
-
- position: relative;
-
- width: 100px;
-
- height: 100px;
-
- border: 8px solid #0934f7;
-
- border-radius: 50%;
-
- animation: rotate 1s linear infinite;
-
- &:after {
-
- position: absolute;
-
- left: 50%;
-
- top: 50%;
-
- width: 110px;
-
- height: 110px;
-
- content: '';
-
- transform: translate(-50%, -50%);
-
- border: 8px solid transparent;
-
- border-bottom-color: #00eaff;
-
- border-radius: 50%;
-
- }
-
- }
-
- .progress {
-
- margin-top: -60px;
-
- color: #6be031;
-
- font-size: 16px;
-
- font-weight: 700;
-
- }
-
- .text {
-
- margin-top: 60px;
-
- color: #f5a327;
-
- font-size: 14px;
-
- }
-
- }
-
- canvas {
-
- width: 100%;
-
- height: 100%;
-
- outline: none;
-
- cursor: pointer;
-
- }
-
- .btn_list {
-
- position: absolute;
-
- bottom: 0;
-
- width: 100%;
-
- height: 50px;
-
- z-index: 99;
-
- button {
-
- margin: 0 15px 0 0;
-
- &:last-child {
-
- margin: 0;
-
- }
-
- }
-
- }
-
- .video_main {
-
- position: absolute;
-
- top: 50%;
-
- left: 50%;
-
- transform: translate(-50%, -50%);
-
- width: 800px;
-
- height: 500px;
-
- z-index: 999;
-
- video {
-
- outline: none;
-
- }
-
- }
-
- }
-
- </style>
参见:
Babylon.js: Powerful, Beautiful, Simple, Open - Web-Based 3D At Its Best
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。