123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- <template>
- <view class="SlideBody" ref="slide">
- <div class="Slide-progress">
- <div
- class="Slide-progress-loaded"
- :style="{ width: `${leftWidth}px` }"
- />
- </div>
- <div
- class="Slide-control"
- :style="{ left:`${leftWidth}px` }"
- @touchmove.stop.prevent="controlMove"
- @touchstart="controlTouchStart"
- @touchend="controlTouchEnd"
- >
- {{ playTime | mediaTimeFormatter }} / {{ allTime | mediaTimeFormatter }}
- </div>
- </view>
- </template>
- <script>
- export default {
- props: {
- ratio: {
- type: Number,
- default: 1
- },
- direction: {
- type: String,
- default: 'clientX'
- },
- iosDirection: {
- type: Number,
- default: 1
- },
- allTime: {
- type: Number,
- default: 0
- },
- playTime: {
- type: Number,
- default: 0
- }
- },
- data() {
- return {
- oldToucesX: 0,
- leftWidth: 0,
- oldLeftWidth: 0,
- currentWidth: 0,
- controlWidth: 0
- }
- },
- mounted() {
- this.init()
- },
- filters: {
- mediaTimeFormatter: num => {
- if (!num) return "00:00";
- num = Math.floor(num);
- let hour = Math.floor(num / 3600);
- let minutes = Math.floor((num - hour * 3600) / 60);
- let second = num - hour * 3600 - minutes * 60;
- if (hour > 0) {
- return `${hour > 9 ? hour : "0" + hour}:${
- minutes > 9 ? minutes : "0" + minutes
- }:${second > 9 ? second : "0" + second}`;
- } else {
- return `${minutes > 9 ? minutes : "0" + minutes}:${
- second > 9 ? second : "0" + second
- }`;
- }
- }
- },
- watch: {
- playTime: {
- handler(a) {
- if(a && this.allTime) {
- if(this.currentWidth && this.controlWidth) {
- let maxLeftWidth = this.currentWidth - this.controlWidth
- this.leftWidth = Math.ceil((a / this.allTime) * maxLeftWidth)
- } else {
- this.init(() => {
- let maxLeftWidth = this.currentWidth - this.controlWidth
- this.leftWidth = Math.ceil((a / this.allTime) * maxLeftWidth)
- })
- }
- } else {
- this.leftWidth = 0
- }
- },
- immediate: true
- },
- allTime: {
- handler(a) {
- if(a && this.playTime) {
- if(this.currentWidth && this.controlWidth) {
- let maxLeftWidth = this.currentWidth - this.controlWidth
- this.leftWidth = Math.ceil((this.playTime / a) * maxLeftWidth)
- } else {
- this.init(() => {
- let maxLeftWidth = this.currentWidth - this.controlWidth
- this.leftWidth = Math.ceil((this.playTime / a) * maxLeftWidth)
- })
- }
- } else {
- this.leftWidth = 0
- }
- },
- immediate: true
- }
- },
- methods: {
- init(cb) {
- const query = uni.createSelectorQuery().in(this);
- query.select('.SlideBody').boundingClientRect(({ width }) => {
- this.currentWidth = width
- }).exec();
- query.select('.Slide-control').boundingClientRect(({ width }) => {
- this.controlWidth = width
- }).exec();
- setTimeout(() => {
- cb && cb()
- }, 200)
- },
- controlTouchStart(e) {
- this.oldLeftWidth = this.leftWidth
- this.oldToucesX = e.changedTouches[0][this.direction];
- this.$emit('touchStart')
- },
- controlMove(e) {
- let newToucesX;
- let maxLeftWidth = this.currentWidth - this.controlWidth
- newToucesX= e.changedTouches[0][this.direction];
- this.leftWidth = this.iosDirection*(newToucesX - this.oldToucesX)+ this.oldLeftWidth
- this.leftWidth = this.leftWidth > maxLeftWidth ? maxLeftWidth : this.leftWidth
- this.leftWidth = this.leftWidth < 0? 0 : this.leftWidth
- },
- controlTouchEnd(e) {
- let maxLeftWidth = this.currentWidth - this.controlWidth
- let current = this.leftWidth / maxLeftWidth
- let value = current * this.allTime
- this.$emit('update:progress', { value })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .SlideBody {
- width: 100%;
- height: 34rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
- -webkit-overflow-scrolling : touch;
- .Slide {
- &-progress {
- width: 100%;
- height: 8rpx;
- border-radius: 8rpx;
- background: #EEEEEE;
- position: relative;
- overflow: hidden;
- &-loaded{
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- width: 0;
- height: 100%;
- background: linear-gradient(to right, #F97C55, #F44545);
- }
- }
- &-control {
- height: 34rpx;
- border-radius: 34rpx;
- background: linear-gradient(to right, #F97C55, #F44545);
- color: #FFFFFF;
- font-size: 24rpx;
- padding: 0 12rpx;
- line-height: 34rpx;
- position: absolute;
- top: 50%;
- left: 0;
- transform: translate(0, -50%);
- }
- }
- }
- </style>
|