mirror of
https://gitee.com/dromara/go-view.git
synced 2025-04-06 03:58:04 +08:00
feat: 新增页面框选效果
This commit is contained in:
parent
a54a007c5a
commit
f02e92a58e
@ -6,7 +6,7 @@ export enum MouseEventButton {
|
|||||||
|
|
||||||
// 页面拖拽键名
|
// 页面拖拽键名
|
||||||
export enum DragKeyEnum {
|
export enum DragKeyEnum {
|
||||||
DROG_KEY = 'ChartData'
|
DRAG_KEY = 'ChartData'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 操作枚举
|
// 操作枚举
|
||||||
|
@ -59,4 +59,10 @@ export const requestInterval = 30
|
|||||||
export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND
|
export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND
|
||||||
|
|
||||||
// 工作区域历史记录存储最大数量
|
// 工作区域历史记录存储最大数量
|
||||||
export const editHistoryMax = 100
|
export const editHistoryMax = 100
|
||||||
|
|
||||||
|
// 拖拽时蒙层的 z-index,需比所有图表高
|
||||||
|
export const canvasModelIndex = 9999
|
||||||
|
|
||||||
|
// 框选时蒙层的 z-index,需比所有图表高
|
||||||
|
export const selectBoxIndex = canvasModelIndex + 10
|
||||||
|
@ -21,7 +21,8 @@ export enum EditCanvasTypeEnum {
|
|||||||
USER_SCALE = 'userScale',
|
USER_SCALE = 'userScale',
|
||||||
LOCK_SCALE = 'lockScale',
|
LOCK_SCALE = 'lockScale',
|
||||||
IS_CREATE = 'isCreate',
|
IS_CREATE = 'isCreate',
|
||||||
IS_DRAG = 'isDrag'
|
IS_DRAG = 'isDrag',
|
||||||
|
IS_SELECT = 'isSelect'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑区域
|
// 编辑区域
|
||||||
@ -41,6 +42,8 @@ export type EditCanvasType = {
|
|||||||
[EditCanvasTypeEnum.IS_CREATE]: boolean
|
[EditCanvasTypeEnum.IS_CREATE]: boolean
|
||||||
// 拖拽中
|
// 拖拽中
|
||||||
[EditCanvasTypeEnum.IS_DRAG]: boolean
|
[EditCanvasTypeEnum.IS_DRAG]: boolean
|
||||||
|
// 框选中
|
||||||
|
[EditCanvasTypeEnum.IS_SELECT]: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滤镜/背景色/宽高主题等
|
// 滤镜/背景色/宽高主题等
|
||||||
|
@ -52,7 +52,9 @@ export const useChartEditStore = defineStore({
|
|||||||
// 初始化
|
// 初始化
|
||||||
isCreate: false,
|
isCreate: false,
|
||||||
// 拖拽中
|
// 拖拽中
|
||||||
isDrag: false
|
isDrag: false,
|
||||||
|
// 框选中
|
||||||
|
isSelect: false
|
||||||
},
|
},
|
||||||
// 右键菜单
|
// 右键菜单
|
||||||
rightMenuShow: false,
|
rightMenuShow: false,
|
||||||
@ -216,10 +218,10 @@ export const useChartEditStore = defineStore({
|
|||||||
},
|
},
|
||||||
// * 设置鼠标位置
|
// * 设置鼠标位置
|
||||||
setMousePosition(x?: number, y?: number, startX?: number, startY?: number): void {
|
setMousePosition(x?: number, y?: number, startX?: number, startY?: number): void {
|
||||||
if (startX) this.mousePosition.startX = startX
|
|
||||||
if (startY) this.mousePosition.startY = startY
|
|
||||||
if (x) this.mousePosition.x = x
|
if (x) this.mousePosition.x = x
|
||||||
if (y) this.mousePosition.y = y
|
if (y) this.mousePosition.y = y
|
||||||
|
if (startX) this.mousePosition.startX = startX
|
||||||
|
if (startY) this.mousePosition.startY = startY
|
||||||
},
|
},
|
||||||
// * 找到目标 id 数据的下标位置,id可为父级或子集数组(无则返回-1)
|
// * 找到目标 id 数据的下标位置,id可为父级或子集数组(无则返回-1)
|
||||||
fetchTargetIndex(id?: string): number {
|
fetchTargetIndex(id?: string): number {
|
||||||
|
@ -45,7 +45,7 @@ const dragStartHandle = (e: DragEvent, item: ConfigType) => {
|
|||||||
componentInstall(item.chartKey, fetchChartComponent(item))
|
componentInstall(item.chartKey, fetchChartComponent(item))
|
||||||
componentInstall(item.conKey, fetchConfigComponent(item))
|
componentInstall(item.conKey, fetchConfigComponent(item))
|
||||||
// 将配置项绑定到拖拽属性上
|
// 将配置项绑定到拖拽属性上
|
||||||
e!.dataTransfer!.setData(DragKeyEnum.DROG_KEY, JSON.stringify(omit(item, ['image'])))
|
e!.dataTransfer!.setData(DragKeyEnum.DRAG_KEY, JSON.stringify(omit(item, ['image'])))
|
||||||
// 修改状态
|
// 修改状态
|
||||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CREATE, true)
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_CREATE, true)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="go-edit-range go-transition" :style="rangeStyle" @mousedown="mousedownHandleUnStop($event, undefined)">
|
<div class="go-edit-range go-transition" :style="rangeStyle" @mousedown="mousedownBoxSelect($event, undefined)">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<!-- 水印 -->
|
<!-- 水印 -->
|
||||||
<edit-watermark></edit-watermark>
|
<edit-watermark></edit-watermark>
|
||||||
@ -7,19 +7,23 @@
|
|||||||
<edit-rule></edit-rule>
|
<edit-rule></edit-rule>
|
||||||
<!-- 拖拽时的辅助线 -->
|
<!-- 拖拽时的辅助线 -->
|
||||||
<edit-align-line></edit-align-line>
|
<edit-align-line></edit-align-line>
|
||||||
|
<!-- 框选时的样式框 -->
|
||||||
|
<edit-select></edit-select>
|
||||||
<!-- 拖拽时的遮罩 -->
|
<!-- 拖拽时的遮罩 -->
|
||||||
<div class="go-edit-range-model" :style="rangeModelStyle"></div>
|
<div v-if="showModel" class="go-edit-range-model" :style="rangeModelStyle"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { toRefs, computed } from 'vue'
|
import { toRefs, computed } from 'vue'
|
||||||
import { useSizeStyle } from '../../hooks/useStyle.hook'
|
import { useSizeStyle } from '../../hooks/useStyle.hook'
|
||||||
import { mousedownHandleUnStop } from '../../hooks/useDrag.hook'
|
import { canvasModelIndex } from '@/settings/designSetting'
|
||||||
|
import { mousedownBoxSelect } from '../../hooks/useDrag.hook'
|
||||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
import { EditAlignLine } from '../EditAlignLine'
|
import { EditAlignLine } from '../EditAlignLine'
|
||||||
import { EditWatermark } from '../EditWatermark'
|
import { EditWatermark } from '../EditWatermark'
|
||||||
import { EditRule } from '../EditRule'
|
import { EditRule } from '../EditRule'
|
||||||
|
import { EditSelect } from '../EditSelect'
|
||||||
|
|
||||||
const chartEditStore = useChartEditStore()
|
const chartEditStore = useChartEditStore()
|
||||||
|
|
||||||
@ -41,11 +45,15 @@ const rangeStyle = computed(() => {
|
|||||||
return { ...useSizeStyle(size.value), ...scale }
|
return { ...useSizeStyle(size.value), ...scale }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 是否展示模态层
|
||||||
|
const showModel = computed(() => {
|
||||||
|
return getEditCanvas.value.isCreate || getEditCanvas.value.isDrag
|
||||||
|
})
|
||||||
|
|
||||||
// 模态层
|
// 模态层
|
||||||
const rangeModelStyle = computed(() => {
|
const rangeModelStyle = computed(() => {
|
||||||
const dragStyle = getEditCanvas.value.isCreate && { 'z-index': 99999 }
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return { ...useSizeStyle(size.value), ...dragStyle }
|
return { ...useSizeStyle(size.value), 'z-index': canvasModelIndex }
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
import EditSelect from './index.vue'
|
||||||
|
|
||||||
|
export { EditSelect }
|
107
src/views/chart/ContentEdit/components/EditSelect/index.vue
Normal file
107
src/views/chart/ContentEdit/components/EditSelect/index.vue
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<div class="go-edit-select" v-if="isSelect" :style="positionStyle">
|
||||||
|
<div class="select-background"></div>
|
||||||
|
<div class="select-border"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, toRefs, watch } from 'vue'
|
||||||
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
|
import { useDesignStore } from '@/store/modules/designStore/designStore'
|
||||||
|
import { useSizeStyle, useComponentStyle } from '../../hooks/useStyle.hook'
|
||||||
|
import { selectBoxIndex } from '@/settings/designSetting'
|
||||||
|
|
||||||
|
// 全局颜色
|
||||||
|
const designStore = useDesignStore()
|
||||||
|
const themeColor = ref(designStore.getAppTheme)
|
||||||
|
const chartEditStore = useChartEditStore()
|
||||||
|
const { isSelect, scale } = toRefs(chartEditStore.getEditCanvas)
|
||||||
|
|
||||||
|
// 位置
|
||||||
|
const positionStyle = ref()
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => chartEditStore.getMousePosition,
|
||||||
|
positionInfo => {
|
||||||
|
if (!isSelect.value) return
|
||||||
|
|
||||||
|
const { startX, startY, x, y } = positionInfo
|
||||||
|
|
||||||
|
const attr = {
|
||||||
|
zIndex: selectBoxIndex,
|
||||||
|
// left
|
||||||
|
x: 0,
|
||||||
|
// top
|
||||||
|
y: 0,
|
||||||
|
// 宽
|
||||||
|
w: 0,
|
||||||
|
// 高
|
||||||
|
h: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理位置
|
||||||
|
if (x > startX && y > startY) {
|
||||||
|
// 右下
|
||||||
|
attr.x = startX
|
||||||
|
attr.y = startY
|
||||||
|
attr.w = Math.round((x - startX) / scale.value)
|
||||||
|
attr.h = Math.round((y - startY) / scale.value)
|
||||||
|
} else if (x > startX && y < startY) {
|
||||||
|
// 右上
|
||||||
|
attr.x = startX
|
||||||
|
attr.w = Math.round((x - startX) / scale.value)
|
||||||
|
attr.h = Math.round((startY - y) / scale.value)
|
||||||
|
attr.y = startY - attr.h
|
||||||
|
} else if (x < startX && y > startY) {
|
||||||
|
// 左下
|
||||||
|
attr.y = startY
|
||||||
|
attr.w = Math.round((startX - x) / scale.value)
|
||||||
|
attr.h = Math.round((y - startY) / scale.value)
|
||||||
|
attr.x = startX - attr.w
|
||||||
|
} else {
|
||||||
|
// 左上
|
||||||
|
attr.w = Math.round((startX - x) / scale.value)
|
||||||
|
attr.h = Math.round((startY - y) / scale.value)
|
||||||
|
attr.x = startX - attr.w
|
||||||
|
attr.y = startY - attr.h
|
||||||
|
}
|
||||||
|
|
||||||
|
positionStyle.value = {
|
||||||
|
...useComponentStyle(attr, selectBoxIndex),
|
||||||
|
...useSizeStyle(attr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@include go('edit-select') {
|
||||||
|
position: absolute;
|
||||||
|
.select-border,
|
||||||
|
.select-background {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.select-border {
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 1;
|
||||||
|
border-width: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: v-bind('themeColor');
|
||||||
|
}
|
||||||
|
.select-background {
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
opacity: 0.1;
|
||||||
|
background-color: v-bind('themeColor');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -20,7 +20,7 @@ export const dragHandle = async (e: DragEvent) => {
|
|||||||
loadingStart()
|
loadingStart()
|
||||||
|
|
||||||
// 获取拖拽数据
|
// 获取拖拽数据
|
||||||
const drayDataString = e!.dataTransfer!.getData(DragKeyEnum.DROG_KEY)
|
const drayDataString = e!.dataTransfer!.getData(DragKeyEnum.DRAG_KEY)
|
||||||
if (!drayDataString) {
|
if (!drayDataString) {
|
||||||
loadingFinish()
|
loadingFinish()
|
||||||
return
|
return
|
||||||
@ -60,6 +60,38 @@ export const mousedownHandleUnStop = (e: MouseEvent, item?: CreateComponentType
|
|||||||
chartEditStore.setTargetSelectChart(undefined)
|
chartEditStore.setTargetSelectChart(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * 框选
|
||||||
|
export const mousedownBoxSelect = (e: MouseEvent, item?: CreateComponentType | CreateComponentGroupType) => {
|
||||||
|
mousedownHandleUnStop(e)
|
||||||
|
|
||||||
|
// 记录点击初始位置
|
||||||
|
const startOffsetX = e.offsetX
|
||||||
|
const startOffsetY = e.offsetY
|
||||||
|
const startScreenX = e.screenX
|
||||||
|
const startScreenY = e.screenY
|
||||||
|
|
||||||
|
chartEditStore.setMousePosition(undefined, undefined, startOffsetX, startOffsetY)
|
||||||
|
|
||||||
|
// 移动框选
|
||||||
|
const mousemove = throttle((moveEvent: MouseEvent) => {
|
||||||
|
const currX = startOffsetX + moveEvent.screenX - startScreenX
|
||||||
|
const currY = startOffsetY + moveEvent.screenY - startScreenY
|
||||||
|
|
||||||
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_SELECT, true)
|
||||||
|
chartEditStore.setMousePosition(currX, currY)
|
||||||
|
}, 50)
|
||||||
|
|
||||||
|
// 鼠标抬起
|
||||||
|
const mouseup = () => {
|
||||||
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_SELECT, false)
|
||||||
|
chartEditStore.setMousePosition(0, 0, 0, 0)
|
||||||
|
document.removeEventListener('mousemove', mousemove)
|
||||||
|
document.removeEventListener('mouseup', mouseup)
|
||||||
|
}
|
||||||
|
document.addEventListener('mousemove', mousemove)
|
||||||
|
document.addEventListener('mouseup', mouseup)
|
||||||
|
}
|
||||||
|
|
||||||
// * 鼠标事件
|
// * 鼠标事件
|
||||||
export const useMouseHandle = () => {
|
export const useMouseHandle = () => {
|
||||||
// * Click 事件, 松开鼠标触发
|
// * Click 事件, 松开鼠标触发
|
||||||
@ -86,7 +118,6 @@ export const useMouseHandle = () => {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
onClickOutSide()
|
onClickOutSide()
|
||||||
|
|
||||||
// 按下左键 + CTRL
|
// 按下左键 + CTRL
|
||||||
if (
|
if (
|
||||||
e.buttons === MouseEventButton.LEFT &&
|
e.buttons === MouseEventButton.LEFT &&
|
||||||
@ -124,11 +155,10 @@ export const useMouseHandle = () => {
|
|||||||
const startY = e.screenY
|
const startY = e.screenY
|
||||||
|
|
||||||
// 记录初始位置
|
// 记录初始位置
|
||||||
chartEditStore.setMousePosition(startX, startY)
|
chartEditStore.setMousePosition(undefined, undefined, startX, startY)
|
||||||
|
|
||||||
// 移动-计算偏移量
|
// 移动-计算偏移量
|
||||||
const mousemove = throttle((moveEvent: MouseEvent) => {
|
const mousemove = throttle((moveEvent: MouseEvent) => {
|
||||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, true)
|
|
||||||
chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
|
chartEditStore.setMousePosition(moveEvent.screenX, moveEvent.screenY)
|
||||||
|
|
||||||
// 当前偏移量,处理 scale 比例问题
|
// 当前偏移量,处理 scale 比例问题
|
||||||
@ -136,8 +166,8 @@ export const useMouseHandle = () => {
|
|||||||
let offsetY = (moveEvent.screenY - startY) / scale
|
let offsetY = (moveEvent.screenY - startY) / scale
|
||||||
|
|
||||||
chartEditStore.getTargetChart.selectId.forEach(id => {
|
chartEditStore.getTargetChart.selectId.forEach(id => {
|
||||||
if(!targetMap.has(id)) return
|
if (!targetMap.has(id)) return
|
||||||
|
|
||||||
const index = chartEditStore.fetchTargetIndex(id)
|
const index = chartEditStore.fetchTargetIndex(id)
|
||||||
// 拿到初始位置数据
|
// 拿到初始位置数据
|
||||||
const { x, y, w, h } = targetMap.get(id)
|
const { x, y, w, h } = targetMap.get(id)
|
||||||
@ -166,8 +196,7 @@ export const useMouseHandle = () => {
|
|||||||
}, 30)
|
}, 30)
|
||||||
|
|
||||||
const mouseup = () => {
|
const mouseup = () => {
|
||||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
|
chartEditStore.setMousePosition(0, 0, 0, 0)
|
||||||
chartEditStore.setMousePosition(0, 0)
|
|
||||||
document.removeEventListener('mousemove', mousemove)
|
document.removeEventListener('mousemove', mousemove)
|
||||||
document.removeEventListener('mouseup', mouseup)
|
document.removeEventListener('mouseup', mouseup)
|
||||||
}
|
}
|
||||||
@ -237,7 +266,7 @@ export const useMousePointHandle = (e: MouseEvent, point: string, attr: PickCrea
|
|||||||
|
|
||||||
const mouseup = () => {
|
const mouseup = () => {
|
||||||
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
|
chartEditStore.setEditCanvas(EditCanvasTypeEnum.IS_DRAG, false)
|
||||||
chartEditStore.setMousePosition(0, 0)
|
chartEditStore.setMousePosition(0, 0, 0, 0)
|
||||||
document.removeEventListener('mousemove', mousemove)
|
document.removeEventListener('mousemove', mousemove)
|
||||||
document.removeEventListener('mouseup', mouseup)
|
document.removeEventListener('mouseup', mouseup)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user