效果图
<template><view v-if="info" class="all"><video:src="info.videoUrl"class="video" id="video" :controls="true" object-fit="fill" :show-fullscreen-btn="false"play-btn-position="center":autoplay="true" @loadedmetadata="loadedMetadata"></video><view class="slider"><view class="thumb-left" @touchmove="e=>handleTouchMove(e,0)" @touchend="e=>handleTouchEnd(e,0)":style="` margin-left: ${thumbLeft}px;`">{{ start }}</view><view class="slider-bg"></view><view class="thumb-right" @touchmove="e=>handleTouchMove(e,1)" @touchend="e=>handleTouchEnd(e,1)":style="` margin-right: ${thumbRight}px;`">{{ end }}</view></view></view></template><script lang="ts" setup>
const videoInfo = defineProps(["info"])
const emit = defineEmits(['onChange'])
import {ref, computed, onMounted, getCurrentInstance} from "vue";
import {onReady,
} from "@dcloudio/uni-app"const min = ref(0)
const max = ref(0)
const minInterval = ref(15)//最小裁剪间隔
const thumbLeft = ref(0)
const thumbRight = ref(0)
const start = ref(computed(() => {return Math.round((thumbLeft.value) * rate.value)
}))
const end = ref(computed(() => {return Math.round((totalWidth.value - thumbRight.value) * rate.value)
}))const rate = ref(computed(() => {return max.value / totalWidth.value
}))
const interval = ref(computed(() => {return minInterval.value / rate.value
}))const instance = getCurrentInstance()
const thumbLeftSize = ref({width: 0,height: 0,left: 0,right: 0
})
const thumbRightSize = ref({width: 0,height: 0,left: 0,right: 0
})
let dxLeft = 0
let dxRight = 0
const totalWidth = ref(0)
const videoTotalDuration = ref(0)
let videoContext: UniApp.VideoContext = null
let windowWidth = 0
let timer: number = nullfunction loadedMetadata(e) {max.value = Math.floor(e.detail.duration)emit('onChange', {start: start.value, end: end.value})
}onReady(() => {videoContext = uni.createVideoContext('video', instance);windowWidth = uni.getSystemInfoSync().windowWidth
})
onMounted(() => {uni.createSelectorQuery().in(instance).select('.thumb-left').boundingClientRect(data => {console.log(data)thumbLeftSize.value = dataconsole.log(thumbLeftSize.value)}).exec();uni.createSelectorQuery().in(instance).select('.thumb-right').boundingClientRect(data => {console.log(data)thumbRightSize.value = dataconsole.log(thumbRightSize.value)totalWidth.value = thumbRightSize.value.right - thumbLeftSize.value.left - 2 * thumbLeftSize.value.width}).exec();
});function handleTouchMove(e, index: Number) {let pageX = e.touches[0].pageXif (index == 0) {//左边边viewdxLeft = Math.max(pageX - thumbLeftSize.value.left, 0)//修正if (dxLeft + dxRight + interval.value > totalWidth.value) {dxLeft = totalWidth.value - dxRight}console.log("pageX:" + pageX, "dxRight:" + dxRight, "dxLeft:" + dxLeft, "thumbRight:" + thumbRight.value, "thumbLeft:" + thumbLeft.value, "width:" + thumbLeftSize.value.width, "windowWidth:" + windowWidth, thumbRightSize.value.right, "totalWidth:" + totalWidth.value)if (dxLeft <= interval.value) {//左边边界thumbLeft.value = 0return}if (dxRight + dxLeft + interval.value > totalWidth.value) {thumbLeft.value = windowWidth - thumbRight.value - 2 * thumbLeftSize.value.width - 2 * thumbLeftSize.value.left - interval.value} else {thumbLeft.value = dxLeft - interval.value}} else {//右边viewdxRight = Math.max(windowWidth - pageX - thumbRightSize.value.width, 0)//修正if (dxRight + dxLeft + interval.value > totalWidth.value) {dxRight = totalWidth.value - dxLeft}console.log("pageX:" + pageX, "dxRight:" + dxRight, "dxLeft:" + dxLeft, "thumbRight:" + thumbRight.value, "thumbLeft:" + thumbLeft.value, "width:" + thumbLeftSize.value.width, "windowWidth:" + windowWidth, thumbRightSize.value.right, "totalWidth:" + totalWidth.value)if (dxRight <= interval.value) {//右边边界thumbRight.value = 0return}if (dxRight + dxLeft + interval.value > totalWidth.value) {//左边边界修正thumbRight.value = windowWidth - thumbLeft.value - 2 * thumbLeftSize.value.width - 2 * thumbLeftSize.value.left - interval.value} else {thumbRight.value = dxRight - interval.value}}}function handleTouchEnd(e, index: Number) {emit('onChange', {start: start.value, end: end.value})videoContext.seek(index == 0 ? start.value : end.value);videoContext.play();
}
</script><style lang="scss" scoped>
.all {margin-left: 25rpx;margin-right: 25rpx;.video {height: 400rpx;width: 100%;}.slider {display: flex;color: white;flex-direction: row;height: 100rpx;.thumb-left {width: 50rpx;height: 100%;color: black;display: flex;font-size: 12rpx;align-items: center;justify-content: center;background-color: #8EFB7C;border-top-left-radius: 20rpx;border-bottom-left-radius: 20rpx;}.slider-bg {display: flex;flex: 1;background-color: #F1FFF0}.thumb-right {width: 50rpx;height: 100%;color: black;display: flex;font-size: 12rpx;align-items: center;justify-content: center;background-color: #8EFB7C;border-top-right-radius: 20rpx;border-bottom-right-radius: 20rpx;}}
}</style>