393 lines
11 KiB
Vue
393 lines
11 KiB
Vue
<template>
|
|
<div class="generalDrag" ref="generalDragDom">
|
|
<div class="item" v-show="showMark" :style="likeStyle">
|
|
<a-spin size="large" class="content_img_flex"></a-spin>
|
|
</div>
|
|
<div v-for="item in list" :key="item.id" class="item"
|
|
:style="likeStyle"
|
|
@mousedown.stop="designMousedown(getMousePosition($event,false),item.id,'disLike')"
|
|
@touchstart.passive="designMousedown(getMousePosition($event,true),item.id,'disLike')"
|
|
>
|
|
|
|
<img v-if="item.url"
|
|
:class="[isVideo?'video':'']"
|
|
@mouseenter.stop="gifPlay($event,item)"
|
|
@mouseleave.stop="gifPause($event,item)"
|
|
:src="item.url"
|
|
alt=""
|
|
>
|
|
<a-spin v-else size="large" class="content_img_flex"></a-spin>
|
|
<div class="btn">
|
|
<div class="like" v-if="item.url" @click.stop="()=>$emit('setBtn',item.id,'like')">
|
|
<i :class="['fi',isLike?'fi-sr-heart srLike':'fi-rr-heart']"></i>
|
|
</div>
|
|
<div class="down" v-if="isVideo && item.url" @click.stop="down(item)">
|
|
<i class="fi fi-ss-down-to-line"></i>
|
|
</div>
|
|
<div class="zoom" v-if="item.url" @click.stop="()=>$emit('setBtn',item.id,'zoom')">
|
|
<i class="fi fi-bs-expand-arrows-alt"></i>
|
|
</div>
|
|
<div class="copy" v-if="item.url && (type == 'Relight') && isCopy" @click.stop="()=>$emit('setBtn',item.id,'copy')">
|
|
<i class="fi fi-br-refresh"></i>
|
|
</div>
|
|
<div class="delete" v-if="item.url && isDelete" @click.stop="()=>$emit('setBtn',item.id,'delete')">
|
|
<i class="fi fi-rr-trash icon_delete"></i>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script lang="ts">
|
|
import { defineComponent,computed,ref,provide,nextTick,onMounted,toRefs, reactive,onBeforeUnmount, watch} from 'vue'
|
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
|
import { useStore } from "vuex";
|
|
import { useI18n } from 'vue-i18n'
|
|
import { getMousePosition } from "@/tool/mdEvent"
|
|
export default defineComponent({
|
|
components:{
|
|
},
|
|
props:{
|
|
selectKey:{type:String,default:''},
|
|
list:{type:Array,default:()=>[]},
|
|
isVideo:{type:Boolean,default:false},
|
|
showMark:{type:Boolean,default:false},
|
|
isLike:{type:Boolean,default:false},
|
|
isDelete:{type:Boolean,default:true},
|
|
isCopy:{type:Boolean,default:true},
|
|
type:{type:String,default:''},
|
|
},
|
|
emits:['setBtn','setSort'],
|
|
setup(props,{emit}) {
|
|
const store = useStore();
|
|
const data = reactive({
|
|
selectIndex:0,
|
|
observerData:{
|
|
time:false as any,
|
|
observer:null as any,
|
|
},
|
|
})
|
|
const dataDom = reactive({
|
|
generalDragDom:null as any,
|
|
})
|
|
const collItemSize = reactive({
|
|
collValue:18,
|
|
num:2,
|
|
padding:40,
|
|
likeStyle:{
|
|
width:'0px',
|
|
// width:'240px',
|
|
height:'0px',
|
|
// height:'370px',
|
|
position:'absolute',
|
|
},
|
|
itemStyle:{
|
|
width:0,
|
|
height:0,
|
|
},
|
|
scale:[1,1.539],
|
|
collTime:null as any,
|
|
isMove:false,
|
|
elList:[] as any,
|
|
})
|
|
const designMousedown = (e:any,Id:number,str:string)=>{
|
|
let item:any = collItemSize.elList.filter((item:any)=>item.id == Id)[0]
|
|
if(!item)return
|
|
item.el.style.zIndex = 2;
|
|
item.el.style.transition = 'all 0s';
|
|
let startX = e.clientX,
|
|
startY = e.clientY,
|
|
left = item.el.offsetLeft,
|
|
top = item.el.offsetTop;
|
|
collItemSize.isMove = false
|
|
let moveFun = (e:any) => {
|
|
collItemSize.isMove = true
|
|
let X = e.clientX - startX + left;
|
|
let Y = e.clientY - startY + top;
|
|
item.el.style.left = `${X}px`;
|
|
item.el.style.top = `${Y}px`;
|
|
reRange(item, X, Y,str);
|
|
};
|
|
let mouseUpFun = ()=>{
|
|
document.removeEventListener('mousemove',mouseMove)
|
|
document.removeEventListener('touchmove',touchmove)
|
|
|
|
document.removeEventListener('mouseup',mouseUpFun)
|
|
document.removeEventListener('touchend',mouseUpFun)
|
|
item.el.style.zIndex = 1;
|
|
item.el.style.transition = 'top,left .5s';
|
|
moveItem();
|
|
if(str == 'like')sortDesignCollection()
|
|
}
|
|
let mouseMove = function(event:any){
|
|
let e = getMousePosition(event,false)
|
|
moveFun(e)
|
|
}
|
|
let touchmove = function(event:any){
|
|
let e = getMousePosition(event,true)
|
|
moveFun(e)
|
|
}
|
|
|
|
document.addEventListener('mousemove',mouseMove)
|
|
document.addEventListener('touchmove',touchmove)
|
|
|
|
document.addEventListener('mouseup',mouseUpFun)
|
|
document.addEventListener('touchend',mouseUpFun)
|
|
}
|
|
//排序 从大到小
|
|
const sortDesignCollection = ()=> {
|
|
// let arrData:any = []
|
|
// likeDesignCollectionList.value.forEach((likeItem:any)=>{
|
|
// let item = collItemSize.elList.filter((item:any)=>item.id == likeItem.id)[0]
|
|
// likeItem.sort = item.sort + 1
|
|
// let obj = {
|
|
// id:likeItem.id,
|
|
// "sort": item.sort + 1,
|
|
// "userLikeGroupId": likeItem.userLikeGroupId,
|
|
// "userLikeId": likeItem.id
|
|
// }
|
|
// arrData.push(obj)
|
|
// })
|
|
// let data = {
|
|
// "userLikeGroupId": userGroupId.value,
|
|
// "userLikeSortList": arrData
|
|
// }
|
|
// Https.axiosPost(Https.httpUrls.designSort, data).then((rv:any)=>{
|
|
// })
|
|
}
|
|
const reRange = (item:any, x:number, y:number,str:string)=>{
|
|
dataDom.generalDragDom
|
|
let elList:any = collItemSize.elList
|
|
let index = data.selectIndex
|
|
let width,height,num
|
|
num = collItemSize.num
|
|
width = collItemSize.itemStyle.width
|
|
height = collItemSize.itemStyle.height
|
|
|
|
let moveIndex = Math.round(x / (width + 10)) + Math.round(y / (height + 10)) * num;
|
|
moveIndex = elList.length - 1 - moveIndex
|
|
moveIndex = moveIndex < 0 ? 0 : moveIndex;
|
|
moveIndex = moveIndex > elList.length - 1 ? elList.length - 1 : moveIndex;
|
|
if(moveIndex != index){
|
|
data.selectIndex = moveIndex;
|
|
|
|
let currentSort = item.sort;
|
|
for(let i = 0;i < elList.length;i++){
|
|
if(currentSort < moveIndex){
|
|
if(elList[i].sort > currentSort && elList[i].sort <= moveIndex){
|
|
elList[i].sort -= 1;
|
|
};
|
|
}else if(currentSort > moveIndex){
|
|
if(elList[i].sort < currentSort && elList[i].sort >= moveIndex){
|
|
elList[i].sort += 1;
|
|
};
|
|
}
|
|
};
|
|
elList[item.index].sort = moveIndex;
|
|
moveItem();
|
|
}
|
|
}
|
|
const moveItem = ()=>{
|
|
let value = collItemSize.num
|
|
// let num = str == 'like'?value:3
|
|
for(let i = 0;i < collItemSize.elList.length;i++){
|
|
if(!collItemSize.elList[i].el)return
|
|
collItemSize.elList[i].el.style.left = (collItemSize.elList.length - 1 - collItemSize.elList[i].sort) % value * (collItemSize.itemStyle.width +10) + collItemSize.padding/2 + 'px';
|
|
collItemSize.elList[i].el.style.top = parseInt(String((collItemSize.elList.length - 1 - collItemSize.elList[i].sort) / value)) * (collItemSize.itemStyle.height +10) + 'px';
|
|
}
|
|
|
|
}
|
|
const setItemPosition = ()=>{
|
|
let parent = dataDom.generalDragDom.offsetWidth
|
|
let elArr = dataDom.generalDragDom.children
|
|
let value = collItemSize.num
|
|
//子元素宽度 = (父容器总宽度 - (列数-1)*间隙) / 列数
|
|
collItemSize.itemStyle.width = (parent - collItemSize.padding - ((value-1)*10)) / value
|
|
// collItemSize.itemStyle.width = (parent - (value * 10)) / value
|
|
collItemSize.itemStyle.height = collItemSize.itemStyle.width * 1.539
|
|
collItemSize.likeStyle.width = collItemSize.itemStyle.width + 'px'
|
|
collItemSize.likeStyle.height = collItemSize.itemStyle.height + 'px'
|
|
collItemSize.elList = []
|
|
let arr:any = props.list
|
|
for(let i = 0;i < arr.length;i++){
|
|
collItemSize.elList.push({
|
|
el: elArr[i+1],
|
|
sort: arr.length - i -1,
|
|
// sort: props.list[i].sort?props.list[i].sort:props.list.length - i -1,
|
|
index: i,
|
|
id:arr[i].id,
|
|
});
|
|
}
|
|
moveItem()
|
|
}
|
|
watch(()=>props.list.length,(val)=>{
|
|
nextTick(()=>{
|
|
if(props.list.length>0){
|
|
setItemPosition()
|
|
}
|
|
|
|
})
|
|
},{immediate: true})
|
|
// watch(()=>props.showMark,(val)=>{
|
|
// let elArr = dataDom.generalDragDom.children
|
|
// collItemSize.elList.forEach((item:any)=>{
|
|
// if(val){
|
|
// item.sort --
|
|
// }else{
|
|
// console.log(item);
|
|
// item.sort ++
|
|
// }
|
|
// })
|
|
// if(val){
|
|
// // collItemSize.elList.unshift({
|
|
// // el: elArr[0],
|
|
// // sort: collItemSize.elList.length,
|
|
// // index: -1,
|
|
// // id:-1,
|
|
// // });
|
|
// }else{
|
|
// // let index = collItemSize.elList.findIndex((item:any)=>item.id == -1)
|
|
// // if(index>=0)collItemSize.elList.splice(index,1)
|
|
// }
|
|
// console.log(collItemSize.elList)
|
|
// moveItem()
|
|
// })
|
|
const gifPlay = (e:any,item:any)=>{
|
|
if(!props.isVideo)return
|
|
e.target.src = item.gifUrl//使用gif图片
|
|
// e.target.src = ''//使用gif图片
|
|
}
|
|
const gifPause = (e:any,item:any)=>{
|
|
if(!props.isVideo)return
|
|
e.target.src = item.url//静态图片
|
|
// e.target.src = ''//静态图片
|
|
}
|
|
const down = async (item:any)=>{
|
|
const videoUrl = item.videoUrl; // 视频文件 URL
|
|
const response = await fetch(videoUrl);
|
|
const blob = await response.blob();
|
|
const blobUrl = URL.createObjectURL(blob);
|
|
|
|
const a = document.createElement('a');
|
|
a.href = blobUrl;
|
|
a.download = 'video.mp4';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
|
|
// 清理
|
|
setTimeout(() => {
|
|
document.body.removeChild(a);
|
|
URL.revokeObjectURL(blobUrl);
|
|
}, 100);
|
|
}
|
|
onMounted(()=>{
|
|
data.observerData.observer = new ResizeObserver(entries => {
|
|
for (let entry of entries) {
|
|
clearTimeout(data.observerData.time)
|
|
data.observerData.time = setTimeout(()=>{
|
|
nextTick(()=>{
|
|
collItemSize.num = 2
|
|
// if(dataDom.generalDragDom.offsetWidth > 900){
|
|
// collItemSize.num = 3
|
|
// }else{
|
|
// collItemSize.num = 2
|
|
// }
|
|
let width = (dataDom.generalDragDom.offsetWidth - collItemSize.padding) / collItemSize.num
|
|
collItemSize.likeStyle.width = width + 'px'
|
|
collItemSize.likeStyle.height = width * 1.54 + 'px'
|
|
setItemPosition()
|
|
})
|
|
},100)
|
|
// const { width } = entry.contentRect;
|
|
}
|
|
});
|
|
data.observerData.observer.observe(dataDom.generalDragDom);
|
|
})
|
|
onBeforeUnmount(()=>{
|
|
data.observerData.observer.unobserve(dataDom.generalDragDom);
|
|
})
|
|
return{
|
|
...toRefs(dataDom),
|
|
...toRefs(data),
|
|
...toRefs(collItemSize),
|
|
setItemPosition,
|
|
getMousePosition,
|
|
designMousedown,
|
|
gifPlay,
|
|
gifPause,
|
|
down,
|
|
}
|
|
},
|
|
provide() {
|
|
return {
|
|
}
|
|
},
|
|
})
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.generalDrag{
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
> .item{
|
|
// border-radius: 2rem;
|
|
// border: 2px solid;
|
|
position: absolute;
|
|
transition: all .3s;
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
// background: #fff;
|
|
> img{
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
&.video{
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
> .btn{
|
|
position: absolute;
|
|
top: 1rem;
|
|
cursor: pointer;
|
|
right: 2rem;
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
background: rgba(255,255,255,.5);
|
|
> div{
|
|
padding: .8rem;
|
|
&:hover{
|
|
background: rgba(255,255,255,.7);
|
|
}
|
|
}
|
|
.like{
|
|
}
|
|
.zoom{
|
|
i{
|
|
font-size: 2.5rem;
|
|
}
|
|
}
|
|
.down{
|
|
}
|
|
.delete{
|
|
}
|
|
i{
|
|
display: flex;
|
|
font-size: 3rem;
|
|
&.srLike{
|
|
color: red;
|
|
}
|
|
}
|
|
}
|
|
&:hover{
|
|
> .btn{
|
|
display: flex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |