index.vue 3.79 KB
<template>
  <div class="go-content-box">
    <!-- fix: 预览三维图像需加上preserveDrawingBuffer: true -->
    <div v-if="supportWebGL">
      <vue3dLoader
        ref="vue3dLoaderRef"
        :webGLRendererOptions="webGLRendererOptions"
        :backgroundColor="backgroundColor"
        :backgroundAlpha="backgroundAlpha"
        :height="h"
        :width="w"
        :filePath="dataset"
        :autoPlay="autoPlay"
        :enableDamping="enableDamping"
        :outputEncoding="outputEncoding"
        :clearScene="clearScene"
        :dampingFactor="dampingFactor"
        :labels="labels"
        @process="onProcess"
        @load="onLoad"
        @click="onClick"
      />
      <div v-show="show" class="process">
        <span> 拼命加载中... </span>
        <n-progress type="line" :color="themeColor" :percentage="process" :indicator-placement="'inside'" processing />
      </div>
    </div>
    <div v-else>您的浏览器不支持WebGL!</div>
  </div>
</template>
<script setup lang="ts">
import { PropType, toRefs, ref, onMounted, nextTick, computed } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { vue3dLoader } from 'vue-3d-loader'
import { useDesignStore } from '@/store/modules/designStore/designStore'

const designStore = useDesignStore()

const props = defineProps({
  chartConfig: {
    type: Object as PropType<CreateComponentType>,
    required: true
  }
})

// 颜色
const themeColor = computed(() => {
  return designStore.getAppTheme
})

const vue3dLoaderRef = ref(null)

//threejs配置
const webGLRendererOptions = {
  alpha: true, // 透明
  antialias: true, // 抗锯齿
  preserveDrawingBuffer: true //缩略图生效需开启
}

//标注示例可以多个支持图片和文字
const labels = ref()
labels.value = [
  {
    text: 'co2浓度:44',
    position: { x: 0, y: 18, z: 0 },
    scale: { x: 11.5, y: 10.8, z: 30.5 },
    textStyle: {
      fontFamily: 'Arial',
      fontSize: 12,
      fontWeight: 600,
      lineHeight: 1,
      color: '#ffffff',
      borderWidth: 8,
      borderRadius: 0,
      borderColor: '#000000',
      backgroundColor: 'rgba(0,0,0,1)'
    },
    sid: 3 // 自定义标识,可有可无
  },
  {
    text: '氧气浓度:100',
    position: { x: 10, y: 18, z: 0 },
    scale: { x: 11.5, y: 10.8, z: 30.5 },
    textStyle: {
      fontFamily: 'Arial',
      fontSize: 12,
      fontWeight: 600,
      lineHeight: 1,
      color: '#ffffff',
      borderWidth: 8,
      borderRadius: 0,
      borderColor: '#000000',
      backgroundColor: 'rgba(0,0,0,1)'
    },
    sid: 4 // 自定义标识,可有可无
  }
]

//三维模型加载
const show = ref(true)

const onLoad = async () => {
  //加载完成
  await nextTick()
  show.value = false
}

//三维模型进度条
const process = ref(0)

const onProcess = (event: any) => {
  process.value= Math.floor((event.loaded / event.total) * 100)
}

const onClick = (event: any) => {
  console.log(event)
}

//判断浏览器是否支持WebGL
const supportWebGL = ref(true)
const detectWebGLContext = () => {
  let canvas = document.createElement('canvas')
  let gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
  if (gl && gl instanceof WebGLRenderingContext) {
    supportWebGL.value = true
  } else {
    supportWebGL.value = false
  }
}

onMounted(() => {
  detectWebGLContext()
  console.log(`实例`, vue3dLoaderRef.value)
})

const { w, h } = toRefs(props.chartConfig.attr)

const {
  backgroundColor,
  backgroundAlpha,
  autoPlay,
  enableDamping,
  dataset,
  outputEncoding,
  clearScene,
  dampingFactor
} = toRefs(props.chartConfig.option) as any
</script>

<style lang="scss" scoped>
.go-content-box {
  height: 100%;
  position: relative;
  .process {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 50%;
    transform: translate(-50%, -50%);
  }
}
</style>