feat: 导入导出组件树预览等功能完成
parent
e02f7349ff
commit
8209dae48e
@ -1,9 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg width="24" height="24" viewBox="0 0 48 48" fill="none"
|
<svg width="24" height="24" viewBox="0 0 48 48" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M9 10V44H39V10H9Z" fill="none" stroke="#333" stroke-width="4" stroke-linejoin="round"/>
|
<g stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M20 20V33" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M9 10V44H39V10H9Z" fill="none" />
|
||||||
<path d="M28 20V33" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M20 20V33" />
|
||||||
<path d="M4 10H44" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M28 20V33" />
|
||||||
<path d="M16 10L19.289 4H28.7771L32 10H16Z" fill="none" stroke="#333" stroke-width="4" stroke-linejoin="round"/>
|
<path d="M4 10H44" />
|
||||||
|
<path d="M16 10L19.289 4H28.7771L32 10H16Z" fill="none" />
|
||||||
|
</g>
|
||||||
|
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 451 B |
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.9998 8L6 14L12.9998 21" stroke="#333" stroke-width="4" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
<path
|
||||||
|
d="M6 14H28.9938C35.8768 14 41.7221 19.6204 41.9904 26.5C42.2739 33.7696 36.2671 40 28.9938 40H11.9984"
|
||||||
|
stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 482 B |
@ -0,0 +1,242 @@
|
|||||||
|
<!-- eslint-disable prettier/prettier -->
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="canvas"
|
||||||
|
@mousedown="onCanvasMouseDown"
|
||||||
|
@mousemove="onCanvasMouseMove"
|
||||||
|
@mouseup="onCanvasMouseUp"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
:style="{ backgroundColor: preview_data.config.background_color }"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
:transform="`translate(${
|
||||||
|
preview_data.config.position_center.x + preview_data.layout_center.x
|
||||||
|
},${
|
||||||
|
preview_data.config.position_center.y + preview_data.layout_center.y
|
||||||
|
})rotate(${0})scale(${preview_data.config.scale})`"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
v-for="item in preview_data.done_json"
|
||||||
|
:key="item.id"
|
||||||
|
:transform="`translate(${item.x},${item.y})rotate(0)scale(1)`"
|
||||||
|
v-show="item.display"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
:transform="`translate(${item.actual_bound.x + item.actual_bound.width / 2},${
|
||||||
|
item.actual_bound.y + item.actual_bound.height / 2
|
||||||
|
})rotate(${item.rotate}) scale(1) translate(${-(
|
||||||
|
item.actual_bound.x +
|
||||||
|
item.actual_bound.width / 2
|
||||||
|
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
|
||||||
|
>
|
||||||
|
<connection-line
|
||||||
|
v-if="item.type === EDoneJsonType.ConnectionLine"
|
||||||
|
:item-info="item"
|
||||||
|
></connection-line>
|
||||||
|
<use
|
||||||
|
v-else-if="item.type === EDoneJsonType.File"
|
||||||
|
:xlink:href="`#svg-${item.name}`"
|
||||||
|
v-bind="prosToVBind(item)"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
:id="item.id"
|
||||||
|
:transform="`translate(${item.actual_bound.x + item.actual_bound.width / 2},${
|
||||||
|
item.actual_bound.y + item.actual_bound.height / 2
|
||||||
|
}) scale(${item.scale_x},${item.scale_y}) translate(${-(
|
||||||
|
item.actual_bound.x +
|
||||||
|
item.actual_bound.width / 2
|
||||||
|
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
|
||||||
|
></use>
|
||||||
|
<component
|
||||||
|
v-else-if="item.type === EDoneJsonType.CustomSvg"
|
||||||
|
:is="item.tag"
|
||||||
|
v-bind="prosToVBind(item)"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
:id="item.id"
|
||||||
|
:transform="`translate(${item.actual_bound.x + item.actual_bound.width / 2},${
|
||||||
|
item.actual_bound.y + item.actual_bound.height / 2
|
||||||
|
}) scale(${item.scale_x},${item.scale_y}) translate(${-(
|
||||||
|
item.actual_bound.x +
|
||||||
|
item.actual_bound.width / 2
|
||||||
|
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
|
||||||
|
></component>
|
||||||
|
<foreignObject
|
||||||
|
v-else-if="item.type === EDoneJsonType.Vue"
|
||||||
|
v-bind="getActualBoundScale(item.actual_bound, item.scale_x, item.scale_y)"
|
||||||
|
:id="`foreign-object${item.id}`"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="item.tag"
|
||||||
|
v-bind="prosToVBind(item)"
|
||||||
|
:id="item.id"
|
||||||
|
:transform="`translate(${item.actual_bound.x + item.actual_bound.width / 2},${
|
||||||
|
item.actual_bound.y + item.actual_bound.height / 2
|
||||||
|
}) scale(${item.scale_x},${item.scale_y}) translate(${-(
|
||||||
|
item.actual_bound.x +
|
||||||
|
item.actual_bound.width / 2
|
||||||
|
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
|
||||||
|
>{{ item.tag_slot }}</component
|
||||||
|
>
|
||||||
|
</foreignObject>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getCurrentInstance, PropType, reactive } from 'vue';
|
||||||
|
import { useGlobalStore } from '@/store/global';
|
||||||
|
import { EGlobalStoreIntention, EMouseInfoState } from '@/store/global/types';
|
||||||
|
import { prosToVBind } from '@/utils';
|
||||||
|
|
||||||
|
import { EDoneJsonType } from '@/config-center/types';
|
||||||
|
import ConnectionLine from '@/components/webtopo-svgedit/components/connection-line/index.vue';
|
||||||
|
|
||||||
|
import { ComponentImport } from '@/config-center';
|
||||||
|
import { IDataModel } from '../webtopo-svgedit/types';
|
||||||
|
import 'element-plus/dist/index.css';
|
||||||
|
// import HandlePanel from '../handle-panel/index.vue';
|
||||||
|
//注册所有组件
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
Object.keys(ComponentImport).forEach((key) => {
|
||||||
|
if (!Object.keys(instance?.appContext?.components as any).includes(key)) {
|
||||||
|
instance?.appContext.app.component(key, ComponentImport[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const props = defineProps({
|
||||||
|
dataModel: {
|
||||||
|
type: [Object, null] as PropType<IDataModel | null>,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
canvasDrag: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const preview_data = reactive(
|
||||||
|
props.dataModel ?? {
|
||||||
|
layout_center: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
background_color: '#fff',
|
||||||
|
scale: 1,
|
||||||
|
position_center: {
|
||||||
|
x: -295,
|
||||||
|
y: -95
|
||||||
|
},
|
||||||
|
svg_position_center: {
|
||||||
|
x: 50,
|
||||||
|
y: 50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
done_json: []
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const globalStore = useGlobalStore();
|
||||||
|
const onCanvasMouseMove = (e: MouseEvent) => {
|
||||||
|
//如果鼠标不是按下状态 连线除外
|
||||||
|
if (
|
||||||
|
globalStore.mouse_info.state != EMouseInfoState.Down &&
|
||||||
|
globalStore.intention !== EGlobalStoreIntention.Connection
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!props.canvasDrag) {
|
||||||
|
console.log(props.canvasDrag);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { clientX, clientY } = e;
|
||||||
|
globalStore.mouse_info.new_position_x =
|
||||||
|
globalStore.mouse_info.now_position_x + clientX - globalStore.mouse_info.position_x;
|
||||||
|
globalStore.mouse_info.new_position_y =
|
||||||
|
globalStore.mouse_info.now_position_y + clientY - globalStore.mouse_info.position_y;
|
||||||
|
if (globalStore.intention == EGlobalStoreIntention.MoveCanvas) {
|
||||||
|
//移动画布
|
||||||
|
preview_data.layout_center.x = globalStore.mouse_info.new_position_x;
|
||||||
|
preview_data.layout_center.y = globalStore.mouse_info.new_position_y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onCanvasMouseUp = () => {
|
||||||
|
//如果鼠标不是按下状态
|
||||||
|
if (globalStore.mouse_info.state != EMouseInfoState.Down) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (globalStore.intention != EGlobalStoreIntention.Select) {
|
||||||
|
globalStore.intention = EGlobalStoreIntention.None;
|
||||||
|
}
|
||||||
|
globalStore.setMouseInfo({
|
||||||
|
state: EMouseInfoState.Up,
|
||||||
|
position_x: 0,
|
||||||
|
position_y: 0,
|
||||||
|
now_position_x: 0,
|
||||||
|
now_position_y: 0,
|
||||||
|
new_position_x: 0,
|
||||||
|
new_position_y: 0
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const onCanvasMouseDown = (e: MouseEvent) => {
|
||||||
|
console.log('onCanvasMouseDown', e);
|
||||||
|
const { clientX, clientY } = e;
|
||||||
|
//点击画布 未选中组件 拖动画布
|
||||||
|
globalStore.intention = EGlobalStoreIntention.MoveCanvas;
|
||||||
|
globalStore.setMouseInfo({
|
||||||
|
state: EMouseInfoState.Down,
|
||||||
|
position_x: clientX,
|
||||||
|
position_y: clientY,
|
||||||
|
now_position_x: preview_data.layout_center.x,
|
||||||
|
now_position_y: preview_data.layout_center.y,
|
||||||
|
new_position_x: preview_data.layout_center.x,
|
||||||
|
new_position_y: preview_data.layout_center.y
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const getActualBoundScale = (
|
||||||
|
actual_bound: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
},
|
||||||
|
scale_x: number,
|
||||||
|
scale_y: number
|
||||||
|
) => {
|
||||||
|
return {
|
||||||
|
x: actual_bound.x - (actual_bound.width / 2) * scale_x + actual_bound.width / 2,
|
||||||
|
y: actual_bound.y - (actual_bound.height / 2) * scale_y + actual_bound.height / 2,
|
||||||
|
width: actual_bound.width * scale_x,
|
||||||
|
height: actual_bound.height * scale_y
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-item-none {
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
outline: 1px solid #0cf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-item-move {
|
||||||
|
cursor: move;
|
||||||
|
outline: 1px dashed rgb(23, 222, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-item-select {
|
||||||
|
cursor: move;
|
||||||
|
outline: 1px solid rgb(23, 222, 30);
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<el-tree
|
||||||
|
:data="data"
|
||||||
|
:props="defaultProps"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
:default-expand-all="true"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:highlight-current="true"
|
||||||
|
node-key="id"
|
||||||
|
:current-node-key="current_node_key"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useGlobalStore } from '@/store/global';
|
||||||
|
import { EGlobalStoreIntention, IDoneJson } from '@/store/global/types';
|
||||||
|
import { ElTree } from 'element-plus';
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
|
const global_store = useGlobalStore();
|
||||||
|
const data = ref<IDoneJson[]>([]);
|
||||||
|
const current_node_key = ref(global_store.handle_svg_info?.info.id);
|
||||||
|
const handleNodeClick = (data: IDoneJson) => {
|
||||||
|
global_store.intention = EGlobalStoreIntention.Select;
|
||||||
|
global_store.setHandleSvgInfo(data);
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
data.value = global_store.done_json;
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
|
label: 'title'
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,36 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { VAceEditor } from 'vue3-ace-editor';
|
||||||
|
import '@/config-center/ace-edit';
|
||||||
|
import { useGlobalStore } from '@/store/global';
|
||||||
|
import { useSvgEditLayoutStore } from '@/store/svgedit-layout';
|
||||||
|
import { useConfigStore } from '@/store/config';
|
||||||
|
import { IDataModel } from '../../types';
|
||||||
|
const content = ref('');
|
||||||
|
const globalStore = useGlobalStore();
|
||||||
|
const svgEditLayoutStore = useSvgEditLayoutStore();
|
||||||
|
const configStore = useConfigStore();
|
||||||
|
onMounted(() => {
|
||||||
|
const export_json: IDataModel = {
|
||||||
|
layout_center: svgEditLayoutStore.center_offset,
|
||||||
|
config: configStore.svg,
|
||||||
|
done_json: globalStore.done_json
|
||||||
|
};
|
||||||
|
content.value = JSON.stringify(export_json, null, 2);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-ace-editor
|
||||||
|
v-model:value="content"
|
||||||
|
lang="json"
|
||||||
|
theme="monokai"
|
||||||
|
style="height: 400px"
|
||||||
|
:options="{
|
||||||
|
useWorker: true,
|
||||||
|
enableBasicAutocompletion: true,
|
||||||
|
enableSnippets: true,
|
||||||
|
enableLiveAutocompletion: true
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</template>
|
@ -0,0 +1,50 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { VAceEditor } from 'vue3-ace-editor';
|
||||||
|
import '@/config-center/ace-edit';
|
||||||
|
import { useGlobalStore } from '@/store/global';
|
||||||
|
import { useSvgEditLayoutStore } from '@/store/svgedit-layout';
|
||||||
|
import { useConfigStore } from '@/store/config';
|
||||||
|
import { IDataModel } from '../../types';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
const content = ref<string>('');
|
||||||
|
const globalStore = useGlobalStore();
|
||||||
|
const svgEditLayoutStore = useSvgEditLayoutStore();
|
||||||
|
const configStore = useConfigStore();
|
||||||
|
const onImportJson = () => {
|
||||||
|
try {
|
||||||
|
const json: IDataModel = JSON.parse(content.value);
|
||||||
|
console.log(json, json.layout_center, configStore, 15);
|
||||||
|
if (!json.config || !json.layout_center || !json.done_json) {
|
||||||
|
ElMessage.error('请导入正确的数据模型!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
configStore.svg = json.config;
|
||||||
|
svgEditLayoutStore.center_offset = json.layout_center;
|
||||||
|
globalStore.setDoneJson(json.done_json);
|
||||||
|
ElMessage.success('导入成功');
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('请导入正确的数据模型!');
|
||||||
|
console.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
defineExpose({
|
||||||
|
onImportJson
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-ace-editor
|
||||||
|
v-model:value="content"
|
||||||
|
lang="json"
|
||||||
|
theme="monokai"
|
||||||
|
style="height: 400px"
|
||||||
|
:options="{
|
||||||
|
useWorker: true,
|
||||||
|
enableBasicAutocompletion: true,
|
||||||
|
enableSnippets: true,
|
||||||
|
enableLiveAutocompletion: true
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</template>
|
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" plain round @click="dialogVisible = true">点击编辑</el-button>
|
||||||
|
<el-dialog v-model="dialogVisible" title="配置编辑" width="60%">
|
||||||
|
<v-ace-editor
|
||||||
|
v-model:value="content"
|
||||||
|
lang="json"
|
||||||
|
theme="monokai"
|
||||||
|
style="height: 400px"
|
||||||
|
:options="{
|
||||||
|
useWorker: true,
|
||||||
|
enableBasicAutocompletion: true,
|
||||||
|
enableSnippets: true,
|
||||||
|
enableLiveAutocompletion: true
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="onYesBtnClick">确定</el-button>
|
||||||
|
<el-button type="primary" @click="dialogVisible = false">关闭</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { VAceEditor } from 'vue3-ace-editor';
|
||||||
|
import '@/config-center/ace-edit';
|
||||||
|
import { ElButton, ElDialog } from 'element-plus';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
const props = defineProps({
|
||||||
|
contentObj: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const emits = defineEmits(['updateAttrItemVal']);
|
||||||
|
const content = ref(JSON.stringify(props.contentObj, null, 2));
|
||||||
|
const onYesBtnClick = () => {
|
||||||
|
emits('updateAttrItemVal', JSON.parse(content.value));
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,19 @@
|
|||||||
|
import { IPositionCenterSvg } from '@/store/config/types';
|
||||||
|
import { IDoneJson } from '@/store/global/types';
|
||||||
|
|
||||||
|
export type IVisibleConf = {
|
||||||
|
[key in EVisibleConfKey]: boolean;
|
||||||
|
};
|
||||||
|
export enum EVisibleConfKey {
|
||||||
|
ImportJson = 'ImportJson',
|
||||||
|
ExportJson = 'ExportJson',
|
||||||
|
ComponentTree = 'ComponentTree'
|
||||||
|
}
|
||||||
|
export interface IDataModel {
|
||||||
|
layout_center: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
};
|
||||||
|
config: IPositionCenterSvg;
|
||||||
|
done_json: IDoneJson[];
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import ace from 'ace-builds';
|
||||||
|
|
||||||
|
import themeMonokaiUrl from 'ace-builds/src-noconflict/theme-monokai?url';
|
||||||
|
ace.config.setModuleUrl('ace/theme/monokai', themeMonokaiUrl);
|
||||||
|
|
||||||
|
import workerBaseUrl from 'ace-builds/src-noconflict/worker-base?url';
|
||||||
|
ace.config.setModuleUrl('ace/mode/base', workerBaseUrl);
|
||||||
|
|
||||||
|
import modeJsonUrl from 'ace-builds/src-noconflict/mode-json?url';
|
||||||
|
ace.config.setModuleUrl('ace/mode/json', modeJsonUrl);
|
||||||
|
import workerJsonUrl from 'ace-builds/src-noconflict/worker-json?url';
|
||||||
|
ace.config.setModuleUrl('ace/mode/json_worker', workerJsonUrl);
|
||||||
|
import snippetsJsonUrl from 'ace-builds/src-noconflict/snippets/json?url';
|
||||||
|
ace.config.setModuleUrl('ace/snippets/json', snippetsJsonUrl);
|
||||||
|
|
||||||
|
import modeJavascriptUrl from 'ace-builds/src-noconflict/mode-javascript?url';
|
||||||
|
ace.config.setModuleUrl('ace/mode/javascript', modeJavascriptUrl);
|
||||||
|
import workerJavascriptUrl from 'ace-builds/src-noconflict/worker-javascript?url';
|
||||||
|
ace.config.setModuleUrl('ace/mode/javascript_worker', workerJavascriptUrl);
|
||||||
|
import snippetsJavascriptUrl from 'ace-builds/src-noconflict/snippets/javascript?url';
|
||||||
|
ace.config.setModuleUrl('ace/snippets/javascript', snippetsJavascriptUrl);
|
||||||
|
|
||||||
|
import 'ace-builds/src-noconflict/ext-language_tools';
|
||||||
|
ace.require('ace/ext/language_tools');
|
@ -1,14 +1,15 @@
|
|||||||
export interface IPositionCenter {
|
export interface IPositionCenter {
|
||||||
svg: {
|
svg: IPositionCenterSvg;
|
||||||
background_color: string;
|
}
|
||||||
scale: number;
|
export interface IPositionCenterSvg {
|
||||||
position_center: {
|
background_color: string;
|
||||||
x: number;
|
scale: number;
|
||||||
y: number;
|
position_center: {
|
||||||
};
|
x: number;
|
||||||
svg_position_center: {
|
y: number;
|
||||||
x: number;
|
};
|
||||||
y: number;
|
svg_position_center: {
|
||||||
};
|
x: number;
|
||||||
|
y: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<webtopo-svgedit></webtopo-svgedit>
|
<webtopo-svgedit @on-return="onReturn"></webtopo-svgedit>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import WebtopoSvgedit from '../../components/webtopo-svgedit/index.vue';
|
import WebtopoSvgedit from '../../components/webtopo-svgedit/index.vue';
|
||||||
|
const onReturn = () => {
|
||||||
|
console.log('点击了返回按钮');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>预览页</div>
|
<webtopo-svg-preview :data-model="data_model" :canvas-drag="true"></webtopo-svg-preview>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import WebtopoSvgPreview from '@/components/webtopo-svg-preview/index.vue';
|
||||||
|
import { IDataModel } from '@/components/webtopo-svgedit/types';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
const route = useRoute();
|
||||||
|
const data_model = ref<IDataModel | null>(null);
|
||||||
|
|
||||||
|
if (route.params.data_model) {
|
||||||
|
data_model.value = JSON.parse(route.params.data_model as string);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
Loading…
Reference in New Issue