【精选】鼠标框选/ctrl+单击选中多个元素拖拽,缩放单个元素 您所在的位置:网站首页 Js拖动选择单元格 【精选】鼠标框选/ctrl+单击选中多个元素拖拽,缩放单个元素

【精选】鼠标框选/ctrl+单击选中多个元素拖拽,缩放单个元素

2023-11-16 10:34| 来源: 网络整理| 查看: 265

在这里插入图片描述1. 鼠标框选或ctrl+单击选中多个元素进行拖拽 2. 基于vue-drag-resize实现单个元素的大小缩放

(做的过程中比较坑的是vue-drag-resize)的拖动效果会和自己写的多个拖动事件之间有影响,所以就直接将vue-drag-resize的isDraggable设置为false,直接自己写拖动效果了)

上移: 下移: 左移: 右移: {{currentSelectChartIdArr}} {{item.id}} {{item.dragging}} import $ from 'jquery' import vueDragResize from 'vue-drag-resize' import SelectArea from './SelectArea.vue' export default { components: { vueDragResize, SelectArea }, data() { return { isPressCtrl: '', toTop: 0, toBottom: 0, toLeft: 0, toRight: 0, startPoint: {x: 0, y: 0}, endPoint: {x: 0, y: 0}, mouseKey: false, mouseComplete: false, currentSelectChartIdArr: [], currentChartDataArr: [], oldCurrentChartDataArr: [], selectedChartsDOM: [], datalist: [ { id: '0', w: 100, h: 200, x: 0, y: 0, color:'rgba(10,33,190,.1)' }, { id: '1', w: 200, h: 300, x: 200, y: 50, color:'rgba(10,83,190,.1)' }, { id: '2', w: 200, h: 300, x: 600, y: 50, color:'rgba(10,83,190,.1)' } ], dragFlag: false, startX: 0, startY: 0, clickStartTime: 0, clickEndTime: 0, containerClickStartTime: 0, containerClickEndTime: 0, isSingleFlag: true } }, watch: { currentSelectChartIdArr: { handler() { this.toTop = 0 this.toBottom = 0 this.toLeft = 0 this.toRight = 0 }, deep: true } }, mounted() { this.setup(); }, beforeDestroy() { window.removeEventListener('mouseup', this.handleMouseUp); window.removeEventListener('keydown', this.handleKeydown); window.removeEventListener('keyup', this.handleKeyup); }, methods: { handleChange(value, type) { this.getOutermost() if(type === 'left') { this.moveChart(0-value, 0) } else if(type === 'right') { this.moveChart(value, 0) } else if(type === 'top') { this.moveChart(0, 0-value) } else if(type === 'bottom') { this.moveChart(0, value) } }, setup() { this.mouseKey = false; // 是否监听鼠标移动(移出编辑区范围,不再监听鼠标移动事件) this.mouseComplete = false; // 鼠标移动事件是否完成(鼠标按下到抬起的流程) window.addEventListener('mouseup', this.handleMouseUp); window.addEventListener('keydown', this.handleKeydown) window.addEventListener('keyup', this.handleKeyup) }, handleKeydown(e) { console.log(e,e.keyCode) if(e.keyCode == 17) { this.isPressCtrl = true } }, handleKeyup(e){ this.isPressCtrl = false }, // 画选中框 - 鼠标按下 handleMouseDown(e) { this.containerClickStartTime = +new Date() this.startPoint.x = e.clientX; this.startPoint.y = e.clientY; this.mouseKey = true; this.mouseComplete = false; }, // 画选中框 - 鼠标按下并移动 handleMouseMove(e) { if (this.mouseKey && !this.mouseComplete) { this.endPoint.x = e.clientX this.endPoint.y = e.clientY this.getSelectCharts() } }, // 根据选中的内容,处理数据和选中图表的样式 getSelectCharts() { const selectAreaBox = document.getElementById('selectAreaBox') let {left, right, bottom, top} = selectAreaBox.getBoundingClientRect() let allCharts = document.querySelectorAll('.vdr') let selectedChartsDOM = [] let currentSelectChartIdArr = [] let currentChartDataArr = [] allCharts.forEach(item => { item.classList.remove('active') item.classList.remove('inactive') item.classList.add('inactive') let child = item.getBoundingClientRect() if (child.left > left && child.top > top && child.bottom currentChartDataArr.push(chartData) } } else { item.style.backgroundColor='#fff' } }) this.selectedChartsDOM = selectedChartsDOM this.currentSelectChartIdArr = currentSelectChartIdArr // 在这里把所有数据的dragging重置为false,避免vueDragResize和自己写的拖动事件发生冲突 currentChartDataArr.forEach((item, index) => { item.dragging = false }) this.currentChartDataArr = currentChartDataArr this.oldCurrentChartDataArr = JSON.parse(JSON.stringify(currentChartDataArr)) if(this.currentChartDataArr.length === 0) { this.isSingleFlag = true } else { this.isSingleFlag = false } }, // 画选中框 -- 鼠标抬起, 如果是点击主区域除图表外的其他地方,取消所有图表的选中状态 handleMouseUp(e){ this.mouseKey = false; this.mouseComplete = true; this.startPoint.x = 0; this.startPoint.y = 0; this.endPoint.x = 0; this.endPoint.y = 0; this.containerClickEndTime = +new Date() if(this.containerClickEndTime - this.containerClickStartTime this.clickStartTime = +new Date() if(this.isPressCtrl) { return false } if(this.currentSelectChartIdArr.length === 0 || this.isSingleFlag) { this.resetSelectMuti(e, data) } this.dragFlag = true this.startX = e.clientX this.startY = e.clientY // 找出最左,最右,最上,最下的元素 this.getOutermost() }, getOutermost() { let leftArr = [], rightArr = [], topArr = [], bottomArr = [] this.oldCurrentChartDataArr.forEach(item => { leftArr.push(item.x) topArr.push(item.y) rightArr.push(item.x + item.w) bottomArr.push(item.y + item.h) }) this.leftMax = Math.min(...leftArr) this.rightMax = Math.max(...rightArr) this.topMax = Math.min(...topArr) this.bottomMax = Math.max(...bottomArr) }, moveChart(moveX, moveY) { const {width, height} = document.querySelector('.main-container').getBoundingClientRect() let {leftMax, rightMax, topMax, bottomMax} = this if(this.currentSelectChartIdArr.length) { this.currentChartDataArr.forEach((item, index) => { if(moveX = 0 || moveX > 0 && rightMax + moveX item.y = this.oldCurrentChartDataArr[index].y + moveY } }) } }, // 多选时拖拽图表 -- 鼠标按住拖拽 onChartDragging(e) { if(!this.dragFlag) { return false } if(this.isPressCtrl) { return false } let moveX = e.clientX - this.startX let moveY = e.clientY - this.startY this.moveChart(moveX, moveY) }, // 多选时拖拽图表 -- 拖拽结束, 如果是单击了某个图表,取消其他图表的选中状态 onChartDragStop(e, data) { this.clickEndTime = +new Date() this.oldCurrentChartDataArr = JSON.parse(JSON.stringify(this.currentChartDataArr)) this.dragFlag = false this.clickEndTime = +new Date() if(this.clickEndTime - this.clickStartTime data.dragging = false let vdrBox = $(e.target).parents(".vdr")[0] let chartId = vdrBox.getAttribute('dataChartId') let index = this.currentSelectChartIdArr.indexOf(chartId) if(index > -1) { this.currentSelectChartIdArr.splice(index, 1) this.currentChartDataArr.splice(index, 1) this.selectedChartsDOM.splice(index, 1) vdrBox.style.backgroundColor = '#fff' } else { this.currentSelectChartIdArr.push(chartId) this.currentChartDataArr.push(data) this.selectedChartsDOM.push(vdrBox) vdrBox.style.backgroundColor = '#00aaff' } this.oldCurrentChartDataArr = JSON.parse(JSON.stringify(this.currentChartDataArr)) this.isSingleFlag = this.currentSelectChartIdArr.length === 0 } else { this.resetSelectMuti(e, data) this.isSingleFlag = true } } }, // 重置图表的选中状态 resetSelectMuti(e, data) { this.currentSelectChartIdArr = [] this.datalist.forEach(item => { item.dragging = false }) this.selectedChartsDOM.forEach(item => { item.style.backgroundColor = '#fff' }) this.currentChartDataArr = [] this.selectedChartsDOM = [] this.oldCurrentChartDataArr = [] if(data) { data.dragging = true let vdrBox = $(e.target).parents(".vdr")[0] let chartId = vdrBox.getAttribute('dataChartId') this.currentSelectChartIdArr.push(chartId) this.currentChartDataArr.push(data) this.selectedChartsDOM.push(vdrBox) this.oldCurrentChartDataArr = JSON.parse(JSON.stringify(this.currentChartDataArr)) } } } } * { margin: 0; padding: 0; } .body { width: 100%; height: 100vh; position: relative; >div { height: 100%; &.left { position: absolute; width: 300px; left: 0; top: 0; background: rgb(228, 125, 189); } &.main-container { margin: 0 100px 0 300px; position: relative; background: rgb(224, 247, 182); >div{ background: #fff; } } &.right { position: absolute; width: 100px; right: 0; top: 0; background: rgb(228, 125, 189); } } } 组件selectArea export default { name: 'SelectArea', props: { startPoint: { type: Object, required: true, }, endPoint: { type: Object, required: true, }, }, computed:{ Point() { let x = this.endPoint.x === 0 ? this.startPoint.x : Math.min(this.startPoint.x, this.endPoint.x); let y = this.endPoint.y === 0 ? this.startPoint.y : Math.min(this.startPoint.y, this.endPoint.y); return { x, y, }; }, size(){ let width = this.endPoint.x === 0 ? 0 : Math.abs(this.startPoint.x - this.endPoint.x); let height = this.endPoint.y === 0 ? 0 : Math.abs(this.startPoint.y - this.endPoint.y); return { width, height, }; } }, } .select-area { position: fixed; background-color: rgba(255, 192, 203, 0.1); border: 1px solid red; z-index: 9; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有