Files
aida_front/src/component/modules/generalDrag.vue
X1627315083 4b694236ee 页面调整
2025-07-19 14:04:48 +08:00

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>