jiuyiUniapp/jiuyi2/components/index/videoProgress.vue

161 lines
3.1 KiB
Vue
Raw Normal View History

2024-12-18 15:46:27 +08:00
<script setup>
/**
* 视频进度条
*/
import {
ref,
2025-01-02 01:01:23 +08:00
computed,
2024-12-18 15:46:27 +08:00
defineEmits,
2025-01-02 01:01:23 +08:00
onMounted,
getCurrentInstance,
watch,
2024-12-18 15:46:27 +08:00
} from 'vue';
// 接收
const props = defineProps({
2025-01-02 01:01:23 +08:00
time: {
2024-12-18 15:46:27 +08:00
type: Object,
2025-01-02 01:01:23 +08:00
default: {
duration: 0,
currentTime: 0,
}
2024-12-18 15:46:27 +08:00
},
2025-01-02 01:01:23 +08:00
// 组件宽度
viewWidth: {
type: Number
}
})
watch(props.time, (nV, oV) => {
console.log('time', nV, oV)
}, {
deep: true,
2024-12-18 15:46:27 +08:00
})
// 触发
const emit = defineEmits(['change', 'end'])
2025-01-02 01:01:23 +08:00
//
const {
proxy
} = getCurrentInstance()
2024-12-18 15:46:27 +08:00
// 拖拽开关
const trigger = ref(false)
2025-01-02 01:01:23 +08:00
// 视频播放时间
const videoTime = ref(0)
// 视频进度
const videoProgress = ref(0)
// 视频当前
const videoCurrent = computed(() => {
let result = formatNum(props.time.currentTime)
if (trigger.value) result = videoTime.value
return result
})
// 进度条长度
const progress = computed(() => {
let result = 0
if (!trigger.value) {
const duration = formatNum(props.time.duration)
if (duration != 0) result = formatNum(props.time.currentTime) / duration * props.viewWidth
result = formatNum(result)
} else {
result = videoProgress.value
}
return result
})
// 格式化视频时长
const formatDuration = computed(() => {
let result = formatNum(props.time.duration).toFixed(2)
return result
})
// 格式化数字
function formatNum(num) {
let result = Number.parseFloat(num).toFixed(2)
return Number.parseFloat(result)
}
2024-12-18 15:46:27 +08:00
// 开始触摸
function onStart() {
2025-01-02 01:01:23 +08:00
trigger.value = true
2024-12-18 15:46:27 +08:00
}
// 触摸移动
function onMove(ev) {
2025-01-02 01:01:23 +08:00
// 横轴移动像素
const time = formatNum(ev.changedTouches[0].screenX)
// 当前进度
let target = formatNum(formatNum(time / props.viewWidth) * Number(formatDuration.value))
videoTime.value = target
videoProgress.value = time
2024-12-18 15:46:27 +08:00
}
// 移动结束
function onEnd(ev) {
2025-01-02 01:01:23 +08:00
trigger.value = false
// 视频播放时间
emit('change', {
time: videoTime.value,
})
2024-12-18 15:46:27 +08:00
}
</script>
<template>
2025-01-02 01:01:23 +08:00
<view class="timeBox fdr jcc" v-if="trigger">
<view class="time fdr jcc">
<text class="text f1">{{videoCurrent}}</text>
<text class="text">/</text>
<text class="text f1">{{formatDuration}}</text>
</view>
</view>
<view class="durationBox" ref="durationBoxRef" @touchstart.stop="onStart" @touchmove.stop="onMove"
@touchcancel="onEnd" @touchend.stop="onEnd">
<!-- <slider :min="0" :max="formatDuration" @change="change" /> -->
2024-12-18 15:46:27 +08:00
<view class="duration">
2025-01-02 01:01:23 +08:00
<view class="line" :style="{ width: progress + 'px' }"></view>
2024-12-18 15:46:27 +08:00
</view>
</view>
</template>
<style lang="scss" scoped>
2025-01-02 01:01:23 +08:00
.timeBox {
position: fixed;
left: 0;
right: 0;
bottom: 300rpx;
text-align: center;
z-index: 9;
.time {
width: 450rpx;
padding: 0 20rpx;
background-color: rgba(0, 0, 0, .6);
border-radius: 10rpx;
}
.text {
margin: 10rpx 20rpx;
font-size: 50rpx;
color: #fff;
}
}
2024-12-18 15:46:27 +08:00
// 视频时长
.durationBox {
padding-top: 60rpx;
// background-color: red;
// z-index: 10;
.duration {
width: 750rpx;
background-color: rgba(255, 255, 255, .3);
// 时间时长
.line {
width: 0;
height: 2rpx;
background-color: rgba(255, 255, 255, .8);
transition-duration: .25s;
}
}
}
</style>