vue列表拖拽到图片上打点定位(开箱即用)

图示:
在这里插入图片描述

上代码:

<template>
    <div>
        <div style="padding: 10px 0">
            <el-select v-model="storepointId" placeholder="请选择">
                <el-option
                    label="库点1"
                    value="1">
                </el-option>
                <el-option
                    label="库点2"
                    value="2">
                </el-option>
            </el-select>
            <el-button class="sumbitt-style" type="primary" size="medium" @click="sumbitt">保存</el-button>
            <el-button class="sumbitt-style"  size="medium" @click="clearAllPoint">清除所有标记</el-button>
        </div>
        <div style="display: flex">
            <div class="draggable-list">
                <el-scrollbar style="height:100%" wrap-style="overflow-x:hidden;">
                    <div v-for="(item, index) in storehouseList" :key="item.id" class="draggable-item"
                         :draggable="!item.draggableFalg"
                         @dragstart="onDragStart(item)">
                        <el-link icon="el-icon-s-home" class="link-style" :underline="false"
                                 :disabled="item.draggableFalg">{
   
   { item.text }}
                        </el-link>
                    </div>
                </el-scrollbar>

            </div>

            <div class="drop-area" ref="dragoverCont" @dragover.prevent @drop="onDrop">
                <div
                        @dragover.prevent
                        class="draggable"
                        v-for="(item, index) in pointList"
                        :key="index"
                        :style="{ top: `${item.top}px`, right: `${item.right}px`,zIndex:index==checkIndex?11:1 }"
                        @mousedown.stop="handleMouseDown(item, $event,index)">
                    <span class="draggable-name"> {
   
   { item.text }}<i class="el-icon-delete delete-icon"
                                                                    @click.stop="deleteList(item)"></i></span>

                </div>
            </div>
        </div>
    </div>


</template>

<script>
export default {
    data() {
        return {
            storehouseList: [
                {id: 1, text: '仓库1', draggableFalg: false},
                {id: 2, text: '仓库2', draggableFalg: false},
                {id: 3, text: '仓库3', draggableFalg: false},
                {id: 4, text: '仓库4', draggableFalg: false},
                {id: 5, text: '仓库5', draggableFalg: false}
            ],
            draggingItem: null,
            draggableFalg: false,
            storepointId:'',
            isDragging: false,
            draggedItem: null,
            startX: 0,
            startY: 0,
            offsetX: 0,
            offsetY: 0,
            pointList: [],
            checkIndex: 0,
            positionFalg: false,
            offsetWidth:0,
            offsetHeight:0
        }
    },
    mounted() {
        this.$nextTick(()=>{
            this.dragoverContOffset()
            this.getDataObject()
        })
    },
    methods: {
        dragoverContOffset(){
            this.offsetWidth=this.$refs.dragoverCont.offsetWidth
            this.offsetHeight=this.$refs.dragoverCont.offsetHeight
        },
        getDataObject(){
            let old=[{
                top:53,
                right:43,
                id: 1,
                text: '仓库1'
            },{
                top:73,
                right:63,
                id: 2,
                text: '仓库2'
            }]
            old.forEach(el=>{
                if(el.top){
                    el.top=parseInt(((el.top*this.offsetHeight)/100).toFixed(0))
                }
                if(el.right){
                    el.right=parseInt(((el.right*this.offsetWidth)/100).toFixed(0))
                }
                this.pointList.push(el)
            })
            let checkIdList = this.pointList.map(el => {
                return el.id
            })
            this.storehouseList.forEach(item => {
                if (checkIdList.includes(item.id)) {
                    item.draggableFalg = true
                }else {
                    item.draggableFalg = false
                }
            })
            console.log('pointList',this.pointList)

        },
        sumbitt() {
            let itemsList = JSON.parse(JSON.stringify(this.pointList))
            itemsList.forEach(item => {
                item.right = ((item.right / this.offsetWidth) * 100).toFixed(2)
                item.top = ((item.top / this.offsetHeight) * 100).toFixed(2)
            })
            console.log('this.itemsList', itemsList)
            console.log('this.pointList', this.pointList)
            // console.log('x%',(100-(x/this.offsetWidth)*100).toFixed(2))
            // console.log('y%',((y/this.offsetHeight)*100).toFixed(2))

        },
        clearAllPoint(){
            let checkIdList = this.pointList.map(el => {
                return el.id
            })
            this.storehouseList.forEach(item => {
                if (checkIdList.includes(item.id)) {
                    item.draggableFalg = false
                }
            })
            this.pointList=[]
            this.$message.warning('所有标记已清除,请保存!');
        },
        //删除
        deleteList(item) {
            this.pointList = this.pointList.filter(el => el.id != item.id)
            this.storehouseList.forEach(listItem => {
                if (listItem.id == item.id) {
                    listItem.draggableFalg = false
                }
            })
            this.$message.warning('标记已删除,请保存!');
        },
        //列表长按拖拽
        onDragStart(item) {
            this.draggingItem = item
        },
        //长按拖拽画布
        onDrop(event) {
            event.preventDefault()
            if (!this.draggedItem) {
                // 获取鼠标坐标
                const x = event.offsetX
                const y = event.offsetY
                this.pointList.push({
                    top: y,
                    right: this.offsetWidth - x,
                    id: this.draggingItem.id,
                    text: this.draggingItem.text
                })
                let checkIdList = this.pointList.map(el => {
                    return el.id
                })
                this.storehouseList.forEach(item => {
                    if (checkIdList.includes(item.id)) {
                        item.draggableFalg = true
                    }
                })
                this.draggingItem = null
                this.$message.warning('已标记,请保存!');
            }
        },
        //画布上的元素鼠标按下
        handleMouseDown(item, event, index) {
            this.isDragging = true;
            this.draggedItem = item;
            this.startX = event.clientX;
            this.startY = event.clientY;
            const rect = event.target.getBoundingClientRect();
            this.offsetX = event.clientX - rect.right;
            this.offsetY = event.clientY - rect.top;
            this.checkIndex = index;
            window.addEventListener("mousemove", this.handleMouseMove);
            window.addEventListener("mouseup", this.handleMouseUp);
        },
        //画布上的元素鼠标移动
        handleMouseMove(event) {
            if (this.isDragging && this.draggedItem) {
                const deltaX = event.clientX - this.startX;
                const deltaY = event.clientY - this.startY;
                if (deltaY != this.draggedItem.top) {
                    this.positionFalg = true
                }
                this.draggedItem.right -= deltaX;
                this.draggedItem.top += deltaY;
                // const rect = event.target.getBoundingClientRect();
                this.startX = event.clientX;
                this.startY = event.clientY;
                this.$forceUpdate();
            }
        },
        //画布上的元素鼠标离开
        handleMouseUp() {
            if (this.positionFalg) {
                this.$message.warning('位置已改变,请保存!');
            }
            this.positionFalg = false;
            this.isDragging = false;
            this.draggedItem = null;
            window.removeEventListener("mousemove", this.handleMouseMove);
            window.removeEventListener("mouseup", this.handleMouseUp);
        }
    }
}
</script>

<style>
.draggable-list {
    width: 1.5rem;
    height: 7.7rem;
    display: flex;
    flex-wrap: wrap;
    flex-direction: column;
    outline: 1px salmon solid;
}
.sumbitt-style{
    margin-left: 10px !important;
}
.el-icon-s-home{
    font-size: .22rem;
}
.draggable-item {
    margin: 10px;
    .link-style{
        cursor: grab;
        font-size: .18rem;
    }
    .el-link.el-link--default.is-disabled{
        cursor: no-drop !important;
    }
}

.drop-area {
    flex: 1;
    height: 7.7rem;
    outline: 1px salmon solid;
    /*background: url("/cloud/aerialViewImg/largeScreenShow/mainBgm.jpg");*/
    /*background-size: 100% 100%;*/
    text-align: center;
    position: relative;
    overflow: hidden;

}

.draggable {
    position: absolute;
    width: 0.6rem;
    height: 0.75rem;
    background: url('/cloud/aerialViewImg/largeScreenShow/smallIcon/warehouseInforIcon.png');
    background-size: 100% 100%;
    transform: translate(50%, -82%);
    cursor: grab;
    z-index: 999;

    &:hover .draggable-name {
        .delete-icon {
            display: inline-block;
        }
    }

    .draggable-name {
        cursor: grab;
        display: block;
        text-align: center;
        color: rgba(2, 251, 2, 1);
        font-size: 0.16rem;
        font-weight: bold;
        overflow: hidden;
        position: absolute;
        top: -.25rem;
        margin: 0 auto;
        white-space: nowrap; /* 子元素不自动换行 */

        .delete-icon {
            display: none;
            color: #d43f3a;
            cursor: pointer;
            margin-left: .05rem;
        }
    }
}
</style>

总结:列表拖拽到右边,已经打了点的列表不能再次拖拽,右边可以再次拖动更改位置。点击保存就是右边按照分辨率的比例点位。

猜你喜欢

转载自blog.csdn.net/weixin_44056717/article/details/131062900