refactor: dashboard

This commit is contained in:
wangjiahao
2025-05-16 12:55:12 +08:00
parent 273479af7a
commit 76bff9c1f8
3 changed files with 249 additions and 0 deletions
@@ -0,0 +1,126 @@
<script setup lang="ts">
import { type CanvasItem } from '../utils/CanvasUtils'
import { ref, toRefs, type PropType } from 'vue'
const shapeRef = ref(null)
// Props
const props = defineProps({
configItem: {
type: Object as PropType<CanvasItem>,
required: true
},
itemIndex: {
type: Number,
required: true
},
moveAnimate: {
type: Boolean,
required: true
},
draggable: {
type: Boolean,
required: true
},
baseWidth: {
type: Number,
default: 100
},
baseHeight: {
type: Number,
default: 50
},
baseMarginLeft: {
type: Number,
default: 20
},
baseMarginTop: {
type: Number,
default: 20
},
startMove: {
type: Function,
default: () => {
return {}
}
},
startResize: {
type: Function,
default: () => {
return {}
}
}
})
const {
baseWidth,
baseHeight,
baseMarginLeft,
baseMarginTop,
draggable,
} = toRefs(props)
const cursors = {
lt: 'nw',
t: 'n',
rt: 'ne',
r: 'e',
rb: 'se',
b: 's',
lb: 'sw',
l: 'w'
}
function getPointStyle(point: string) {
const hasT = /t/.test(point)
const hasB = /b/.test(point)
const hasL = /l/.test(point)
const hasR = /r/.test(point)
let newLeft = '0px'
let newTop = '0px'
// Points at the four corners
if (point.length === 2) {
newLeft = hasL ? '0px' : '100%'
newTop = hasT ? '0px' : '100%'
} else {
// The point between the upper and lower points, with a width centered
if (hasT || hasB) {
newLeft = '50%'
newTop = hasT ? '0px' : '100%'
}
// The points on both sides are centered in height
if (hasL || hasR) {
newLeft = hasL ? '0px' : '100%'
newTop ='50%'
}
}
return {
marginLeft: '-4px',
marginTop: '-4px',
left: `${newLeft}`,
top: `${newTop}`,
// @ts-expect-error
cursor: `${cursors[point]}-resize`
}
}
const pointList = ['lt', 't', 'rt', 'r', 'rb', 'b', 'lb', 'l']
</script>
<template>
<div :class="{
item: true,
moveAnimation: moveAnimate,
movingItem: configItem.isPlayer,
canNotDrag: !draggable
}" @mousedown="startMove($event, configItem, itemIndex)" ref="shapeRef">
<slot></slot>
<div v-for="point in pointList" :key="point" class="resizeHandle" :style="getPointStyle(point, configItem)"
@mousedown="startResize($event, point, configItem, itemIndex)"></div>
</div>
</template>
<style scoped lang="less">
@import '../css/CanvasStyle.less';
</style>
@@ -0,0 +1,97 @@
.dragAndResize
{
position: relative;
user-select: none;
*
{
box-sizing: border-box;
margin: 0;
padding: 0;
}
.item
{
position: absolute;
width: 100px;
height: 100px;
cursor: move;
border: 1px solid #59c7f9;
background-color: #fff;
.resizeHandle
{
position: absolute;
background: #fff;
border: 1px solid #59c7f9;
width: 8px;
height: 8px;
border-radius: 50%;
z-index: 0;
}
}
.moveAnimation
{
transition: top 80ms ease;
}
.canNotDrag
{
cursor: default!important;
}
.cloneNode
{
z-index: 3;
transition: none;
opacity: .5;
}
.movingItem
{
position: absolute;
border: none;
&:before
{
position: absolute;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: '';
background-color: #b8d3f9;
}
.resizeHandle
{
display: none;
}
}
.positionBox
{
position: fixed;
top: 0;
right: 100px;
overflow: auto;
width: 500px;
height: 500px;
border: 1px solid;
}
.coords
{
position: fixed;
right: 100px;
bottom: 200px;
overflow: auto;
width: 200px;
height: 200px;
border: 1px solid;
}
}
@@ -0,0 +1,26 @@
export interface CanvasItem {
_dragId: string | number
x: number
y: number
sizeX: number
sizeY: number
[key: string]: any
}
export type CanvasCoord = {
x1: number
y1: number
x2: number
y2: number
c1: number
c2: number
el: {
x: number
y: number
sizeX: number
sizeY: number
_dragId: string | number
[key: string]: any
}
}