| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- <template>
- <div class="go-edit-align-line">
- <div
- class="line"
- v-for="item in line.lineArr"
- :key="item"
- :class="[
- item.includes('row') ? 'row' : 'col',
- line['select'].has(item) && 'visible'
- ]"
- :style="useComponentStyle(line['select'].get(item))"
- />
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive, computed, watch } from 'vue'
- import { useDesignStore } from '@/store/modules/designStore/designStore'
- import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
- import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
- import { CreateComponentType } from '@/packages/index.d'
- import throttle from 'lodash/throttle'
- import cloneDeep from 'lodash/cloneDeep'
- // 全局颜色
- const designStore = useDesignStore()
- const themeColor = ref(designStore.getAppTheme)
- const chartEditStore = useChartEditStore()
- // 线条集合
- const line = reactive({
- // 吸附距离(px)
- minDistance: 10,
- // 行横向row(上中下),列竖线col(左中右)
- lineArr: ['rowt', 'rowc', 'rowb', 'coll', 'colc', 'colr'],
- // 展示线
- select: new Map(),
- // 已经吸附
- sorptioned: {
- x: false,
- y: false
- }
- })
- // 位置计算
- const useComponentStyle = (attr?: Partial<{ x: number; y: number }>) => {
- if (!attr) return {}
- const componentStyle = {
- left: `${attr.x ? attr.x : 0}px`,
- top: `${attr.y ? attr.y : 0}px`
- }
- return componentStyle
- }
- // 是否开始计算
- const isComputedLine = computed(() => {
- const isDrag = chartEditStore.getEditCanvas[EditCanvasTypeEnum.IS_DRAG]
- return isDrag
- })
- // 吸附判定
- const isSorption = (selectValue: number, componentValue: number) => {
- const isSorption = Math.abs(selectValue - componentValue) <= line.minDistance
- return isSorption
- }
- // 当前目标
- const selectId = computed(() => chartEditStore.getTargetChart.selectId)
- const selectTatget = computed(
- () => chartEditStore.getComponentList[chartEditStore.fetchTargetIndex()]
- )
- const selectAttr = computed(() => selectTatget.value.attr)
- // 画布坐标
- const canvasPositionList = computed(() => {
- return {
- id: '0',
- attr: {
- w: cloneDeep(chartEditStore.getEditCanvasConfig.width),
- h: cloneDeep(chartEditStore.getEditCanvasConfig.height),
- x: 0,
- y: 0,
- zIndex: 0
- }
- }
- })
- // 监听鼠标移动
- watch(
- () => chartEditStore.getMousePosition,
- throttle(e => {
- if (!isComputedLine.value) return
- // 获取目标组件数据
- const selectW = selectAttr.value.w
- const selectH = selectAttr.value.h
- // 距离左侧
- const selectLeftX = selectAttr.value.x
- const selectHalfX = selectLeftX + selectW / 2
- const selectRightX = selectLeftX + selectW
- const seletX = [selectLeftX, selectHalfX, selectRightX]
- // 距离顶部
- const selectTopY = selectAttr.value.y
- const selectHalfY = selectTopY + selectH / 2
- const selectBottomY = selectTopY + selectH
- const seletY = [selectTopY, selectHalfY, selectBottomY]
- line.select.clear()
- line.sorptioned.y = false
- // 循环查询所有组件数据
- const componentList = chartEditStore.getComponentList.map((e:CreateComponentType) => {
- return {
- id: e.id,
- attr: e.attr
- }
- })
- componentList.push(canvasPositionList.value)
- // 传入画布数据
- line.lineArr.forEach(lineItem => {
- componentList.forEach((component: typeof canvasPositionList.value) => {
- // 排除自身
- if (selectId.value === component.id) return
- const componentW = component.attr.w
- const componentH = component.attr.h
- // 距离左侧
- const componentLeftX = component.attr.x
- const componentHalfX = componentLeftX + componentW / 2
- const componentRightX = componentLeftX + componentW
- const componentX = [componentLeftX, componentHalfX, componentRightX]
- // 距离顶部
- const componentTopY = component.attr.y
- const componentHalfY = componentTopY + componentH / 2
- const componentBottomY = componentTopY + componentH
- const componentY = [componentTopY, componentHalfY, componentBottomY]
- // 横线对比的是 Y
- if (lineItem.includes('rowt')) {
- // 顶部
- if (isSorption(selectTopY, componentTopY)) {
- line.select.set(lineItem, { y: componentTopY })
- selectTatget.value.setPosition(selectLeftX, componentTopY)
- }
- if (isSorption(selectTopY, componentHalfY)) {
- line.select.set(lineItem, { y: componentHalfY })
- selectTatget.value.setPosition(selectLeftX, componentHalfY)
- }
- if (isSorption(selectTopY, componentBottomY)) {
- line.select.set(lineItem, { y: componentBottomY })
- selectTatget.value.setPosition(selectLeftX, componentBottomY)
- }
- }
- if (lineItem.includes('rowc')) {
- // 顶部
- if (isSorption(selectHalfY, componentTopY)) {
- line.select.set(lineItem, { y: componentTopY })
- selectTatget.value.setPosition(
- selectLeftX,
- componentTopY - selectH / 2
- )
- }
- if (isSorption(selectHalfY, componentHalfY)) {
- line.select.set(lineItem, { y: componentHalfY })
- selectTatget.value.setPosition(
- selectLeftX,
- componentHalfY - selectH / 2
- )
- }
- if (isSorption(selectHalfY, componentBottomY)) {
- line.select.set(lineItem, { y: componentBottomY })
- selectTatget.value.setPosition(
- selectLeftX,
- componentBottomY - selectH / 2
- )
- }
- }
- if (lineItem.includes('rowb')) {
- // 顶部
- if (isSorption(selectBottomY, componentTopY)) {
- line.select.set(lineItem, { y: componentTopY })
- selectTatget.value.setPosition(selectLeftX, componentTopY - selectH)
- }
- if (isSorption(selectBottomY, componentHalfY)) {
- line.select.set(lineItem, { y: componentHalfY })
- selectTatget.value.setPosition(
- selectLeftX,
- componentHalfY - selectH
- )
- }
- if (isSorption(selectBottomY, componentBottomY)) {
- line.select.set(lineItem, { y: componentBottomY })
- selectTatget.value.setPosition(
- selectLeftX,
- componentBottomY - selectH
- )
- }
- }
- // 纵线对比的是 X
- if (lineItem.includes('coll')) {
- if (isSorption(selectLeftX, componentLeftX)) {
- line.select.set(lineItem, { x: componentLeftX })
- selectTatget.value.setPosition(componentLeftX, selectTopY)
- }
- if (isSorption(selectLeftX, componentHalfX)) {
- line.select.set(lineItem, { x: componentHalfX })
- selectTatget.value.setPosition(componentHalfX, selectTopY)
- }
- if (isSorption(selectLeftX, componentRightX)) {
- line.select.set(lineItem, { x: componentRightX })
- selectTatget.value.setPosition(componentRightX, selectTopY)
- }
- }
- if (lineItem.includes('colc')) {
- if (isSorption(selectHalfX, componentLeftX)) {
- line.select.set(lineItem, { x: componentLeftX })
- selectTatget.value.setPosition(
- componentLeftX - selectW / 2,
- selectTopY
- )
- }
- if (isSorption(selectHalfX, componentHalfX)) {
- line.select.set(lineItem, { x: componentHalfX })
- selectTatget.value.setPosition(
- componentHalfX - selectW / 2,
- selectTopY
- )
- }
- if (isSorption(selectHalfX, componentRightX)) {
- line.select.set(lineItem, { x: componentRightX })
- selectTatget.value.setPosition(
- componentRightX - selectW / 2,
- selectTopY
- )
- }
- }
- if (lineItem.includes('colr')) {
- if (isSorption(selectRightX, componentLeftX)) {
- line.select.set(lineItem, { x: componentLeftX })
- selectTatget.value.setPosition(componentLeftX - selectW, selectTopY)
- }
- if (isSorption(selectRightX, componentHalfX)) {
- line.select.set(lineItem, { x: componentHalfX })
- selectTatget.value.setPosition(componentHalfX - selectW, selectTopY)
- }
- if (isSorption(selectRightX, componentRightX)) {
- line.select.set(lineItem, { x: componentRightX })
- selectTatget.value.setPosition( componentRightX - selectW, selectTopY )
- }
- }
- /*
- * 我也不知道为什么这个不行,还没时间调
- if(lineItem.includes('row')) {
- seletY.forEach(sY => {
- componentY.forEach(cY => {
- if (isSorption(sY, cY)) {
- line.select.set(lineItem, { y: cY })
- }
- })
- })
- return
- }
- if(lineItem.includes('col')) {
- seletX.forEach(sX => {
- componentX.forEach(cX => {
- if (isSorption(sX, cX)) {
- line.select.set(lineItem, { x: sX })
- }
- })
- })
- return
- }
- */
- })
- })
- }, 200),
- {
- deep: true
- }
- )
- // 取消对齐线
- watch(
- () => isComputedLine.value,
- (val: boolean) => {
- if (!val) {
- line.select.clear()
- line.sorptioned.y = false
- chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, true)
- }
- }
- )
- </script>
- <style lang="scss" scoped>
- @include go(edit-align-line) {
- .line {
- z-index: 1;
- position: absolute;
- top: 0;
- left: 0;
- display: none;
- border-width: 1px;
- border-style: solid;
- border-color: v-bind('themeColor');
- opacity: 0.7;
- &.visible {
- display: block;
- }
- }
- .row {
- width: 100%;
- }
- .col {
- height: 100%;
- }
- }
- </style>
|