vue中实现鼠标框选功能

283 阅读1分钟

前端业务中的鼠标框选功能

<template>
    <div class="box-img" @mousedown="handleMouseDown"
        :style="{ width: maxWidth + 'px', height: maxHeight + 'px', left: divLeft + 'px', top: divTop + 'px' }"
        ref="parent">
        <div class="mask" v-show="this.positionList.is_show_mask"
            :style="'width:' + mask_width + 'left:' + mask_left + 'height:' + mask_height + 'top:' + mask_top"></div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            positionList: {
                is_show_mask: false,
                start_x: 0,
                start_y: 0,
                end_x: 0,
                end_y: 0
            },
            maxWidth: 500,
            maxHeight: 500,
            divLeft: 500,
            divTop: 100,
            selectWidth: '',
            selectHeight: '',
        }
    },
    computed: {
        mask_width() {
            this.selectWidth = Math.abs(this.positionList.end_x - this.positionList.start_x)
            return `${this.selectWidth}px;`;
        },
        mask_height() {
            this.selectHeight = Math.abs(this.positionList.end_y - this.positionList.start_y)
            return `${this.selectHeight}px;`;
        },
        mask_left() {
            return `${Math.min(this.positionList.start_x, this.positionList.end_x) - this.divLeft}px;`;
        },
        mask_top() {
            return `${Math.min(this.positionList.start_y, this.positionList.end_y) - this.divTop}px;`;
        }
    },
    methods: {
        handleMouseDown(event) {
            this.positionList.is_show_mask = true;
            this.positionList.start_x = event.clientX
            this.positionList.start_y = event.clientY
            this.positionList.end_x = event.clientX
            this.positionList.end_y = event.clientY
            document.addEventListener("mousemove", this.handleMouseMove); //监听鼠标移动事件
            document.addEventListener("mouseup", this.handleMouseUp); //监听鼠标抬起事件
        },
        handleMouseMove(event) {
            if (event.clientX > this.divLeft) {
                this.positionList.end_x = event.clientX
            } else {
                this.positionList.end_x = this.divLeft
            }
            if (event.clientX > this.divLeft + this.maxWidth) {
                this.positionList.end_x = this.divLeft + this.maxWidth
            }

            if (event.clientY > this.divTop) {
                this.positionList.end_y = event.clientY
            } else {
                this.positionList.end_y = this.divTop
            }
            if (event.clientY > this.divTop + this.maxHeight) {
                this.positionList.end_y = this.divTop + this.maxHeight
            }
        },

        handleMouseUp() {
            document.removeEventListener("mousemove", this.handleMouseMove);
            document.removeEventListener("mouseup", this.handleMouseUp);
            this.positionList.is_show_mask = false;
            const origin = [this.divLeft, this.divTop]
            const leftTop = this.transformCoordinate([this.positionList.start_x, this.positionList.start_y], origin)
            const rightTop = this.transformCoordinate([this.positionList.end_x, this.positionList.start_y], origin)
            const rightBottom = this.transformCoordinate([this.positionList.end_x, this.positionList.end_y], origin)
            const leftBottom = this.transformCoordinate([this.positionList.start_x, this.positionList.end_y], origin)
            const result = [leftTop, rightTop, rightBottom, leftBottom]
            console.log(result);
            // this.resSetXY();
        },
        resSetXY() {
            this.positionList.start_x = 0;
            this.positionList.start_y = 0;
            this.positionList.end_x = 0;
            this.positionList.end_y = 0;
        },
        transformCoordinate(newCoordinate, oldCoordinate) {
            const newX = newCoordinate[0] - oldCoordinate[0];
            const newY = newCoordinate[1] - oldCoordinate[1];
            return [newX, newY];
        }
    }
}
</script>
<style lang="scss" scoped>
.box-img {
    display: flex;
    align-items: center;
    justify-content: space-around;
    position: relative;
    left: 200px;
    top: 100px;
    background: red;

    .mask {
        position: absolute;
        background: #409eff;
        opacity: 0.4;
        z-index: 100;
    }
}
</style>