@TOC
H5实现时间揍拖动
实现双击文件列表的项添加到时间揍的最后一条。
时间轴里可以左右拖动位置。
主要代码:
/*** 时间轴拖动结束* @param $event* @constructor*/
const lineDragEnd = ( $event ) => {console.log( '时间轴拖动结束' , $event )console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)lineList.value[moveIndex].left+=$event.pageX - moveStartPosition.value.xmoveStartPosition.value.x = 0moveStartPosition.value.y = 0moveIndex = ''
}
计算拖动距离给项设置左边距实现
全部代码
index.vue
<template>{{ moveStartPosition }}<p>文件列表</p><div class="file-list"><div class="file" v-for="(file,index) in fileList"draggable="true"@dragstart="fileDragStart($event,file)"@dragend="fileDragEnd($event,file)"@dblclick="appendFile(file)":key="'file'+index">{{ file.name }}</div></div><div>时间轴{{ moveIn }}</div><div class="line-list" :class="{'line-in':lineIn}"@dragenter="lineDragEnter"@dragleave="lineDragLeave"@dragover="lineDragOver"@drop="lineDropFile"><transition-group name="list"><div class="line" v-for="(line,index) in lineList":key="'line'+line.key":style="style(line)":title="line.name"@dragstart="lineDragStart($event,index)"@dragend="lineDragEnd":draggable="lineDraggable"@dragenter="lineItemDragEnter($event,index)"@dragleave="lineItemDragLeave"@dragover="lineItemDragMove"@drop.stop="lineItemDropFile(index)">{{ line.name }}</div></transition-group></div><!-- 隐藏对象--><div class="hidden"><div id="move" ref="moveBlock">{{ nowFile.name }}</div></div>
</template><script setup>
import { randColor } from '@/utils/color.js'
import { uuid } from '@/utils/key.js'
import { ref } from 'vue'
const fileList = ref( [{ name: '视频1.mp4' , type: 'video' , duration: 10 } ,{ name: '音频2.mp4' , type: 'audio' , duration: 60 } ,{ name: '视频3.mp4' , type: 'video' , duration: 70 } ,{ name: '音频4.mp4' , type: 'audio' , duration: 80 } ,
] )
const lineList = ref( [] )
const moveBlock = ref( null )
const nowFile = ref( { name: '' } )
const lineIn = ref( false )
const moveStartPosition = ref({x:0,y:0})
let dragType = 'create'
let moveIndex = ''
let moveIn = ''
const style = ( file ) => {return {background: file.color ,width: file.duration * 5 + 'px','margin-left':file.left + 'px'}
}const appendFile = (item)=> {console.log('双击添加',item)let color = randColor()let file = {key: uuid() ,name: item.name ,type: item.type ,duration: item.duration ,left:0,color: color}console.log( 'file' , file )lineList.value.push( file )
}/*** 文件列表拖拽开始* @param $event* @param file*/
const fileDragStart = ( $event , file ) => {console.log( '文件列表拖拽开始' , $event , file )dragType = 'create'nowFile.value = filelet width = nowFile.value.duration * 2moveBlock.value.style.width = (width > 270 ? 270 : width) + 'px'$event.dataTransfer.setDragImage( moveBlock.value , 0 , 0 )
}/*** 文件列表拖拽结束* @param $event* @param file*/
const fileDragEnd = ( $event , file ) => {console.log( '文件列表拖拽结束' , $event , file )lineIn.value = false
}/*** 时间轴进入* @param $event* @constructor*/
const lineDragEnter = ( $event ) => {console.log( '时间列表进入' , $event )$event.preventDefault(); //阻止默认事件lineIn.value = true
}
/*** 时间轴离开* @param $event* @param file* @constructor*/
const lineDragLeave = ( $event , file ) => {console.log( '时间列表离开' , $event )$event.preventDefault(); //阻止默认事件lineIn.value = false
}/*** 时间轴阻止默认* @param $event* @constructor*/
const lineDragOver = ( $event ) => {$event.preventDefault(); //阻止默认事件
}/*** 时间轴放入* @param $event*/
const lineDropFile = ( $event ) => {console.log( '时间列表放入' ,dragType, $event )// 放在空的地方if ( dragType === 'create' ) {let color = randColor()let file = {key: uuid() ,name: nowFile.value.name ,type: nowFile.value.type ,duration: nowFile.value.duration ,left:0,color: color}console.log( 'file' , file )lineList.value.push( file )}
}/*** 时间轴拖动开始* @param $event* @param index*/
const lineDragStart = ( $event , index ) => {console.log( '时间轴拖动开始' , $event )dragType = 'move'moveIndex = indexmoveStartPosition.value.x = $event.pageXmoveStartPosition.value.y = $event.pageY
}const lineItemDragMove = ($event) => {console.log("拖拽移动",$event)console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)
}
/*** 时间轴拖动结束* @param $event* @constructor*/
const lineDragEnd = ( $event ) => {console.log( '时间轴拖动结束' , $event )console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)lineList.value[moveIndex].left+=$event.pageX - moveStartPosition.value.xmoveStartPosition.value.x = 0moveStartPosition.value.y = 0moveIndex = ''
}/*** 时间轴内容进入* @param $event* @constructor*/
const lineItemDragEnter = ( $event,index ) => {console.log( '时间轴进入' , $event )$event.preventDefault(); //阻止默认事件moveIn = index
}
/*** 时间轴内容离开* @param $event* @constructor*/
const lineItemDragLeave = ( $event ) => {console.log( '时间轴离开' , $event )$event.preventDefault(); //阻止默认事件moveIn = ''
}/*** 时间轴放入* @param index*/
const lineItemDropFile = ( index ) => {console.log( '时间轴放入' , index )// 放在某个轴上if ( dragType === 'create' ) {let color = randColor()let file = {key: uuid() ,name: nowFile.value.name ,type: nowFile.value.type ,left:0,duration: nowFile.value.duration ,color: color}console.log( 'file' , file )lineList.value.splice(index,0,file)}// 移动if ( dragType === 'move' ) {console.log( '移动' ,moveIndex,index)let list = lineList.valueif(moveIndex > index){const item = lineList.value[moveIndex]list.splice(moveIndex,1)list.splice(index,0,item)}else{const item = lineList.value[moveIndex]console.log('移动',item,list)list.splice(moveIndex,1)list.splice(index,0,item)console.log("移动到后面",list)}lineList.value = list}
}const lineDraggable = ref(true)</script><style lang="less" scoped>
.hidden {position: fixed;left: 0;top: -100px;#move {min-width: 20px;height: 20px;background: red;border: 1px solid #07b3c9;overflow: hidden;}
}.line-list {height: 200px;overflow-y: auto;.line {user-select: none;overflow: hidden;height: 20px;white-space: nowrap; /*不显示的地方用省略号...代替*/text-overflow: ellipsis; /* 支持 IE */.move{display: inline-block;cursor: move;}}
}.line-in {background: #999;
}.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {transition: all 0.5s ease;
}.list-enter-from,
.list-leave-to {opacity: 0;transform: translateX(30px);
}/* 确保将离开的元素从布局流中删除以便能够正确地计算移动的动画。 */
.list-leave-active {position: absolute;
}
</style>