Skip to content

案例展示

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绘制容器的idstring-