优化:画矩形选区

This commit is contained in:
jmal 2021-04-06 11:27:53 +08:00
parent 942961fcdc
commit a2d1d0fe9f
3 changed files with 104 additions and 110 deletions

View File

@ -19,7 +19,7 @@
<div v-else-if="item.contentType.indexOf('audio') > -1" v-on:mousedown="noDrag($event)"> <div v-else-if="item.contentType.indexOf('audio') > -1" v-on:mousedown="noDrag($event)">
<div v-if="item.music !== undefined"> <div v-if="item.music !== undefined">
<div v-if="item.music.name !== null"> <div v-if="item.music.name !== null">
<el-image v-if="grid" :style="{'width':details?'110px':'80px','height':details?'110px':'80px'}" fit="contain" :src="item.fileId ? (audioCoverUrl+item.fileId) : (audioCoverUrl+item.id)"> <el-image v-if="grid" :style="{'height':details?'110px':(gridWidth-35) + 'px'}" fit="contain" :src="item.fileId ? (audioCoverUrl+item.fileId) : (audioCoverUrl+item.id)">
<div slot="error" class="image-slot"> <div slot="error" class="image-slot">
<svg-icon class="avatar-default-image" icon-class="audio"/> <svg-icon class="avatar-default-image" icon-class="audio"/>
</div> </div>
@ -35,7 +35,7 @@
</div> </div>
<!--<svg-icon v-else-if="item.contentType.indexOf('text') > -1" icon-class="file-txt"/>--> <!--<svg-icon v-else-if="item.contentType.indexOf('text') > -1" icon-class="file-txt"/>-->
<div v-else-if="item.contentType.startsWith('image')" v-on:mousedown="noDrag($event)"> <div v-else-if="item.contentType.startsWith('image')" v-on:mousedown="noDrag($event)">
<el-image v-if="grid || grid === 'details'" :style="{'width':details?'110px':'80px','height':details?'110px':'80px'}" fit="contain" :src="item.fileId ? (imageUrl+item.fileId) : (imageUrl+item.id)"> <el-image v-if="grid || grid === 'details'" :style="{'height':details?'110px':(gridWidth-35) + 'px'}" fit="contain" :src="item.fileId ? (imageUrl+item.fileId) : (imageUrl+item.id)">
<div slot="error" class="image-slot"> <div slot="error" class="image-slot">
<svg-icon icon-class="loading-image-error"/> <svg-icon icon-class="loading-image-error"/>
</div> </div>
@ -67,6 +67,10 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
gridWidth: {
type: Number,
default: 120
},
details: { details: {
type: Boolean, type: Boolean,
default: false default: false

View File

@ -30,7 +30,7 @@
<el-tooltip v-if="index===0 && pathList.length > 1" class="item" effect="dark" content="返回上一级" <el-tooltip v-if="index===0 && pathList.length > 1" class="item" effect="dark" content="返回上一级"
placement="top"> placement="top">
<a @click.prevent="lastLink()"> <a @click.prevent="lastLink()">
<svg-icon icon-class="back" style="font-size: 24px;"/>&nbsp;</a> <svg-icon icon-class="back" style="font-size: 24px;margin-left: 20px;"/>&nbsp;</a>
</el-tooltip> </el-tooltip>
<el-tooltip v-if="index===0 && pathList.length > 2" class="item" effect="dark" content="根目录" <el-tooltip v-if="index===0 && pathList.length > 2" class="item" effect="dark" content="根目录"
placement="top"> placement="top">
@ -209,20 +209,22 @@
> >
<template v-for="(item,index) in tableHead"> <template v-for="(item,index) in tableHead">
<!--索引--> <!--索引-->
<pl-table-column <!-- <pl-table-column-->
v-if="index === 0 && !selectFile" <!-- v-if="index === 0 && !selectFile"-->
:key="index" <!-- :key="index"-->
:index="index" <!-- :index="index"-->
type="selection" <!-- type="selection"-->
min-width="50" <!-- min-width="50"-->
> <!-- >-->
</pl-table-column> <!-- </pl-table-column>-->
<!--图标--> <!--图标-->
<pl-table-column <pl-table-column
v-if="index === 1" v-if="index === 1"
:key="index" :key="index"
:index="index" :index="index"
width="50" align="center"
header-align="center"
width="80"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<icon-file :item="scope.row" :image-url="imageUrl" :audio-cover-url="audioCoverUrl"></icon-file> <icon-file :item="scope.row" :image-url="imageUrl" :audio-cover-url="audioCoverUrl"></icon-file>
@ -338,75 +340,35 @@
element-loading-text="文件加载中" element-loading-text="文件加载中"
element-loading-spinner="el-icon-loading" element-loading-spinner="el-icon-loading"
element-loading-background="#f6f7fa88"> element-loading-background="#f6f7fa88">
<!-- <div class="checkbox-group-header" v-show="!selectFile">-->
<!-- <div class="select-operation">-->
<!-- <van-checkbox class="grid-all-checkbox" @click="clickGridAllCheckBox" v-model="allChecked">-->
<!-- {{ selectRowData.length > 0 ? '已选择 ' + this.tableHead[2].label : "选择" }}-->
<!-- </van-checkbox>-->
<!-- <div>-->
<!-- <el-button class="select-operation-button" icon="el-icon-download" v-if="selectRowData.length > 0"-->
<!-- @click="downloadFile">-->
<!-- 下载-->
<!-- </el-button>-->
<!-- <el-button class="select-operation-button" icon="el-icon-share" v-if="selectRowData.length === 1"-->
<!-- @click="share">-->
<!-- 分享-->
<!-- </el-button>-->
<!-- <el-button class="select-operation-button" icon="el-icon-document-copy" v-if="selectRowData.length > 0"-->
<!-- @click="moveOrCopy">-->
<!-- 移动或复制-->
<!-- </el-button>-->
<!-- <el-button class="select-operation-button" icon="el-icon-delete" v-if="selectRowData.length > 0"-->
<!-- type="danger" @click="deleteFile">-->
<!-- </el-button>-->
<!-- </div>-->
<!-- </div>-->
<!-- <el-divider style="transform: scaleY(0.5);"></el-divider>-->
<!-- </div>-->
<van-checkbox-group v-model="selectRowData" @change="handleSelectionChange" ref="checkboxGroup"> <van-checkbox-group v-model="selectRowData" @change="handleSelectionChange" ref="checkboxGroup">
<van-grid square :center="true" :column-num="gridColumnNum" :gutter="10" :border="false" <van-grid square :center="true" :column-num="gridColumnNum" :gutter="10" :border="false"
:style="{'width':'100%','max-height': clientHeight-45+'px','overflow':'auto'}"> :style="{'width':'100%','max-height': clientHeight-45+'px','overflow':'auto'}">
<van-grid-item v-for="(item,index) in fileList" ref="gridItem" :key="item.id" <van-grid-item v-for="(item,index) in fileList" ref="gridItem" :key="item.id"
@click="gridItemClick(item)" :title="'大小:'+formatSize(item.size)+'\r\n'+(item.w && item.h ? '分辨率:'+item.w + 'x' + item.h +'\r\n' : '')+'名称:'+item.name+'\r\n'+'创建时间:'+item.uploadDate+'\r\n'+'修改时间:'+item.updateDate+'\r\n'+'路径:'+item.path"
> >
<div <div
class="grid-time van-grid-item__content van-grid-item__content--center van-grid-item__content--square" class="grid-time van-grid-item__content van-grid-item__content--center van-grid-item__content--square"
:style="{ :style="{
'background': queryFileType === 'image' ? 'url('+imageUrl+item.id+')' : selectRowData.includes(item)?'#caeaf991':'', 'background': selectRowData.includes(item)?'#caeaf991':'',
'background-size': 'cover', 'background-size': 'cover',
'background-position': 'center', 'background-position': 'center',
'border': selectRowData.includes(item)?'solid 1px #409eff':'', 'border': selectRowData.includes(item)?'solid 1px #409eff':'',
}" }"
@click="gridItemClick(item)"
@dblclick="fileClick(item)" @dblclick="fileClick(item)"
@mouseover="gridItemHover(item,index)" @mouseover="gridItemHover(item,index)"
@mouseout="gridItemOut(item,index)" @mouseout="gridItemOut(item,index)"
@contextmenu.prevent="rowContextmenu(item)" @contextmenu.prevent="rowContextmenu(item)"
> >
<!-- <van-checkbox v-show="!selectFile" v-if="gridHoverItemIndex === index || selectRowData.includes(item)"--> <div class="grid-item-icon">
<!-- class="grid-item-checkbox" :name="item"--> <icon-file :item="item" :image-url="imageUrl" :audio-cover-url="audioCoverUrl" :grid="true" :grid-width="gridColumnWidth"></icon-file>
<!-- @click.stop.prevent="clickGridItemCheckBox(item,index)"/>-->
<div :class="{'grid-item-icon':true, 'grid-item-icon-image': queryFileType === 'image' ? gridHoverItemIndex === index || selectRowData.includes(item) : false}">
<icon-file v-show="queryFileType !== 'image'" :item="item" :image-url="imageUrl" :audio-cover-url="audioCoverUrl"
:grid="true"></icon-file>
</div> </div>
<!--<el-tooltip effect="light" :content="item.name" placement="top">--> <div class="grid-item-text">{{ item.name }}</div>
<div v-show="item.w && item.h && queryFileType === 'image' ? gridHoverItemIndex === index || selectRowData.includes(item) : false"
:class="{'grid-item-text': true, 'grid-item-text-image-size': queryFileType === 'image'}">
{{ item.w + ' x ' + item.h }}
</div>
<div
:title="item.name"
v-show="queryFileType === 'image' ? gridHoverItemIndex === index || selectRowData.includes(item) : true"
:class="{'grid-item-text': true, 'grid-item-text-image': queryFileType === 'image'}">
{{ item.name }}
</div>
<!--</el-tooltip>-->
</div> </div>
</van-grid-item> </van-grid-item>
</van-grid> </van-grid>
</van-checkbox-group> </van-checkbox-group>
<!--<el-divider class="grid-divider" content-position="center"><i class="el-icon-folder-opened"></i>&nbsp;{{summaries}}</el-divider>-->
</div> </div>
</div> </div>
@ -798,6 +760,7 @@ export default {
grid: this.defaultGrid, grid: this.defaultGrid,
vmode: this.defaultGrid ? 'grid' : 'list', vmode: this.defaultGrid ? 'grid' : 'list',
gridColumnNum: -1, gridColumnNum: -1,
gridColumnWidth: 120,
gridHoverItemIndex: -1, gridHoverItemIndex: -1,
gridHoverIntermediate: -1, gridHoverIntermediate: -1,
allChecked: false, allChecked: false,
@ -823,7 +786,8 @@ export default {
selectOrgin: -1,// 选择起点(主要用于按住shift键多选) selectOrgin: -1,// 选择起点(主要用于按住shift键多选)
selectEnd: -1,// 选择终点 selectEnd: -1,// 选择终点
selectPin: false,// 默认false,不按住 selectPin: false,// 默认false,不按住
isCmd: false,// 是否按住了command键 isCmd: false,// 是否按住了command(control)键
isCmdA: false, // 是否按住了command(control) + A 键
dragElementList: [], dragElementList: [],
drawFlag: false, drawFlag: false,
fileListScrollTop: 0, fileListScrollTop: 0,
@ -883,27 +847,8 @@ export default {
} }
// 获取键盘事件 // 获取键盘事件
window.addEventListener('keydown', event => { window.addEventListener('keydown', event => this.keydown(event))
const isMac = navigator.platform.startsWith('Mac'); window.addEventListener('keyup', event => this.keyup(event))
const {key, c, keyCode, ctrlKey, metaKey} = event;
this.isCmd = isMac && metaKey || !isMac && ctrlKey;
// 按住shift建
if (event.keyCode === 16 && event.shiftKey) {
this.selectPin = true
}
})
window.addEventListener('keyup', event => {
const isMac = navigator.platform.startsWith('Mac');
const {key, c, keyCode, ctrlKey, metaKey} = event;
this.isCmd = isMac && metaKey || !isMac && ctrlKey;
// 松开shift建
if (event.keyCode === 16) {
this.selectPin = false
}
})
// 加载布局 // 加载布局
if (this.$route.query.vmode) { if (this.$route.query.vmode) {
@ -936,7 +881,9 @@ export default {
Bus.$on('msg/file/change', (msg) => this.onmessage(msg)) Bus.$on('msg/file/change', (msg) => this.onmessage(msg))
}, },
destroyed() { destroyed() {
window.removeEventListener('popstate', this.goBack, false); window.removeEventListener('keydown', this.keydown, false)
window.removeEventListener('keyup', this.keydown, false)
window.removeEventListener('popstate', this.goBack, false)
if (this.stompClient) { if (this.stompClient) {
this.stompClient.unsubscribe() this.stompClient.unsubscribe()
} }
@ -971,6 +918,33 @@ export default {
} }
}, },
methods: { methods: {
keydown(event) {
const isMac = navigator.platform.startsWith('Mac');
const {key, c, keyCode, ctrlKey, metaKey} = event;
this.isCmd = isMac && metaKey || !isMac && ctrlKey;
// 按住shift建
if (event.keyCode === 16 && event.shiftKey) {
this.selectPin = true
}
if(this.isCmd && keyCode == 65) {
this.$nextTick(() => {
if(this.$refs.fileListTable) {
this.$refs.fileListTable.toggleAllSelection()
}
})
event.preventDefault()
event.stopPropagation()
}
},
keyup(event) {
const isMac = navigator.platform.startsWith('Mac');
const {key, c, keyCode, ctrlKey, metaKey} = event;
this.isCmd = isMac && metaKey || !isMac && ctrlKey;
// 松开shift建
if (event.keyCode === 16) {
this.selectPin = false
}
},
onmessage(msg) { onmessage(msg) {
let fileDoc = JSON.parse(msg.body) let fileDoc = JSON.parse(msg.body)
const url = msg.headers.url const url = msg.headers.url
@ -1048,10 +1022,11 @@ export default {
let clientWidth = container.clientWidth let clientWidth = container.clientWidth
this.clientHeight = document.documentElement.clientHeight - this.lessClientHeight this.clientHeight = document.documentElement.clientHeight - this.lessClientHeight
if (this.queryFileType === 'image') { if (this.queryFileType === 'image') {
this.gridColumnNum = Math.round((clientWidth-10)/145) this.gridColumnNum = Math.round((clientWidth-10)/165)
} else { } else {
this.gridColumnNum = Math.round((clientWidth-10)/135) this.gridColumnNum = Math.round((clientWidth-10)/135)
} }
this.gridColumnWidth = (clientWidth - 11 * this.gridColumnNum) / this.gridColumnNum - 4.5
if(clientWidth < 900){ if(clientWidth < 900){
this.showUpdateDateItem = false this.showUpdateDateItem = false
} else { } else {
@ -1086,9 +1061,11 @@ export default {
} }
let evt = window.event || e let evt = window.event || e
if (_this.grid) { if (_this.grid) {
itemClassName = 'van-grid-item van-grid-item--square' itemClassName = 'van-grid-item__content van-grid-item__content--center van-grid-item__content--square'
} }
let throughRow = e.path.find(path => { console.log(e)
const elPath = e.path || (e.composedPath && e.composedPath())
let throughRow = elPath.find(path => {
if (path.className === itemClassName) { if (path.className === itemClassName) {
return path return path
} }
@ -1099,11 +1076,19 @@ export default {
if (evt.button !== 0) { if (evt.button !== 0) {
return return
} }
_this.dragElementList.forEach(element => { if (!_this.isCmd && !_this.selectPin) {
_this.$refs.fileListTable.toggleRowSelection([{row: _this.fileList[element.rowIndex], selected: false}]) let index = -1
}) if (_this.grid) {
const drawOffsetTop = getElementToPageTop(draw) index = elPath.findIndex(el => el.className === 'van-grid-item__content van-grid-item__content--center van-grid-item__content--square')
const drawOffsetLeft = getElementToPageLeft(draw) } else {
index = elPath.findIndex(el => el.className === 'plTableBox')
}
if(index < 0){
_this.dragElementList.forEach(element => {
_this.$refs.fileListTable.clearSelection()
})
}
}
let scrollTop = draw.scrollTop || draw.scrollTop let scrollTop = draw.scrollTop || draw.scrollTop
let scrollLeft = draw.scrollLeft || draw.scrollLeft let scrollLeft = draw.scrollLeft || draw.scrollLeft
startX = evt.clientX + scrollLeft startX = evt.clientX + scrollLeft
@ -1137,7 +1122,7 @@ export default {
return return
} }
const drawRectangle = $$(wId) const drawRectangle = $$(wId)
if (drawRectangle && retcTop >= drawOffsetTop) { if (drawRectangle) {
noScroll() noScroll()
drawRectangle.style.left = retcLeft + 'px' drawRectangle.style.left = retcLeft + 'px'
drawRectangle.style.top = retcTop + 'px' drawRectangle.style.top = retcTop + 'px'
@ -1315,9 +1300,9 @@ export default {
if (rectangle) { if (rectangle) {
document.getElementById('v-draw-rectangle').removeChild(rectangle) document.getElementById('v-draw-rectangle').removeChild(rectangle)
} }
const elPath = e.path || (e.composedPath && e.composedPath())
dragged = e.path[0] dragged = elPath[0]
draggedIndex = e.path[0].rowIndex draggedIndex = elPath[0].rowIndex
// 只有选中的才能拖拽 // 只有选中的才能拖拽
_this.cellMouseIndex = -1 _this.cellMouseIndex = -1
// dragged.style.cursor = 'grabbing' // dragged.style.cursor = 'grabbing'
@ -1342,12 +1327,13 @@ export default {
// 判断经过了那个元素 // 判断经过了那个元素
let judgThroughDom = function (e, d) { let judgThroughDom = function (e, d) {
let throughRow = null let throughRow = null
const elPath = e.path || (e.composedPath && e.composedPath())
if (_this.grid) { if (_this.grid) {
if (e.path[0].className === gridItemChildenClassName) { if (elPath[0].className === gridItemChildenClassName) {
// throughRow 表示被拖动的元素正在哪一行上 // throughRow 表示被拖动的元素正在哪一行上
return throughRow return throughRow
} else { } else {
throughRow = e.path.find(path => { throughRow = elPath.find(path => {
if (path.className === gridItemChildenClassName) { if (path.className === gridItemChildenClassName) {
return path return path
} }
@ -1377,9 +1363,9 @@ export default {
} }
return throughRow return throughRow
} else { } else {
if (e.path[0].tagName === 'TD') { if (elPath[0].tagName === 'TD') {
// throughRow 表示被拖动的元素正在哪一行上 // throughRow 表示被拖动的元素正在哪一行上
throughRow = e.path.find(path => { throughRow = elPath.find(path => {
if (path.className === 'el-table__row') { if (path.className === 'el-table__row') {
return path return path
} }
@ -3095,7 +3081,7 @@ export default {
} }
.info-statistics { .info-statistics {
padding: 5px 0; padding: 5px 15px;
float: right; float: right;
width: 30%; width: 30%;
display: -webkit-box; display: -webkit-box;
@ -3166,6 +3152,7 @@ export default {
>>> .van-grid-item__content { >>> .van-grid-item__content {
background-size: cover; background-size: cover;
background-position: center; background-position: center;
padding: 0;
} }
.vmode{ .vmode{
padding: 5px 10px; padding: 5px 10px;

View File

@ -1,7 +1,7 @@
.dashboard { .dashboard {
&-container { &-container {
min-width: 500px; min-width: 500px;
margin: 10px 10px 10px 15px; margin: 10px 0px 0px 0px;
} }
&-text { &-text {
font-size: 30px; font-size: 30px;
@ -285,7 +285,7 @@
} }
/deep/ .van-grid-item__content .svg-icon{ /deep/ .van-grid-item__content .svg-icon{
font-size: 4rem; font-size: 5rem;
} }
/deep/ .grid-item-text { /deep/ .grid-item-text {
text-align: center; text-align: center;
@ -296,6 +296,9 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
position: absolute;
padding: 0 5px 0 5px;
bottom: 5px;
} }
/deep/ .grid-item-text-image { /deep/ .grid-item-text-image {
position: absolute; position: absolute;
@ -307,11 +310,8 @@
top: 70%; top: 70%;
color: #ffffff; color: #ffffff;
} }
/deep/ .grid-item-text:hover {
color: #19ACF9;
}
/deep/ .grid-time { /deep/ .grid-time {
border-radius: 10px; border-radius: 5px;
padding: 0 8px; padding: 0 8px;
border: solid 1px #ccc0; border: solid 1px #ccc0;
.grid-item-checkbox { .grid-item-checkbox {
@ -322,16 +322,19 @@
} }
.grid-item-icon{ .grid-item-icon{
text-align: center; text-align: center;
position: relative; position: absolute;
margin: 9px auto 0; top: 5px;
width: 84px; //margin: 9px auto 0;
height: 84px; //width: 84px;
//height: 84px;
} }
.grid-item-icon-image { .grid-item-icon-image {
width: calc(100% + 16px); width: 100%;
height: 100%; height: 100%;
border-radius: 10px; top: 0px;
border-radius: 5px;
margin: 0; margin: 0;
-webkit-backdrop-filter: contrast(0.5);
backdrop-filter: contrast(0.5); backdrop-filter: contrast(0.5);
} }
} }