我的订单+我的
This commit is contained in:
307
components/player/CustomSlider.nvue
Normal file
307
components/player/CustomSlider.nvue
Normal file
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<view class="custom-slider">
|
||||
<image
|
||||
v-if="minIcon"
|
||||
class="icon"
|
||||
:src="minIcon"></image>
|
||||
<view
|
||||
ref="slider"
|
||||
class="slider"
|
||||
@touchstart.stop="onTouchStart"
|
||||
@touchmove.stop="onTouchMove"
|
||||
@touchend.stop="onTouchEnd">
|
||||
<view class="bar">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view
|
||||
class="active-bar-wrapper">
|
||||
<view
|
||||
class="active-bar"
|
||||
:style="{flex: presentShow}"></view>
|
||||
</view>
|
||||
<view v-if="step !== 1" class="steps-wrapper">
|
||||
<template v-for="(step, index) in steps">
|
||||
<view v-if="index" class="step"></view>
|
||||
<view class="holder-bar"></view>
|
||||
</template>
|
||||
</view>
|
||||
<view
|
||||
class="dot-wrapper">
|
||||
<view
|
||||
class="holder-bar"
|
||||
:style="{flex: presentShow}"></view>
|
||||
<view class="dot"></view>
|
||||
</view>
|
||||
<view class="know-area">
|
||||
<slot name="know"></slot>
|
||||
</view>
|
||||
</view>
|
||||
<image
|
||||
v-if="maxIcon"
|
||||
class="icon"
|
||||
:src="maxIcon"></image>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// 注意平台差异
|
||||
// #ifdef APP-NVUE
|
||||
const dom = weex.requireModule('dom')
|
||||
// #endif
|
||||
import { range, addNumber } from '@/utils/formate.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dragStatus: '',
|
||||
size: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
currentValue: 0
|
||||
}
|
||||
},
|
||||
props: {
|
||||
disabled: Boolean,
|
||||
vertical: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
barHeight: [Number, String],
|
||||
buttonSize: [Number, String],
|
||||
activeColor: String,
|
||||
inactiveColor: String,
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
minIcon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
maxIcon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
isDOMShow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scope() {
|
||||
return this.max - this.min;
|
||||
},
|
||||
presentShow () {
|
||||
return (this.currentValue - this.min) / this.scope;
|
||||
},
|
||||
steps () {
|
||||
return this.scope / this.step
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isDOMShow (value) {
|
||||
this.getSliderSize();
|
||||
},
|
||||
value (val) {
|
||||
this.currentValue = val;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 同步初始值
|
||||
this.currentValue = this.value;
|
||||
},
|
||||
mounted () {
|
||||
this.getSliderSize();
|
||||
},
|
||||
methods: {
|
||||
touchStart(event) {
|
||||
this.resetTouchStatus();
|
||||
this.startX = event.touches[0].screenX;
|
||||
this.startY = event.touches[0].screenY;
|
||||
},
|
||||
touchMove(event) {
|
||||
const touch = event.touches[0];
|
||||
// safari back will set clientX to negative number
|
||||
this.deltaX = touch.screenX < 0 ? 0 : touch.screenX - this.startX;
|
||||
this.deltaY = touch.screenY - this.startY;
|
||||
this.offsetX = Math.abs(this.deltaX);
|
||||
this.offsetY = Math.abs(this.deltaY);
|
||||
// lock direction when distance is greater than a certain value
|
||||
const LOCK_DIRECTION_DISTANCE = 10;
|
||||
if (
|
||||
!this.direction ||
|
||||
(this.offsetX < LOCK_DIRECTION_DISTANCE &&
|
||||
this.offsetY < LOCK_DIRECTION_DISTANCE)
|
||||
) {
|
||||
this.direction = this.getDirection(this.offsetX, this.offsetY);
|
||||
}
|
||||
},
|
||||
resetTouchStatus() {
|
||||
this.direction = '';
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
},
|
||||
getDirection (x, y) {
|
||||
if (x > y) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
onTouchStart(event) {
|
||||
console.log('start')
|
||||
this.touchStart(event);
|
||||
this.startValue = this.format(this.currentValue);
|
||||
this.dragStatus = 'start';
|
||||
this.$emit('dragStart');
|
||||
},
|
||||
onTouchMove(event) {
|
||||
this.touchMove(event);
|
||||
const rect = this.size;
|
||||
const delta = this.vertical ? this.deltaY : this.deltaX;
|
||||
const total = this.vertical ? rect.height : rect.width;
|
||||
const diff = (delta / total) * this.scope;
|
||||
// console.log('move', delta);
|
||||
if (delta === 0) return;
|
||||
this.dragStatus = 'draging';
|
||||
this.currentValue = this.startValue + diff;
|
||||
this.updateValue(this.currentValue, true);
|
||||
},
|
||||
onTouchEnd(event) {
|
||||
console.log('end')
|
||||
if(this.dragStatus === 'draging') {
|
||||
this.updateValue(this.currentValue, true);
|
||||
return;
|
||||
}
|
||||
if (this.dragStatus === 'start') {
|
||||
this.onClick(event);
|
||||
};
|
||||
},
|
||||
onClick(event) {
|
||||
if (this.disabled) return;
|
||||
const rect = this.size;
|
||||
const delta = this.vertical
|
||||
? event.changedTouches[0].screenY - rect.top
|
||||
: event.changedTouches[0].screenX - rect.left;
|
||||
const total = this.vertical ? rect.height : rect.width;
|
||||
let value = +this.min + (delta / total) * this.scope;
|
||||
// this.startValue = this.value;
|
||||
this.updateValue(value, true);
|
||||
},
|
||||
updateValue(value, end) {
|
||||
value = this.format(value);
|
||||
this.currentValue = value;
|
||||
this.$emit('changing', value);
|
||||
if (end) {
|
||||
this.$emit('change', value);
|
||||
}
|
||||
},
|
||||
format(value) {
|
||||
const min = +this.min;
|
||||
const max = +this.max;
|
||||
const step = +this.step;
|
||||
value = range(value, min, max);
|
||||
const diff = parseInt((value - min) / step) * step;
|
||||
return addNumber(min, diff);
|
||||
},
|
||||
isSameValue(newValue, oldValue) {
|
||||
return JSON.stringify(newValue) === JSON.stringify(oldValue);
|
||||
},
|
||||
getSliderSize () {
|
||||
setTimeout(()=> {
|
||||
const result = dom.getComponentRect(this.$refs.slider, option => {
|
||||
this.size = option.size;
|
||||
})
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.custom-slider
|
||||
flex-direction row
|
||||
align-items center
|
||||
justify-content center
|
||||
.icon
|
||||
width 40rpx
|
||||
height 40rpx
|
||||
.slider
|
||||
position relative
|
||||
margin 0 15rpx
|
||||
height 78rpx
|
||||
flex-direction row
|
||||
align-items center
|
||||
flex 1
|
||||
.bar
|
||||
flex 1
|
||||
flex-direction row
|
||||
height 6rpx
|
||||
background-color rgba(153, 153, 153, 0.4)
|
||||
.active-bar-wrapper
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
bottom 0
|
||||
left 0
|
||||
flex-direction row
|
||||
align-items center
|
||||
.active-bar
|
||||
height 6rpx
|
||||
background-color #FF920A
|
||||
.steps-wrapper
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
bottom 0
|
||||
left 0
|
||||
flex-direction row
|
||||
align-items center
|
||||
.step
|
||||
width 6rpx
|
||||
height 6rpx
|
||||
background-color #FFFFFF
|
||||
.holder-bar
|
||||
flex 1
|
||||
height: 6rpx
|
||||
.dot-wrapper
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
bottom 0
|
||||
left 0
|
||||
flex-direction row
|
||||
align-items center
|
||||
.holder-bar
|
||||
height 6rpx
|
||||
.dot
|
||||
width 28rpx
|
||||
height 28rpx
|
||||
background-color #FFFFFF
|
||||
border-radius 100%
|
||||
.know-area
|
||||
position absolute
|
||||
top 0
|
||||
right 0
|
||||
bottom 0
|
||||
left 0
|
||||
</style>
|
||||
Reference in New Issue
Block a user