feat: 新增连线雏形

Re-1.0
咬轮猫 3 years ago
parent 2ec8f34c9c
commit edfcc4ed23

@ -2,7 +2,7 @@
"name": "vue-webtopo-svgeditor",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"dev": "vite --port 3001",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"lint:eslint": "eslint --fix --ext .js,.ts,.vue,.tsx ./src",

@ -8,6 +8,7 @@
@mousedown="onCanvasMouseDown"
@mousemove="onCanvasMouseMove"
@mouseup="onCanvasMouseUp"
@contextmenu="onCanvasContextMenuEvent"
>
<svg
xmlns="http://www.w3.org/2000/svg"
@ -34,8 +35,12 @@
item.actual_bound.x +
item.actual_bound.width / 2
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
@mousedown="onSvgMouseDown(item, index, $event)"
@mouseenter="onSvgMouseEnter(item, index, $event)"
@mouseleave="onSvgMouseLeave(item, index, $event)"
>
<use
v-if="item.type === EDoneJsonType.File"
:xlink:href="`#svg-${item.name}`"
fill="#ff0000"
width="100"
@ -48,6 +53,25 @@
item.actual_bound.width / 2
)},${-(item.actual_bound.y + item.actual_bound.height / 2)})`"
></use>
<line
v-else-if="item.type === EDoneJsonType.StraightLine"
:id="item.id"
:x1="item.props.start_x.val"
:y1="item.props.start_y.val"
:x2="item.props.end_x.val"
:y2="item.props.end_y.val"
fill="#FF0000"
stroke="#FF0000"
stroke-width="2"
></line>
<path
v-else-if="item.type === EDoneJsonType.ConnectionLine"
:id="item.id"
:d="positionArrarToPath(item.props.point_position.val)"
fill-opacity="0"
stroke="#FF0000"
stroke-width="2"
></path>
<rect
:id="`rect${item.id}`"
fill="black"
@ -77,17 +101,24 @@
? 'svg-item-select'
: ''
}`"
@mousedown="onSvgMouseDown(item, index, $event)"
></rect>
<handle-panel
v-if="
globalStore.handle_svg_info?.info.id == item.id &&
(globalStore.intention === EGlobalStoreIntention.Select ||
globalStore.intention === EGlobalStoreIntention.Zoom ||
globalStore.intention === EGlobalStoreIntention.Rotate)
globalStore.handle_svg_info?.info.id === item.id &&
visiable_info.handle_panel &&
item.config.can_zoom
"
:item-info="item"
></handle-panel>
<connection-panel
v-if="
(globalStore.handle_svg_info?.info.id !== item.id ||
globalStore.intention == EGlobalStoreIntention.None) &&
visiable_info.connection_panel &&
item.config.have_anchor
"
:item-info="item"
></connection-panel>
</g>
</g>
</g>
@ -95,17 +126,23 @@
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { useConfigStore } from '../../../../store/config';
import { useGlobalStore } from '../../../../store/global';
import { computed, reactive } from 'vue';
import { useConfigStore } from '@/store/config';
import { useGlobalStore } from '@/store/global';
import {
EGlobalStoreIntention,
EMouseInfoState,
EScaleInfoType,
IDoneJson
} from '../../../../store/global/types';
import { useSvgEditLayoutStore } from '../../../../store/svgedit-layout';
import { getCenterPoint, randomString } from '../../../../utils';
} from '@/store/global/types';
import { useSvgEditLayoutStore } from '@/store/svgedit-layout';
import {
getCenterPoint,
randomString,
positionArrarToPath,
getSvgNowPosition,
setSvgActualInfo
} from '@/utils';
import {
calculateBottom,
calculateLeft,
@ -115,8 +152,10 @@
calculateRightBottom,
calculateRightTop,
calculateTop
} from '../../../../utils/scale-core';
import HandlePanel from '../handle-panel/index.vue';
} from '@/utils/scale-core';
import HandlePanel from '@/components/webtopo-svgedit/components/handle-panel/index.vue';
import ConnectionPanel from '@/components/webtopo-svgedit/components/connection-panel/index.vue';
import { EDoneJsonType } from '@/config-center/types';
// import HandlePanel from '../handle-panel/index.vue';
const globalStore = useGlobalStore();
const configStore = useConfigStore();
@ -128,6 +167,15 @@
? "url('/src/assets/icons/rotate.svg') 12 12, auto"
: 'default'
);
const visiable_info = reactive({
handle_panel: computed(
() =>
globalStore.intention === EGlobalStoreIntention.Select ||
globalStore.intention === EGlobalStoreIntention.Zoom ||
globalStore.intention === EGlobalStoreIntention.Rotate
),
connection_panel: false
});
const dropEvent = (e: DragEvent) => {
if (globalStore.intention == EGlobalStoreIntention.None) {
return;
@ -138,8 +186,8 @@
}
const done_item_json: IDoneJson = {
id: globalStore.create_svg_info.name + randomString(),
x: e.offsetX - svgEditLayoutStore.center_offset.x,
y: e.offsetY - svgEditLayoutStore.center_offset.y,
x: e.clientX - svgEditLayoutStore.center_offset.x,
y: e.clientY - svgEditLayoutStore.center_offset.y,
client: {
x: e.clientX,
y: e.clientY
@ -204,7 +252,9 @@
};
const onSvgMouseDown = (select_item: IDoneJson, index: number, e: MouseEvent) => {
console.log(172, e);
if (globalStore.intention === EGlobalStoreIntention.Connection) {
return;
}
e.preventDefault();
e.cancelBubble = true;
//
@ -220,9 +270,22 @@
new_position_y: select_item.y
});
};
const onSvgMouseEnter = (select_item: IDoneJson, index: number, e: MouseEvent) => {
e.preventDefault();
e.cancelBubble = true;
visiable_info.connection_panel = true;
};
const onSvgMouseLeave = (select_item: IDoneJson, index: number, e: MouseEvent) => {
e.preventDefault();
e.cancelBubble = true;
visiable_info.connection_panel = false;
};
const onCanvasMouseMove = (e: MouseEvent) => {
//
if (globalStore.mouse_info.state != EMouseInfoState.Down) {
// 线
if (
globalStore.mouse_info.state != EMouseInfoState.Down &&
globalStore.intention !== EGlobalStoreIntention.Connection
) {
return;
}
const { clientX, clientY } = e;
@ -346,17 +409,17 @@
? new_length.height / globalStore.handle_svg_info.info.actual_bound.height
: 1;
const newCenterPoint = getCenterPoint(curPositon, globalStore.scale_info.symmetric_point);
const move_length_x = newCenterPoint.x - globalStore.handle_svg_info.info.client.x;
const move_length_y = newCenterPoint.y - globalStore.handle_svg_info.info.client.y;
if (
scale_x > 0 &&
globalStore.scale_info.type !== EScaleInfoType.TopCenter &&
globalStore.scale_info.type !== EScaleInfoType.BottomCenter
) {
globalStore.handle_svg_info.info.scale_x = scale_x;
globalStore.handle_svg_info.info.x =
globalStore.scale_info.scale_item_info.x + move_length_x;
globalStore.handle_svg_info.info.x = getSvgNowPosition(
globalStore.handle_svg_info.info.client.x,
newCenterPoint.x,
globalStore.scale_info.scale_item_info.x
);
}
if (
scale_y > 0 &&
@ -364,8 +427,11 @@
globalStore.scale_info.type !== EScaleInfoType.Right
) {
globalStore.handle_svg_info.info.scale_y = scale_y;
globalStore.handle_svg_info.info.y =
globalStore.scale_info.scale_item_info.y + move_length_y;
globalStore.handle_svg_info.info.y = getSvgNowPosition(
globalStore.handle_svg_info.info.client.y,
newCenterPoint.y,
globalStore.scale_info.scale_item_info.y
);
}
}
} else if (globalStore.intention === EGlobalStoreIntention.Rotate) {
@ -386,6 +452,25 @@
(Math.PI / 180);
globalStore.handle_svg_info.info.rotate =
globalStore.rotate_info.angle + rotateDegreeAfter - rotateDegreeBefore;
} else if (
globalStore.intention === EGlobalStoreIntention.Connection &&
globalStore.handle_svg_info
) {
globalStore.handle_svg_info.info.props.point_position.val[
globalStore.handle_svg_info?.info.props.point_position.val.length - 1
] = {
x: getSvgNowPosition(
globalStore.mouse_info.position_x,
clientX,
globalStore.handle_svg_info?.info.props.point_position.val[0].x
),
y: getSvgNowPosition(
globalStore.mouse_info.position_y,
clientY,
globalStore.handle_svg_info?.info.props.point_position.val[0].y
)
};
// console.log('线', start_x, start_y, end_x, end_y, clientX, clientY);
}
};
const onCanvasMouseUp = (e: MouseEvent) => {
@ -398,7 +483,8 @@
globalStore.mouse_info.new_position_x;
globalStore.done_json[globalStore.handle_svg_info.index].y =
globalStore.mouse_info.new_position_y;
globalStore.setDoneJson(globalStore.done_json);
// globalStore.setDoneJson(globalStore.done_json);
setSvgActualInfo(globalStore.done_json[globalStore.handle_svg_info.index]);
globalStore.intention = EGlobalStoreIntention.Select;
// globalStore.setHandleSvgInfo(undefined, 0);
} else if (
@ -414,6 +500,8 @@
console.log(newCenterPoint);
globalStore.handle_svg_info.info.client = newCenterPoint;
globalStore.intention = EGlobalStoreIntention.None;
} else if (globalStore.intention === EGlobalStoreIntention.Connection) {
return;
} else if (globalStore.intention != EGlobalStoreIntention.Select) {
globalStore.intention = EGlobalStoreIntention.None;
}
@ -429,18 +517,52 @@
});
};
const onCanvasMouseDown = (e: MouseEvent) => {
console.log('onCanvasMouseDown', e);
const { clientX, clientY } = e;
if (globalStore.intention === EGlobalStoreIntention.Connection && globalStore.handle_svg_info) {
if (e.button === 0) {
//线
globalStore.handle_svg_info.info.props.point_position.val.push({
x: getSvgNowPosition(
globalStore.mouse_info.position_x,
clientX,
globalStore.handle_svg_info?.info.props.point_position.val[0].x
),
y: getSvgNowPosition(
globalStore.mouse_info.position_y,
clientY,
globalStore.handle_svg_info?.info.props.point_position.val[0].y
)
});
}
if (e.button === 2) {
//线
globalStore.intention = EGlobalStoreIntention.None;
setSvgActualInfo(globalStore.done_json[globalStore.handle_svg_info.index]);
}
return;
}
//
globalStore.intention = EGlobalStoreIntention.MoveCanvas;
globalStore.setMouseInfo({
state: EMouseInfoState.Down,
position_x: e.clientX,
position_y: e.clientY,
position_x: clientX,
position_y: clientY,
now_position_x: svgEditLayoutStore.center_offset.x,
now_position_y: svgEditLayoutStore.center_offset.y,
new_position_x: svgEditLayoutStore.center_offset.x,
new_position_y: svgEditLayoutStore.center_offset.y
});
};
/**
* 鼠标右键事件
* @param select_component
* @param e
* @returns
*/
const onCanvasContextMenuEvent = (e: MouseEvent) => {
e.preventDefault(); //
};
</script>
<style lang="less" scoped>
.canvas {

@ -0,0 +1,186 @@
<!-- eslint-disable prettier/prettier -->
<!-- 连线组件 -->
<template>
<g style="vector-effect: non-scaling-stroke">
<circle
id="connection_tc"
:cx="props.itemInfo.actual_bound.x+props.itemInfo.actual_bound.width/2-offset+radius"
:cy="props.itemInfo.actual_bound.y-offset-getCoordinateOffset(props.itemInfo.actual_bound.height,props.itemInfo.scale_y)+radius"
:r="radius"
stroke="rgba(0,0,0,0)"
stroke-width="2"
:fill="fill"
:style="{ 'vector-effect': 'non-scaling-stroke'}"
pointer-events="all"
@mousedown="onConnectionMouseDown(ELineBindAnchors.TopCenter,$event)"/>
<circle
id="connection_l"
:cx="props.itemInfo.actual_bound.x-offset-getCoordinateOffset(props.itemInfo.actual_bound.width,props.itemInfo.scale_x)+radius"
:cy="props.itemInfo.actual_bound.y-offset+props.itemInfo.actual_bound.height*props.itemInfo.scale_y/2-getCoordinateOffset(props.itemInfo.actual_bound.height,props.itemInfo.scale_y)+radius"
:r="radius"
stroke="rgba(0,0,0,0)"
stroke-width="2"
:fill="fill"
:style="{ 'vector-effect': 'non-scaling-stroke'}"
pointer-events="all"
@mousedown="onConnectionMouseDown(ELineBindAnchors.Left,$event)"/>
<circle
id="connection_r"
:cx="props.itemInfo.actual_bound.x-offset+props.itemInfo.actual_bound.width+getCoordinateOffset(props.itemInfo.actual_bound.width,props.itemInfo.scale_x)+radius"
:cy="props.itemInfo.actual_bound.y-offset+props.itemInfo.actual_bound.height*props.itemInfo.scale_y/2-getCoordinateOffset(props.itemInfo.actual_bound.height,props.itemInfo.scale_y)+radius"
:r="radius"
stroke="rgba(0,0,0,0)"
stroke-width="2"
:fill="fill"
:style="{ 'vector-effect': 'non-scaling-stroke'}"
pointer-events="all"
@mousedown="onConnectionMouseDown(ELineBindAnchors.Right,$event)"/>
<circle
id="connection_bc"
:cx="props.itemInfo.actual_bound.x-offset+props.itemInfo.actual_bound.width/2+radius"
:cy="props.itemInfo.actual_bound.y-offset+props.itemInfo.actual_bound.height+getCoordinateOffset(props.itemInfo.actual_bound.height,props.itemInfo.scale_y)+radius"
:r="radius"
stroke="rgba(0,0,0,0)"
stroke-width="2"
:fill="fill"
:style="{ 'vector-effect': 'non-scaling-stroke'}"
pointer-events="all"
@mousedown="onConnectionMouseDown(ELineBindAnchors.BottomCenter,$event)"/>
</g>
</template>
<script lang="ts" setup>
// import { IConfigItem } from '@/config-center/types';
import { straight_line_system, connection_line_system } from '@/config-center/svg-file/system';
import { ELineBindAnchors, ISystemStraightLine } from '@/config-center/svg-file/system/types';
import { useConfigStore } from '@/store/config';
import { PropType, ref } from 'vue';
import { useGlobalStore } from '@/store/global';
import { EGlobalStoreIntention, EMouseInfoState } from '@/store/global/types';
import type { IDoneJson } from '@/store/global/types';
import {
getAnchorPosByAnchorType,
getCoordinateOffset,
objectDeepClone,
randomString
} from '@/utils/index';
const props = defineProps({
itemInfo: {
type: Object as PropType<IDoneJson>,
default: () => {}
}
});
const globalStore = useGlobalStore();
const configStore = useConfigStore();
const offset = ref(4);
const fill = ref('#4F80FF');
const radius = ref(4);
/**
* 点了连线
* @param bind_anchor_type 绑定锚点类型
* @param e
*/
const onConnectionMouseDown = (bind_anchor_type: ELineBindAnchors, e: MouseEvent) => {
e.preventDefault();
const { clientX, clientY } = e;
let create_line_info = objectDeepClone<ISystemStraightLine>(connection_line_system);
console.log('onConnectionMouseDown', connection_line_system, e);
//线 线
if (false) {
create_line_info = straight_line_system;
}
create_line_info.bind_anchors.start = {
type: bind_anchor_type,
target_id: props.itemInfo.id
};
const { x, y } = getAnchorPosByAnchorType(bind_anchor_type, props.itemInfo);
const done_item_json: IDoneJson = {
id: straight_line_system.name + randomString(),
x: x,
y: y,
client: {
x: clientX,
y: clientY
},
scale_x: 1,
scale_y: 1,
rotate: 0,
actual_bound: {
x: 0,
y: 0,
width: 0,
height: 0
},
point_coordinate: {
tl: {
x: 0,
y: 0
},
tc: {
x: 0,
y: 0
},
tr: {
x: 0,
y: 0
},
l: {
x: 0,
y: 0
},
r: {
x: 0,
y: 0
},
bl: {
x: 0,
y: 0
},
bc: {
x: 0,
y: 0
},
br: {
x: 0,
y: 0
}
},
...create_line_info
};
done_item_json.props.point_position.val.push(
{
x: configStore.svg.svg_position_center.x,
y: configStore.svg.svg_position_center.y
},
//push
{
x: configStore.svg.svg_position_center.x,
y: configStore.svg.svg_position_center.y
}
);
done_item_json.props.point_position.val.push();
globalStore.setHandleSvgInfo(done_item_json, globalStore.done_json.length);
globalStore.setDoneJson(done_item_json);
globalStore.intention = EGlobalStoreIntention.Connection;
globalStore.setMouseInfo({
state: EMouseInfoState.Down,
position_x: clientX,
position_y: clientY,
now_position_x: clientX,
now_position_y: clientY,
new_position_x: 0,
new_position_y: 0
});
};
</script>
<style scoped>
.rotate-circle {
stroke: v-bind('fill');
stroke-width: 1;
fill-opacity: 0;
cursor: url('@/assets/icons/rotate.svg') 12 12, auto;
}
</style>

@ -142,6 +142,7 @@
{ start: 158, end: 203, cursor: 'se', type: EScaleInfoType.BottomRight }
];
const onHandleMouseDown = (type: EScaleInfoType, e: MouseEvent) => {
console.log('onHandleMouseDown', e);
const { clientX, clientY } = e;
e.cancelBubble = true;
globalStore.intention = EGlobalStoreIntention.Zoom;

@ -1,51 +1,16 @@
import { useGlobalStore } from '../store/global';
import { calculateRotatedPointCoordinate } from '../utils';
import { IDoneJson } from '@/store/global/types';
import { calculateRotatedPointCoordinate } from '@/utils';
export const useSetPointCoordinate = () => {
const globalStore = useGlobalStore();
if (globalStore.handle_svg_info) {
const item_point = globalStore.handle_svg_info.info;
globalStore.handle_svg_info.info.point_coordinate = {
tl: calculateRotatedPointCoordinate(
item_point.point_coordinate.tl,
item_point.client,
-item_point.rotate
),
tc: calculateRotatedPointCoordinate(
item_point.point_coordinate.tc,
item_point.client,
-item_point.rotate
),
tr: calculateRotatedPointCoordinate(
item_point.point_coordinate.tr,
item_point.client,
-item_point.rotate
),
l: calculateRotatedPointCoordinate(
item_point.point_coordinate.l,
item_point.client,
-item_point.rotate
),
r: calculateRotatedPointCoordinate(
item_point.point_coordinate.r,
item_point.client,
-item_point.rotate
),
bl: calculateRotatedPointCoordinate(
item_point.point_coordinate.bl,
item_point.client,
-item_point.rotate
),
bc: calculateRotatedPointCoordinate(
item_point.point_coordinate.bc,
item_point.client,
-item_point.rotate
),
br: calculateRotatedPointCoordinate(
item_point.point_coordinate.br,
item_point.client,
-item_point.rotate
)
};
}
export const useSetPointCoordinate = (item: IDoneJson) => {
item.point_coordinate = {
tl: calculateRotatedPointCoordinate(item.point_coordinate.tl, item.client, -item.rotate),
tc: calculateRotatedPointCoordinate(item.point_coordinate.tc, item.client, -item.rotate),
tr: calculateRotatedPointCoordinate(item.point_coordinate.tr, item.client, -item.rotate),
l: calculateRotatedPointCoordinate(item.point_coordinate.l, item.client, -item.rotate),
r: calculateRotatedPointCoordinate(item.point_coordinate.r, item.client, -item.rotate),
bl: calculateRotatedPointCoordinate(item.point_coordinate.bl, item.client, -item.rotate),
bc: calculateRotatedPointCoordinate(item.point_coordinate.bc, item.client, -item.rotate),
br: calculateRotatedPointCoordinate(item.point_coordinate.br, item.client, -item.rotate)
};
console.log(item, 1515);
};

@ -4,6 +4,10 @@ export const circuit_breaker_svg_file: IConfigItem = {
name: 'circuit-breaker',
title: '断路器',
type: EDoneJsonType.File,
config: {
can_zoom: true,
have_anchor: true
},
props: {
fill: {
title: '填充色',

@ -4,6 +4,10 @@ export const alternator_svg_file: IConfigItem = {
name: 'alternator',
title: '发电机',
type: EDoneJsonType.File,
config: {
can_zoom: true,
have_anchor: true
},
props: {
fill: {
title: '填充色',

@ -4,6 +4,10 @@ export const traction_transformer_svg_file: IConfigItem = {
name: 'traction-transformer',
title: '牵引变',
type: EDoneJsonType.File,
config: {
can_zoom: true,
have_anchor: true
},
props: {
fill: {
title: '填充色',

@ -0,0 +1,68 @@
import { EConfigItemPropsType, EDoneJsonType } from '@/config-center/types';
import type { ISystemStraightLine } from './types';
export const straight_line_system: ISystemStraightLine = Object.seal({
name: 'straight-line',
title: '直线',
type: EDoneJsonType.StraightLine,
config: {
can_zoom: false,
have_anchor: false
},
props: {
fill: {
title: '填充色',
type: EConfigItemPropsType.Color,
val: '#ff0000'
},
start_x: {
title: '起点x坐标',
type: EConfigItemPropsType.InputNumber,
val: 0
},
start_y: {
title: '起点y坐标',
type: EConfigItemPropsType.InputNumber,
val: 0
},
end_x: {
title: '终点x坐标',
type: EConfigItemPropsType.InputNumber,
val: 0
},
end_y: {
title: '终点y坐标',
type: EConfigItemPropsType.InputNumber,
val: 0
}
},
bind_anchors: {
start: null,
end: null
}
});
export const connection_line_system: ISystemStraightLine = Object.freeze({
name: 'connection_line',
title: '连接线',
type: EDoneJsonType.ConnectionLine,
config: {
can_zoom: false,
have_anchor: false
},
props: {
fill: {
title: '填充色',
type: EConfigItemPropsType.Color,
val: '#ff0000'
},
point_position: {
title: '点坐标',
type: EConfigItemPropsType.JsonEdit,
val: []
}
},
bind_anchors: {
start: null,
end: null
}
});

@ -0,0 +1,19 @@
import { IConfigItem } from '@/config-center/types';
export interface ISystemStraightLine extends IConfigItem {
//绑定锚点
bind_anchors: {
start: IBindAnchors | null;
end: IBindAnchors | null;
};
}
export interface IBindAnchors {
type: ELineBindAnchors;
target_id: string;
}
export enum ELineBindAnchors {
TopCenter = 'TopCenter',
Left = 'Left',
Right = 'Right',
BottomCenter = 'BottomCenter'
}

@ -20,12 +20,13 @@ export interface IConfigItem {
title: string;
props: IConfigItemProps;
type: EDoneJsonType;
config: IDoneJsonConfig;
}
export interface IConfigItemProps {
[key: string]: {
title: string;
type: EConfigItemPropsType;
val: string;
val: any;
options?: { value: any; label: string }[];
};
}
@ -33,9 +34,15 @@ export enum EConfigItemPropsType {
Input = 'Input',
Color = 'Color',
InputNumber = 'InputNumber',
Switch = 'Switch' //此类型option默认索引0为关闭
Switch = 'Switch', //此类型option默认索引0为关闭
JsonEdit = 'JsonEdit'
}
export enum EDoneJsonType {
File = 'File',
StraightLine = 'StraightLine'
StraightLine = 'StraightLine',
ConnectionLine = 'ConnectionLine'
}
interface IDoneJsonConfig {
can_zoom: boolean;
have_anchor: boolean;
}

@ -12,6 +12,10 @@ export const useConfigStore = defineStore('config-store', {
position_center: {
x: -295,
y: -95
},
svg_position_center: {
x: 50,
y: 50
}
}
};

@ -6,5 +6,9 @@ export interface IPositionCenter {
x: number;
y: number;
};
svg_position_center: {
x: number;
y: number;
};
};
}

@ -1,8 +1,8 @@
import { defineStore } from 'pinia';
import { nextTick } from 'vue';
import { configCenter } from '../../config-center';
import { IConfigItem } from '../../config-center/types';
import { isOfType } from '../../utils';
import { configCenter } from '@/config-center';
import { IConfigItem } from '@/config-center/types';
import { isOfType, objectDeepClone, setSvgActualInfo } from '@/utils';
import {
EGlobalStoreIntention,
EMouseInfoState,
@ -20,7 +20,7 @@ export const useGlobalStore = defineStore('global-store', {
return {
config_center: configCenter,
intention: EGlobalStoreIntention.None,
create_svg_info: undefined,
create_svg_info: null,
done_json: [],
mouse_info: {
state: EMouseInfoState.Up,
@ -31,7 +31,7 @@ export const useGlobalStore = defineStore('global-store', {
new_position_x: 0,
new_position_y: 0
},
handle_svg_info: undefined,
handle_svg_info: null,
scale_info: {
type: EScaleInfoType.None,
scale_times: {
@ -54,7 +54,7 @@ export const useGlobalStore = defineStore('global-store', {
},
getters: {},
actions: {
setCreateInfo(create_svg_info: IConfigItem | undefined) {
setCreateInfo(create_svg_info: IConfigItem | null) {
this.intention = EGlobalStoreIntention.Create;
this.create_svg_info = create_svg_info;
},
@ -63,27 +63,16 @@ export const useGlobalStore = defineStore('global-store', {
if (isOfType(done_json, 'id')) {
this.done_json.push(done_json);
nextTick(() => {
const queryBbox = document.querySelector(`#${done_json.id}`);
const rectBBox = document.querySelector(`#rect${done_json.id}`);
// console.log(queryBbox, 190);
if (queryBbox && rectBBox) {
const BBox = (queryBbox as SVGGraphicsElement).getBBox();
const { x, y, width, height } = BBox;
rectBBox.setAttribute('x', x.toString());
rectBBox.setAttribute('y', y.toString());
rectBBox.setAttribute('width', width.toString());
rectBBox.setAttribute('height', height.toString());
done_json.actual_bound = { x, y, width, height };
}
setSvgActualInfo(done_json);
});
} else {
this.done_json = JSON.parse(JSON.stringify(done_json));
this.done_json = objectDeepClone<IDoneJson[]>(done_json);
}
},
setMouseInfo(mouse_info: IMouseInfo) {
this.mouse_info = mouse_info;
},
setHandleSvgInfo(info: IDoneJson | undefined, index: number) {
setHandleSvgInfo(info: IDoneJson | null, index: number) {
if (info) {
this.handle_svg_info = {
info: info,
@ -98,6 +87,6 @@ export const useGlobalStore = defineStore('global-store', {
}
}
});
useGlobalStore().$subscribe((mutation, state) => {
console.log(mutation, state, 102);
});
// useGlobalStore().$subscribe((mutation, state) => {
// console.log(mutation, state, 102);
// });

@ -3,10 +3,10 @@ import { IConfigCenter, IConfigItem } from '../../config-center/types';
export interface IGlobalStore {
config_center: IConfigCenter;
intention: EGlobalStoreIntention;
create_svg_info: IConfigItem | undefined;
create_svg_info: IConfigItem | null;
done_json: IDoneJson[];
mouse_info: IMouseInfo;
handle_svg_info: IHandleSvgInfo | undefined;
handle_svg_info: IHandleSvgInfo | null;
scale_info: IScaleInfo;
rotate_info: IRotateInfo;
}
@ -42,7 +42,8 @@ export enum EGlobalStoreIntention {
MoveCanvas = 'MoveCanvas',
Select = 'Select',
Zoom = 'Zoom',
Rotate = 'Rotate'
Rotate = 'Rotate',
Connection = 'Connection'
}
export interface IMouseInfo {
state: EMouseInfoState;

@ -1,3 +1,6 @@
import { ELineBindAnchors } from '@/config-center/svg-file/system/types';
import type { IDoneJson } from '@/store/global/types';
/**
*
* @param len
@ -72,3 +75,107 @@ export const getCenterPoint = (p1: { x: number; y: number }, p2: { x: number; y:
y: p1.y + (p2.y - p1.y) / 2
};
};
/**
* path
* @param position_arr
* @returns
*/
export const positionArrarToPath = (position_arr: { x: number; y: number }[]) => {
let path_str = '';
for (let index = 0; index < position_arr.length; index++) {
if (index === 0) {
path_str += `M ${position_arr[index].x} ${position_arr[index].y}`;
} else {
path_str += ` L ${position_arr[index].x} ${position_arr[index].y}`;
}
}
return path_str;
};
/**
* svg
* @param init_pos
* @param finally_pos
* @param svg_init_pos svg
* @returns svg
*/
export const getSvgNowPosition = (init_pos: number, finally_pos: number, svg_init_pos: number) => {
return svg_init_pos + (finally_pos - init_pos);
};
/**
*
* @param object
* @param default_val
* @returns
*/
export const objectDeepClone = <T>(object: object, default_val: any = {}) => {
if (!object) {
return default_val as T;
}
return JSON.parse(JSON.stringify(object)) as T;
};
/**
*
* @param done_json
*/
export const setSvgActualInfo = (done_json: IDoneJson) => {
const queryBbox = document.querySelector(`#${done_json.id}`);
const rectBBox = document.querySelector(`#rect${done_json.id}`);
if (queryBbox && rectBBox) {
const BBox = (queryBbox as SVGGraphicsElement).getBBox();
const { x, y, width, height } = BBox;
rectBBox.setAttribute('x', x.toString());
rectBBox.setAttribute('y', y.toString());
rectBBox.setAttribute('width', width.toString());
rectBBox.setAttribute('height', height.toString());
done_json.actual_bound = { x, y, width, height };
done_json.point_coordinate.tl = {
x: done_json.x - width / 2,
y: done_json.y - height / 2
};
done_json.point_coordinate.tc = {
x: done_json.x,
y: done_json.y - height / 2
};
done_json.point_coordinate.tr = {
x: done_json.x + width / 2,
y: done_json.y - height / 2
};
done_json.point_coordinate.l = {
x: done_json.x - width / 2,
y: done_json.y
};
done_json.point_coordinate.r = {
x: done_json.x + width / 2,
y: done_json.y
};
done_json.point_coordinate.bl = {
x: done_json.x - width / 2,
y: done_json.y + height / 2
};
done_json.point_coordinate.bc = {
x: done_json.x,
y: done_json.y + height / 2
};
done_json.point_coordinate.br = {
x: done_json.x + width / 2,
y: done_json.y + height / 2
};
}
};
/**
*
* @param anchor_type
* @param done_json
* @returns
*/
export const getAnchorPosByAnchorType = (anchor_type: ELineBindAnchors, done_json: IDoneJson) => {
if (anchor_type === ELineBindAnchors.BottomCenter) {
return done_json.point_coordinate.bc;
} else if (anchor_type === ELineBindAnchors.Left) {
return done_json.point_coordinate.l;
} else if (anchor_type === ELineBindAnchors.Right) {
return done_json.point_coordinate.r;
} else {
return done_json.point_coordinate.tc;
}
};

@ -12,7 +12,11 @@
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true,
"types": ["vite-plugin-svg-icons/client"]
"types": ["vite-plugin-svg-icons/client"],
"baseUrl": ".",
"paths":{
"@/*":["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]

Loading…
Cancel
Save