案例展示
cad图纸渲染
TIP
支持.dxf格式模型。
<template>
<div class="container">
<div id="TO"></div>
<div id="CAD_container"></div>
<div v-if="loading" class="loading-overlay">
<div class="loading-spinner"></div>
<span class="loading-text">{{ loadingText }}</span>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
let TO: any
let abortController: AbortController | null = null
let drawDXFPromise: Promise<any> | null = null
let isUnmounted = false
let objectUrl: string | null = null
const loading = ref(false)
const loadingText = ref('加载中...')
onMounted(() => {
initScene()
})
onUnmounted(() => {
// 组件卸载时中断请求
isUnmounted = true
if (abortController) {
abortController.abort()
abortController = null
}
// 清理对象 URL
if (objectUrl) {
URL.revokeObjectURL(objectUrl)
objectUrl = null
}
// 清理 ThingOrigin 实例
if (TO) {
try {
TO.dispose?.()
} catch (e) {
console.warn('清理 ThingOrigin 实例时出错:', e)
}
}
})
// 监听页面卸载事件(刷新、跳转等)
if (typeof window !== 'undefined') {
window.addEventListener('beforeunload', () => {
if (abortController) {
abortController.abort()
}
})
}
function initScene() {
// 初始化场景
//@ts-ignore
TO = new ThingOrigin('fileModel', document.getElementById('TO'), {
scene: {
//场景
background: {
type: 'color',
color: {
alpha: 1,
color: '#000000'
}
},
ground: {
active: false
}
},
helper: {
// 辅助工具
axes: {
active: false
},
grid: {
active: false
}
}
})
console.log('🚀 ~ initScene ~ TO:', TO)
// 创建 AbortController 用于中断请求
abortController = new AbortController()
// 开始加载,显示 loading
loading.value = true
loadingText.value = '加载 CAD 图纸...'
// 先加载 DXF 文件,这样可以中断请求
//@ts-ignore
const dxfUrl = `${import.meta.env.BASE_URL}models/cad/sixRobot.dxf`
// 使用 fetch 加载文件,支持中断
fetch(dxfUrl, {
signal: abortController.signal
})
.then((response) => {
if (isUnmounted) {
throw new Error('组件已卸载,中断加载')
}
if (!response.ok) {
throw new Error(`加载 DXF 文件失败: ${response.statusText}`)
}
return response.blob()
})
.then((blob) => {
if (isUnmounted) {
throw new Error('组件已卸载,中断加载')
}
// 更新 loading 文本
loadingText.value = '绘制图纸...'
// 创建对象 URL
objectUrl = URL.createObjectURL(blob)
// 绘制图纸
drawDXFPromise = TO.CAD.drawDXF(objectUrl, 'CAD_container')
return drawDXFPromise
})
.then(() => {
if (isUnmounted) {
// 如果已卸载,清理对象 URL
if (objectUrl) {
URL.revokeObjectURL(objectUrl)
objectUrl = null
}
return
}
console.log('DXF 文件加载并绘制完成')
})
.catch((error) => {
// 清理对象 URL
if (objectUrl) {
URL.revokeObjectURL(objectUrl)
objectUrl = null
}
if (error.name === 'AbortError' || error.message?.includes('中断')) {
console.log('DXF 文件加载已中断')
} else {
console.error('加载或绘制 DXF 文件时出错:', error)
}
})
.finally(() => {
// 隐藏 loading
loading.value = false
// 清理 AbortController
abortController = null
})
}
</script>
<style scoped>
.container {
position: relative;
}
#TO {
width: 100%;
height: 400px;
position: relative;
}
#CAD_container {
width: 646px;
height: 400px;
position: absolute;
top: 0;
left: 0;
/* opacity: 0.5; */
}
.loading-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
z-index: 10;
}
.loading-spinner {
width: 32px;
height: 32px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-top-color: #fff;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.loading-text {
margin-top: 12px;
color: #fff;
font-size: 14px;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>API 介绍
CAD.drawDXF
| 方法签名 | 返回值 | 描述 |
|---|---|---|
drawDXF(url: string, domId?: string) | 绘制dxf文件 |
参数说明:
| 参数名 | 说明 | 类型 | 必填 | 默认值 |
|---|---|---|---|---|
url | 文件地址 | string | 是 | - |
domId | 绘制容器的id | string | 否 | - |