使用拖拽插件啊 draggabilly
<template>
<div class="timeline-container overflow-hidden relative" ref="timelineContainer">
<div class="relative">
<div class="absolute slider left-0 top-0 z-20" ref="slider">
<div class="absolute slider-bar bg-white cursor-mover text-black">{{sliderTime}}</div>
</div>
<div class="timeline z-10" ref="timeline">
<ul class="time-minutes flex h-4 cursor-pointer" @click.stop="timelineClick">
<li
v-for="n in (dayMinutes)"
:key="n"
:data-move="n"
class="minutes border-t border-b border-color"
></li>
</ul>
<ul class="time-hours flex">
<li
class="hour border-r border-color"
:class="n===1?'border-l':''"
v-for="n in dayHours"
:key="n"
>{{(n-1)/2}}</li>
</ul>
</div>
</div>
</div>
</template>
<script>
import Draggabilly from 'draggabilly'
let draggie = null
export default {
name: 'timeline',
props: {
moveX: {
required: true,
default() {
return 0
}
}
},
data() {
return {
dayMinutes: 5 * 6,
dayHours: 10,
transformX: 0,
sliderX: 0,
pxLength: 80 // 80px--------0.5km
}
},
computed: {
sliderTime() {
const { transformX, sliderX } = this
const xPlace = sliderX - transformX
console.log({ transformX, sliderX, xPlace })
const showTime = xPlace / (this.pxLength * 2)
return showTime
}
},
watch: {
moveX: {
handler(newVal) {
console.log({ newVal })
if (!draggie) {
this.$nextTick(() => {
this.setXPlace(newVal)
})
} else {
this.setXPlace(newVal)
}
},
immediate: true
}
},
mounted() {
this.init()
},
methods: {
init() {
this.sliderMove()
},
sliderMove() {
draggie = new Draggabilly('.slider', {
axis: 'x',
containment: '.timeline-container',
handle: '.slider-bar'
})
this.setXPlace(this.moveX)
// vanilla JS
draggie.on('dragEnd', () => {
const position = draggie.position
const { x } = position
// this.sliderX =x
console.log({ position })
this.setXPlace(x)
this.$emit('sliderMove', this.sliderTime)
})
this.$once('hook:beforeDestroy', function () {
draggie.destroy()
})
},
// addZero(num) {
// if (num < 10) {
// return `0${num}`
// } else {
// return num
// }
// },
timelineClick(event) {
const dataMove = event.target.getAttribute('data-move')
// 每个值代表5px
const sliderX = dataMove * 16
console.log({ sliderX })
// this.sliderX = sliderX
this.setXPlace(sliderX)
// 通知父组件移动到哪里了
this.$emit('sliderMove', this.sliderTime)
},
setXPlace(x) {
let int = 0
const minScale = this.pxLength * 1 / 5 // 最小距离0.1km
if (x < (minScale / 2)) {
int = 0
} else if (x > 480) {
int = 480
} else {
if (x % minScale) {
int = parseInt((parseInt(x / minScale) + 1) * minScale)
} else {
int = (parseInt(x / minScale) * minScale)
}
}
this.sliderX = int
draggie.setPosition(int, 0)
}
}
}
</script>
<style lang="scss">
.timeline-container {
padding: 0 10px;
.timeline {
width: 1440px;
height: 60px;
transition: all ease-in-out 0.1s;
user-select: none;
}
.minutes {
/* width: 5px; */
width: 16px;
}
.hour {
/* width: 60px; */
width: 80px;
}
.slider {
height: 40px;
width: 2px;
background-color: #815200;
text-align: center;
}
.slider-bar {
padding: 0 5px;
width: 40px;
left: -20px;
top: 40px;
border: 1px solid #ffa200;
height: 20px;
line-height: 20px;
border-radius: 4px;
cursor: move;
background-color: #fff;
user-select: none;
}
.border-color {
border-color: #116aba;
}
}
</style>