refactor: 重构canvas
This commit is contained in:
@@ -1,316 +1,5 @@
|
||||
// LabCanvas组件管理系统 - 统一导出
|
||||
// 基于VueUse重构的Konva组件管理系统
|
||||
import LabCanvas from './LabCanvas.vue';
|
||||
import LabComponentsDrawer from './LabComponentsDrawer.vue';
|
||||
import { useProvideLabCanvasStore, useLabCanvasStore } from './composable/LabCanvasManager';
|
||||
|
||||
// 类型定义
|
||||
export type {
|
||||
KonvaComponent,
|
||||
KonvaComponentBase,
|
||||
ComponentTemplate,
|
||||
ComponentProps,
|
||||
ComponentGroup,
|
||||
SelectionState,
|
||||
HistoryRecord,
|
||||
ComponentEvents,
|
||||
CanvasConfig,
|
||||
ProjectData
|
||||
} from './types/KonvaComponent'
|
||||
|
||||
// 核心管理器
|
||||
export { useKonvaComponentManager } from './composables/useKonvaComponentManager'
|
||||
export type { UseKonvaComponentManagerOptions } from './composables/useKonvaComponentManager'
|
||||
|
||||
// 模板管理器
|
||||
export { useKonvaTemplateManager } from './composables/useKonvaTemplateManager'
|
||||
export type {
|
||||
TemplateData,
|
||||
UseKonvaTemplateManagerOptions
|
||||
} from './composables/useKonvaTemplateManager'
|
||||
|
||||
// 渲染器
|
||||
export { useKonvaRenderer } from './composables/useKonvaRenderer'
|
||||
export type { UseKonvaRendererOptions } from './composables/useKonvaRenderer'
|
||||
|
||||
// 组件
|
||||
export { default as LabCanvasNew } from './LabCanvasNew.vue'
|
||||
export { default as LabComponentsDrawerNew } from './LabComponentsDrawerNew.vue'
|
||||
export { default as ExampleUsage } from '../../views/TestView.vue'
|
||||
|
||||
// 导入需要的类型
|
||||
import type { ProjectData, ComponentTemplate, CanvasConfig } from './types/KonvaComponent'
|
||||
|
||||
// 工具函数
|
||||
export const KonvaLabUtils = {
|
||||
/**
|
||||
* 生成唯一ID
|
||||
*/
|
||||
generateId: (): string => {
|
||||
return `component-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算矩形的边界框(考虑旋转和缩放)
|
||||
*/
|
||||
calculateBoundingBox: (
|
||||
width: number,
|
||||
height: number,
|
||||
rotation: number = 0,
|
||||
scaleX: number = 1,
|
||||
scaleY: number = 1,
|
||||
padding: number = 0
|
||||
) => {
|
||||
const scaledWidth = width * scaleX
|
||||
const scaledHeight = height * scaleY
|
||||
|
||||
const radians = (rotation * Math.PI) / 180
|
||||
const cos = Math.cos(radians)
|
||||
const sin = Math.sin(radians)
|
||||
|
||||
const corners = [
|
||||
{ x: 0, y: 0 },
|
||||
{ x: scaledWidth, y: 0 },
|
||||
{ x: scaledWidth, y: scaledHeight },
|
||||
{ x: 0, y: scaledHeight },
|
||||
].map((point) => ({
|
||||
x: point.x * cos - point.y * sin,
|
||||
y: point.x * sin + point.y * cos,
|
||||
}))
|
||||
|
||||
const minX = Math.min(...corners.map((p) => p.x))
|
||||
const maxX = Math.max(...corners.map((p) => p.x))
|
||||
const minY = Math.min(...corners.map((p) => p.y))
|
||||
const maxY = Math.max(...corners.map((p) => p.y))
|
||||
|
||||
return {
|
||||
x: minX - padding,
|
||||
y: minY - padding,
|
||||
width: maxX - minX + padding * 2,
|
||||
height: maxY - minY + padding * 2,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查两个矩形是否相交
|
||||
*/
|
||||
rectsIntersect: (
|
||||
rect1: { x: number; y: number; width: number; height: number },
|
||||
rect2: { x: number; y: number; width: number; height: number }
|
||||
): boolean => {
|
||||
return (
|
||||
rect1.x < rect2.x + rect2.width &&
|
||||
rect1.x + rect1.width > rect2.x &&
|
||||
rect1.y < rect2.y + rect2.height &&
|
||||
rect1.y + rect1.height > rect2.y
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算两点之间的距离
|
||||
*/
|
||||
distance: (
|
||||
point1: { x: number; y: number },
|
||||
point2: { x: number; y: number }
|
||||
): number => {
|
||||
const dx = point2.x - point1.x
|
||||
const dy = point2.y - point1.y
|
||||
return Math.sqrt(dx * dx + dy * dy)
|
||||
},
|
||||
|
||||
/**
|
||||
* 格式化项目数据用于导出
|
||||
*/
|
||||
formatProjectForExport: (projectData: ProjectData) => {
|
||||
return {
|
||||
...projectData,
|
||||
exportedAt: new Date().toISOString(),
|
||||
components: projectData.components.map((comp: any) => ({
|
||||
...comp,
|
||||
// 移除运行时状态
|
||||
isSelected: false,
|
||||
isHovered: false,
|
||||
konvaNodeId: undefined
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 验证项目数据格式
|
||||
*/
|
||||
validateProjectData: (data: any): { isValid: boolean; errors: string[] } => {
|
||||
const errors: string[] = []
|
||||
|
||||
if (!data.version) errors.push('缺少版本信息')
|
||||
if (!data.canvas) errors.push('缺少画布配置')
|
||||
if (!Array.isArray(data.components)) errors.push('组件数据格式错误')
|
||||
|
||||
// 验证组件
|
||||
if (Array.isArray(data.components)) {
|
||||
data.components.forEach((comp: any, index: number) => {
|
||||
if (!comp.id) errors.push(`组件 ${index} 缺少ID`)
|
||||
if (!comp.type) errors.push(`组件 ${index} 缺少类型`)
|
||||
if (typeof comp.x !== 'number') errors.push(`组件 ${index} X坐标无效`)
|
||||
if (typeof comp.y !== 'number') errors.push(`组件 ${index} Y坐标无效`)
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: errors.length === 0,
|
||||
errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 预定义的组件模板
|
||||
export const PredefinedTemplates: ComponentTemplate[] = [
|
||||
{
|
||||
type: "MechanicalButton",
|
||||
name: "机械按钮",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
size: "medium",
|
||||
color: "blue",
|
||||
pressed: false
|
||||
},
|
||||
previewSize: 0.4
|
||||
},
|
||||
{
|
||||
type: "Switch",
|
||||
name: "开关",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
state: false,
|
||||
style: "toggle"
|
||||
},
|
||||
previewSize: 0.35
|
||||
},
|
||||
{
|
||||
type: "Pin",
|
||||
name: "引脚",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
type: "input",
|
||||
label: "Pin"
|
||||
},
|
||||
previewSize: 0.8
|
||||
},
|
||||
{
|
||||
type: "SMT_LED",
|
||||
name: "贴片LED",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
color: "red",
|
||||
state: false,
|
||||
brightness: 1
|
||||
},
|
||||
previewSize: 0.7
|
||||
},
|
||||
{
|
||||
type: "SevenSegmentDisplay",
|
||||
name: "数码管",
|
||||
category: "advanced",
|
||||
defaultProps: {
|
||||
digits: 4,
|
||||
value: "0000",
|
||||
color: "red"
|
||||
},
|
||||
previewSize: 0.4
|
||||
},
|
||||
{
|
||||
type: "HDMI",
|
||||
name: "HDMI接口",
|
||||
category: "advanced",
|
||||
defaultProps: {
|
||||
version: "2.0",
|
||||
connected: false
|
||||
},
|
||||
previewSize: 0.5
|
||||
},
|
||||
{
|
||||
type: "DDR",
|
||||
name: "DDR内存",
|
||||
category: "advanced",
|
||||
defaultProps: {
|
||||
type: "DDR4",
|
||||
capacity: "8GB",
|
||||
speed: "3200MHz"
|
||||
},
|
||||
previewSize: 0.5
|
||||
},
|
||||
{
|
||||
type: "ETH",
|
||||
name: "以太网接口",
|
||||
category: "advanced",
|
||||
defaultProps: {
|
||||
speed: "1000Mbps",
|
||||
connected: false
|
||||
},
|
||||
previewSize: 0.5
|
||||
},
|
||||
{
|
||||
type: "SD",
|
||||
name: "SD卡插槽",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
cardInserted: false,
|
||||
type: "microSD"
|
||||
},
|
||||
previewSize: 0.6
|
||||
},
|
||||
{
|
||||
type: "SFP",
|
||||
name: "SFP光纤模块",
|
||||
category: "advanced",
|
||||
defaultProps: {
|
||||
type: "SFP+",
|
||||
speed: "10Gbps",
|
||||
connected: false
|
||||
},
|
||||
previewSize: 0.4
|
||||
},
|
||||
{
|
||||
type: "SMA",
|
||||
name: "SMA连接器",
|
||||
category: "basic",
|
||||
defaultProps: {
|
||||
type: "female",
|
||||
impedance: "50ohm"
|
||||
},
|
||||
previewSize: 0.7
|
||||
},
|
||||
{
|
||||
type: "MotherBoard",
|
||||
name: "主板",
|
||||
category: "template",
|
||||
defaultProps: {
|
||||
model: "Generic",
|
||||
size: "ATX"
|
||||
},
|
||||
previewSize: 0.13
|
||||
},
|
||||
{
|
||||
type: "DDS",
|
||||
name: "信号发生器",
|
||||
category: "virtual",
|
||||
defaultProps: {
|
||||
frequency: 1000,
|
||||
amplitude: 1.0,
|
||||
waveform: "sine",
|
||||
enabled: false
|
||||
},
|
||||
previewSize: 0.3
|
||||
}
|
||||
]
|
||||
|
||||
// 默认配置
|
||||
export const DefaultCanvasConfig: CanvasConfig = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
scale: 1,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
gridSize: 20,
|
||||
showGrid: true,
|
||||
snapToGrid: false
|
||||
}
|
||||
|
||||
// 版本信息
|
||||
export const VERSION = '1.0.0'
|
||||
export {LabCanvas, LabComponentsDrawer};
|
||||
Reference in New Issue
Block a user