zhangxiao
2024-08-20 e47b788ff5f5c699c682999c95da17eb284ca21d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<template>
    <div
        id="the-draggable-container"
        :class="['the-draggable-container', props.grid && 'the-draggable-grid']"
        :style="containerStyle"
    >
        <slot></slot>
        <!--辅助线-->
        <span
            v-for="(item, index) in matchedRows"
            :key="index"
            :style="{
                width: item.width + 'px',
                height: '0',
                left: item.left + 'px',
                top: item.top + 'px',
                borderTop: `2px solid red`,
                position: 'absolute'
            }"
        ></span>
        <span
            v-for="(item, index) in matchedCols"
            :key="index"
            :style="{
                width: '0',
                height: item.height + 'px',
                top: item.top + 'px',
                left: item.left + 'px',
                borderLeft: `2px solid red`,
                position: 'absolute'
            }"
        ></span>
        <!--辅助线END-->
    </div>
</template>
<script lang="ts" setup name="TheDraggableContainer">
import { computed } from "vue";
import { MatchedLine, Position, SetMatchedLine } from "./type";
 
const list = ref<Position[]>([]);
 
const state = reactive<{
    matchedLine: MatchedLine | null;
}>({
    matchedLine: null
});
 
const setMatchedLine: SetMatchedLine = (matchedLine: MatchedLine | null) => {
    state.matchedLine = matchedLine;
};
 
const matchedRows = computed(() => state.matchedLine && state.matchedLine.row);
const matchedCols = computed(() => state.matchedLine && state.matchedLine.col);
 
const props = withDefaults(
    defineProps<{
        grid?: [number, number];
    }>(),
    {
        grid: undefined
    }
);
 
// const coordsList = computed(() => {
//     return list.value.map((item) => {
//         const topLeft = {
//             x: item.x,
//             y: item.y
//         };
//         const topRight = {
//             x: item.x + item.w,
//             y: item.y
//         };
//         const bottomLeft = {
//             x: item.x,
//             y: item.y + item.h
//         };
//         const bottomRight = {
//             x: item.x + item.w,
//             y: item.y + item.h
//         };
//         const center = {
//             x: item.x + item.w / 2,
//             y: item.y + item.h / 2
//         };
//         return {
//             topLeft,
//             topRight,
//             bottomLeft,
//             bottomRight,
//             center
//         };
//     });
// });
 
const containerStyle = computed(() => {
    const style: Record<string, any> = {};
    if (props.grid) {
        style.backgroundImage =
            "linear-gradient(to right, #ccc 1px, transparent 1px), linear-gradient(to bottom, #ccc 1px, transparent 1px)";
        style.backgroundSize = `${props.grid[0]}px ${props.grid[1]}px`;
    }
    return style;
});
 
provide("list", list);
provide("setMatchedLine", setMatchedLine);
// provide("coordsList", coordsList);
</script>
<style lang="scss" scoped>
.the-draggable-container {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.the-draggable-grid {
    // background-image: linear-gradient(to right, #ccc 1px, transparent 1px),
    //     linear-gradient(to bottom, #ccc 1px, transparent 1px);
    // background-size: 40px 80px;
}
</style>