【JavaScript】列表拖拽升级,支持双击添加和时间轴左右拖动

@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.x
    moveStartPosition.value.x = 0
    moveStartPosition.value.y = 0
    moveIndex = ''
}

计算拖动距离给项设置左边距实现
全部代码
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 = file
    let width = nowFile.value.duration * 2
    moveBlock.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 = index
    moveStartPosition.value.x = $event.pageX
    moveStartPosition.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.x
    moveStartPosition.value.x = 0
    moveStartPosition.value.y = 0
    moveIndex = ''
}


/**
 * 时间轴内容进入
 * @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.value
        if(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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值