869 lines
26 KiB
Vue
869 lines
26 KiB
Vue
<template>
|
||
<view class="bing-progress" :style="{width:bpWidth,height:bpHeight,borderRadius:borderRadius,
|
||
backgroundColor:backgroundColor,flexDirection:direction!='vertical'?'row':'column'}">
|
||
<!-- 进度 -->
|
||
<!-- #ifdef APP-NVUE -->
|
||
<div class="bp-bar_max"
|
||
:style="{width:barMaxWidth,height:barMaxHeight,backgroundColor:noActiveColor,
|
||
flexDirection:direction!='vertical'?'row':'column',left:barMaxLeft,borderRadius:barBorderRadius}">
|
||
<div class="bp-bar_sub_active"
|
||
:style="{width:barSubActiveWidth,height:barSubActiveHeight,backgroundColor:subActiveColor,
|
||
top:subActiveTop,bottom:subActiveBottom,left:subActiveLeft,right:subActiveRight,borderRadius:isActiveCircular?barBorderRadius:0}"></div>
|
||
<div class="bp-bar_active"
|
||
:style="{width:barActiveWidth,height:barActiveHeight,backgroundColor:activeColor,
|
||
top:activeTop,bottom:activeBottom,left:activeLeft,right:activeRight,borderRadius:isActiveCircular?barBorderRadius:0}"></div>
|
||
</div>
|
||
<!-- #endif -->
|
||
<!-- #ifndef APP-NVUE -->
|
||
<view class="bp-bar_max"
|
||
:style="{width:barMaxWidth,height:barMaxHeight,backgroundColor:noActiveColor,borderRadius:barBorderRadius,
|
||
flexDirection:direction!='vertical'?'row':'column',left:barMaxLeft}">
|
||
<view class="bp-bar_sub_active"
|
||
:style="{width:barSubActiveWidth,height:barSubActiveHeight,backgroundColor:subActiveColor,
|
||
top:subActiveTop,bottom:subActiveBottom,left:subActiveLeft,right:subActiveRight,borderRadius:isActiveCircular?barBorderRadius:0}"></view>
|
||
<view class="bp-bar_active"
|
||
:style="{width:barActiveWidth,height:barActiveHeight,backgroundColor:activeColor,
|
||
top:activeTop,bottom:activeBottom,left:activeLeft,right:activeRight,borderRadius:isActiveCircular?barBorderRadius:0}"></view>
|
||
</view>
|
||
<!-- #endif -->
|
||
<movable-area id="bp-marea" class="bp-marea" @touchmove.stop.prevent="touchmove" @touchstart.stop.prevent="touchstart" @touchcancel="touchend" @touchend="touchend"
|
||
:style="{width:mareaWidth,height:mareaHeight,left:mareaLeft}">
|
||
<!-- 拖柄 -->
|
||
<movable-view id="bp-mview" class="bp-mview" :direction="direction=='vertical'?'vertical':'horizontal'" :animation="false"
|
||
:disabled="true" :x="handleX" :y="handleY" friction="10" damping="100"
|
||
:style="{width:mhandleWidth,height:mhandleHeight,backgroundColor:handleColor,
|
||
borderRadius:handleBorderRadius,fontSize:infoFontSize,top:mhandleTop}">
|
||
<view id="bp-handle" class="bp-handle" :style="{fontSize:infoFontSize,width:mhandleWidth,height:mhandleHeight,borderRadius:handleBorderRadius}">
|
||
<image class="bp-handle-img" :src="handleImgUrl" v-if="handleImgUrl"
|
||
:style="{fontSize:infoFontSize,width:mhandleWidth,height:mhandleHeight,borderRadius:handleBorderRadius}"></image>
|
||
<!-- 进度值 -->
|
||
<text class="bp-handle-text" v-if="handleImgUrl=='' && infoAlign=='handle' && showInfo"
|
||
:style="{fontSize:infoFontSize,color:infoColor,width:mhandleWidth,height:textHeight,borderRadius:'20px'}">{{ infoContent=='subValue'?msubValue:showValue }}{{ infoEndText }}</text>
|
||
<!-- 挂件 -->
|
||
<!-- #ifndef APP-NVUE -->
|
||
<!-- 图片挂件 -->
|
||
<image v-if="widgetPos=='top' && widgetUrl" class="bp-handle-widget" :src="widgetUrl" :style="{flexDirection: 'column',borderRadius:mwidgetBorderRadius, bottom: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}"></image>
|
||
<image v-if="widgetPos=='right' && widgetUrl" class="bp-handle-widget" :src="widgetUrl" :style="{flexDirection: 'row',borderRadius:mwidgetBorderRadius,left: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}"></image>
|
||
<image v-if="widgetPos=='bottom' && widgetUrl" class="bp-handle-widget" :src="widgetUrl" :style="{flexDirection: 'column',borderRadius:mwidgetBorderRadius,top: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}"></image>
|
||
<image v-if="widgetPos=='left' && widgetUrl" class="bp-handle-widget" :src="widgetUrl" :style="{flexDirection: 'row',borderRadius:mwidgetBorderRadius,right: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}"></image>
|
||
<!-- 自定义元素挂件 -->
|
||
<view v-if="widgetPos=='top' && widgetUrl==''" class="bp-handle-widget" :style="{flexDirection: 'column',borderRadius:mwidgetBorderRadius,bottom: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}">
|
||
<slot/>
|
||
</view>
|
||
<view v-if="widgetPos=='right' && widgetUrl==''" class="bp-handle-widget" :style="{flexDirection: 'row',borderRadius:mwidgetBorderRadius,left: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}">
|
||
<slot/>
|
||
</view>
|
||
<view v-if="widgetPos=='bottom' && widgetUrl==''" class="bp-handle-widget" :style="{flexDirection: 'column',borderRadius:mwidgetBorderRadius,top: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}">
|
||
<slot/>
|
||
</view>
|
||
<view v-if="widgetPos=='left' && widgetUrl==''" class="bp-handle-widget" :style="{flexDirection: 'row',borderRadius:mwidgetBorderRadius,right: moffset,width:mwidgetWidth,height:mwidgetHeight,opacity:widgetOpacity,transform: mwidgetAngle}">
|
||
<slot/>
|
||
</view>
|
||
<!-- #endif -->
|
||
</view>
|
||
</movable-view>
|
||
</movable-area>
|
||
<!-- 进度值 -->
|
||
<text class="bp-value" v-if="showValueState() || (infoAlign=='center'&&direction!='vertical' && showInfo)"
|
||
:style="{color:infoColor,fontSize:infoFontSize,left:valueLeft,width:valueWidth()+'px'}">{{ infoContent=='subValue'?msubValue:showValue }}{{ infoEndText }}</text>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
/**
|
||
* 进度条,副进度条
|
||
*/
|
||
export default {
|
||
created() {
|
||
/**
|
||
* 获取系统屏幕信息,用于后续单位换算
|
||
*/
|
||
const systemInfo = uni.getSystemInfoSync()
|
||
this.px2rpx = 750 / systemInfo.screenWidth
|
||
this.screenWidth = systemInfo.screenWidth
|
||
this.screenHeight = systemInfo.screenHeight
|
||
},
|
||
mounted() {
|
||
// #ifndef APP-NVUE
|
||
/**
|
||
* 非NVUE movable-area 滑动事件获取到的位置是相对于文档的,获取组件位置,用于计算滑块位置
|
||
*/
|
||
this.updateRect()
|
||
// #endif
|
||
this.mmax = this.valueFormat(this.max,false)
|
||
this.percent = Math.abs((this.valueFormat(this.value) - this.min) / (this.mmax - this.min))
|
||
this.subPercent = Math.abs((this.valueFormat(this.subValue,true) - this.min) / (this.mmax - this.min))
|
||
if(this.reverse) {
|
||
if(this.direction!='vertical') {
|
||
this.handleX = (1 - this.percent) * this.barMaxLength
|
||
}
|
||
else {
|
||
this.handleY = this.percent * this.barMaxLength
|
||
}
|
||
}
|
||
else {
|
||
if(this.direction!='vertical') {
|
||
this.handleX = this.percent * this.barMaxLength
|
||
}
|
||
else {
|
||
this.handleY = (1 - this.percent) * this.barMaxLength
|
||
}
|
||
}
|
||
if(this.bpname=='test') {
|
||
console.log(this.mainInfo)
|
||
}
|
||
},
|
||
/**
|
||
* sub表示副进度条属性
|
||
*/
|
||
props: {
|
||
// 组件名字
|
||
bpname: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
width: {
|
||
type: String,
|
||
default: '300px'
|
||
},
|
||
strokeWidth: {
|
||
type: String,
|
||
default: '30px'
|
||
},
|
||
backgroundColor: {
|
||
type: String,
|
||
default: 'rgba(0,0,0,0)'
|
||
},
|
||
noActiveColor: {
|
||
type: String,
|
||
default: "#00ffff"
|
||
},
|
||
activeColor: {
|
||
type: String,
|
||
default: "#0000ff"
|
||
},
|
||
subActiveColor: {
|
||
type: String,
|
||
default: "#ffaaaa"
|
||
},
|
||
handleColor: {
|
||
type: String,
|
||
default: "#ffff00"
|
||
},
|
||
infoColor: {
|
||
type: String,
|
||
default: "#000000"
|
||
},
|
||
// 整个进度条的外边界圆角半径
|
||
borderRadius: {
|
||
type: String,
|
||
default: '5px'
|
||
},
|
||
// 进度条内部滑轨圆角半径
|
||
barBorderRadius: {
|
||
type: String,
|
||
default: '5px'
|
||
},
|
||
// active and subActive 是否显示圆角 NVUE默认true,其他默认false
|
||
// #ifdef APP-NVUE
|
||
isActiveCircular: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// #endif
|
||
// #ifndef APP-NVUE
|
||
isActiveCircular: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// #endif
|
||
handleWidth: {
|
||
type: String,
|
||
default: '50px'
|
||
},
|
||
handleHeight: {
|
||
type: String,
|
||
default: '40px'
|
||
},
|
||
handleBorderRadius: {
|
||
type: String,
|
||
default: '5px'
|
||
},
|
||
handleImgUrl: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
direction: {
|
||
type: String,
|
||
default: 'horizontal'
|
||
},
|
||
infoEndText: {
|
||
type: String,
|
||
default: ""
|
||
},
|
||
infoFontSize: {
|
||
type: String,
|
||
default: '18px'
|
||
},
|
||
showInfo: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// 进度值显示value还是subValue
|
||
infoContent: {
|
||
type: String,
|
||
default: 'value'
|
||
},
|
||
// 进度值显示位置 left, right, center, handle
|
||
infoAlign: {
|
||
type: String,
|
||
default: 'right'
|
||
},
|
||
max: {
|
||
type: Number,
|
||
default: 100
|
||
},
|
||
min: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
value: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
subValue: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
step: {
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
// 副进度条步长
|
||
subStep: {
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
// true连续滑动,false步进,即以step的间隔变化
|
||
continuous: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
// 副进度条continuous
|
||
subContinuous: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
reverse: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// 挂件位置 top, right, bottom, left
|
||
widgetPos: {
|
||
type: String,
|
||
default: "top"
|
||
},
|
||
widgetHeight: {
|
||
type: [String,Number],
|
||
default: '40px'
|
||
},
|
||
widgetWidth: {
|
||
type: [String,Number],
|
||
default: '50px'
|
||
},
|
||
widgetBorderRadius: {
|
||
type: [String,Number],
|
||
default: '5px'
|
||
},
|
||
// 挂件不透明度 0完全透明 1不透明
|
||
widgetOpacity: {
|
||
type: [String,Number],
|
||
default: 1
|
||
},
|
||
// 挂件距离组件的偏移量,正数原理组件,负数靠近组件
|
||
widgetOffset: {
|
||
type: [String,Number],
|
||
default: '0px'
|
||
},
|
||
// 挂件图片
|
||
widgetUrl: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
// 挂件旋转角度
|
||
widgetAngle: {
|
||
type: [String,Number],
|
||
default: 0
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
handleX: 50,
|
||
handleY: 0,
|
||
px2rpx: 1,
|
||
percent: 0, // 0-1
|
||
subPercent: 0, // 0-1
|
||
mainInfo: {
|
||
left: 0,
|
||
top: 0,
|
||
bottom: 0,
|
||
right: 0
|
||
},
|
||
touchState: false,
|
||
screenHeight: 0,
|
||
screenWidth: 0,
|
||
msubValue: 0,
|
||
moveable: true,
|
||
lastTouchTime: 0,
|
||
mmax: 100
|
||
}
|
||
},
|
||
watch: {
|
||
/**
|
||
* @param {Object} newValue
|
||
* @param {Object} oldValue
|
||
*/
|
||
value(newValue, oldValue) {
|
||
if(!this.touchState) {
|
||
newValue = this.valueSetBoundary(newValue)
|
||
this.percent = Math.abs((newValue - this.min) / (this.mmax - this.min))
|
||
}
|
||
},
|
||
showValue(newValue, oldValue) {
|
||
// 步进
|
||
if(!this.continuous) {
|
||
let percent
|
||
if(this.reverse) {
|
||
if(this.direction!='vertical') {
|
||
percent = Math.abs(1 - (newValue - this.min) / (this.mmax - this.min))
|
||
this.handleX = percent * this.barMaxLength
|
||
}
|
||
else {
|
||
percent = Math.abs((newValue - this.min) / (this.mmax - this.min))
|
||
this.handleY = percent * this.barMaxLength
|
||
}
|
||
}
|
||
else {
|
||
if(this.direction!='vertical') {
|
||
percent = Math.abs((newValue - this.min) / (this.mmax - this.min))
|
||
this.handleX = percent * this.barMaxLength
|
||
}
|
||
else {
|
||
percent = (1 - Math.abs((newValue - this.min) / (this.mmax - this.min)))
|
||
this.handleY = percent * this.barMaxLength
|
||
}
|
||
}
|
||
|
||
}
|
||
this.$emit("change", {bpname: this.bpname,type: 'change',value:this.showValue,subValue:this.msubValue})
|
||
this.$emit("valuechange", {bpname: this.bpname,type: 'valuechange',value:this.showValue,subValue:this.msubValue})
|
||
},
|
||
percent(newValue, oldValue) {
|
||
// 连续
|
||
if(this.continuous) {
|
||
if(this.reverse) {
|
||
if(this.direction!='vertical') {
|
||
this.handleX = (1 - newValue) * this.barMaxLength
|
||
}
|
||
else {
|
||
this.handleY = newValue * this.barMaxLength
|
||
}
|
||
}
|
||
else {
|
||
if(this.direction!='vertical') {
|
||
this.handleX = newValue * this.barMaxLength
|
||
}
|
||
else {
|
||
this.handleY = (1 - newValue) * this.barMaxLength
|
||
}
|
||
}
|
||
}
|
||
},
|
||
subValue(newValue, oldValue) {
|
||
newValue = this.valueSetBoundary(newValue)
|
||
|
||
if(this.subContinuous) {
|
||
this.msubValue = newValue
|
||
}
|
||
else {
|
||
this.msubValue = this.valueFormat(newValue, true)
|
||
}
|
||
this.subPercent = Math.abs((newValue - this.min) / (this.mmax - this.min))
|
||
this.$emit("change", {bpname: this.bpname,type: 'change',value:this.showValue,subValue:this.msubValue})
|
||
this.$emit("subvaluechange", {bpname: this.bpname,type: 'subvaluechange',value:this.showValue,subValue:this.msubValue})
|
||
|
||
},
|
||
max(newValue,oldValue) {
|
||
this.mmax = this.valueFormat(newValue,false)
|
||
}
|
||
},
|
||
computed: {
|
||
bpWidth() {
|
||
if(this.direction=="vertical") {
|
||
return this.maxHeight()[2]
|
||
}
|
||
return this.sizeDeal(this.width)[2]
|
||
},
|
||
bpHeight() {
|
||
if(this.direction=="vertical") {
|
||
return this.sizeDeal(this.width)[2]
|
||
}
|
||
return this.maxHeight()[2]
|
||
},
|
||
mareaWidth() {
|
||
if(this.direction=="vertical") {
|
||
return this.maxHeight()[2]
|
||
}
|
||
let width = this.sizeDeal(this.width)[0]
|
||
return (width - this.textWidth()) + 'px'
|
||
},
|
||
mareaHeight() {
|
||
if(this.direction=="vertical") {
|
||
let width = this.sizeDeal(this.width)[0]
|
||
return (width - this.textWidth()) + 'px'
|
||
}
|
||
return this.maxHeight()[2]
|
||
},
|
||
mareaLeft() {
|
||
if(this.showValueState()) {
|
||
if(this.infoAlign == 'left') {
|
||
return this.textWidth() + 'px'
|
||
}
|
||
}
|
||
return 0
|
||
},
|
||
barMaxHeight() {
|
||
if(this.direction=="vertical") {
|
||
let width = this.sizeDeal(this.width)[0]
|
||
let handleWidth = this.sizeDeal(this.handleWidth)
|
||
return (width - this.textWidth() - handleWidth[0]) + 'px'
|
||
}
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
},
|
||
barMaxWidth() {
|
||
if(this.direction=="vertical") {
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
}
|
||
let width = this.sizeDeal(this.width)[0]
|
||
let handleWidth = this.sizeDeal(this.handleWidth)
|
||
return (width - this.textWidth() - handleWidth[0]) + 'px'
|
||
},
|
||
barMaxLeft() {
|
||
if(this.showValueState()) {
|
||
if(this.infoAlign == 'left') {
|
||
return this.textWidth() + this.sizeDeal(this.handleWidth)[0] / 2 + 'px'
|
||
}
|
||
}
|
||
if(this.direction != 'vertical') {
|
||
return this.sizeDeal(this.handleWidth)[0] / 2 + 'px'
|
||
}
|
||
// vertical
|
||
return (this.maxHeight()[0] - this.sizeDeal(this.strokeWidth)[0]) / 2 + 'px'
|
||
|
||
},
|
||
activeRight() {
|
||
if(this.reverse) {
|
||
return 0
|
||
}
|
||
return 'unset'
|
||
},
|
||
activeLeft() {
|
||
if(this.reverse) {
|
||
return 'unset'
|
||
}
|
||
return 0
|
||
},
|
||
activeTop() {
|
||
if(this.reverse) {
|
||
return 0
|
||
}
|
||
return 'unset'
|
||
},
|
||
activeBottom() {
|
||
if(this.reverse) {
|
||
return 'unset'
|
||
}
|
||
return 0
|
||
},
|
||
barActiveWidth() {
|
||
if(this.direction=="vertical") {
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
}
|
||
let percent
|
||
if(this.continuous) {
|
||
percent = this.percent
|
||
}
|
||
else {
|
||
percent = Math.abs((this.showValue - this.min) / (this.mmax - this.min))
|
||
}
|
||
return this.barMaxLength * percent + 'px'
|
||
},
|
||
barActiveHeight() {
|
||
if(this.direction=="vertical") {
|
||
let percent
|
||
if(this.continuous) {
|
||
percent = this.percent
|
||
}
|
||
else {
|
||
percent = Math.abs((this.showValue - this.min) / (this.mmax - this.min))
|
||
}
|
||
return this.barMaxLength * percent + 'px'
|
||
}
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
},
|
||
subActiveTop() {
|
||
if(this.reverse) {
|
||
return 0
|
||
}
|
||
return 'unset'
|
||
},
|
||
subActiveBottom() {
|
||
if(this.reverse) {
|
||
return 'unset'
|
||
}
|
||
return 0
|
||
},
|
||
subActiveRight() {
|
||
if(this.reverse) {
|
||
return 0
|
||
}
|
||
return 'unset'
|
||
},
|
||
subActiveLeft() {
|
||
if(this.reverse) {
|
||
return 'unset'
|
||
}
|
||
return 0
|
||
},
|
||
barSubActiveWidth() {
|
||
if(this.direction == "vertical") {
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
}
|
||
if(this.subContinuous) {
|
||
return this.barMaxLength * this.subPercent + 'px'
|
||
}
|
||
else {
|
||
return this.barMaxLength * Math.abs((this.msubValue - this.min) / (this.mmax - this.min)) + 'px'
|
||
}
|
||
|
||
},
|
||
barSubActiveHeight() {
|
||
if(this.direction == "vertical") {
|
||
if(this.subContinuous) {
|
||
return this.barMaxLength * this.subPercent + 'px'
|
||
}
|
||
else {
|
||
this.barMaxLength * Math.abs((this.msubValue - this.min) / (this.mmax - this.min)) + 'px'
|
||
}
|
||
|
||
}
|
||
return this.sizeDeal(this.strokeWidth)[2]
|
||
},
|
||
mhandleWidth() {
|
||
if(this.direction == "vertical") {
|
||
return this.sizeDeal(this.handleHeight)[2]
|
||
}
|
||
return this.sizeDeal(this.handleWidth)[2]
|
||
},
|
||
mhandleHeight() {
|
||
if(this.direction == "vertical") {
|
||
return this.sizeDeal(this.handleWidth)[2]
|
||
}
|
||
return this.sizeDeal(this.handleHeight)[2]
|
||
},
|
||
mhandleTop() {
|
||
if(this.direction == 'vertical') {
|
||
return 0
|
||
}
|
||
else {
|
||
// 拖柄垂直居中
|
||
let handle = this.sizeDeal(this.handleHeight)[0]
|
||
let top = this.maxHeight()[0] / 2 - handle / 2 + 'px'
|
||
return top
|
||
}
|
||
},
|
||
showValue() {
|
||
return this.valueFormat(this.percent * (this.mmax - this.min) + this.min)
|
||
},
|
||
textHeight() {
|
||
let infoSize = this.sizeDeal(this.infoFontSize)
|
||
return infoSize[0]*1.2 + infoSize[1]
|
||
},
|
||
valueLeft() {
|
||
if(this.infoAlign=='left') {
|
||
return 0
|
||
}
|
||
else if(this.infoAlign == 'center') {
|
||
let width = this.sizeDeal(this.width)
|
||
return width[0]/2 - this.valueWidth()/2 + 'px'
|
||
}
|
||
else if(this.infoAlign=='right'){
|
||
let width = this.sizeDeal(this.width)
|
||
return width[0] - this.textWidth() + 'px'
|
||
}
|
||
return 0
|
||
},
|
||
barMaxLength() {
|
||
let width = this.sizeDeal(this.width)[0]
|
||
let handleWidth = this.sizeDeal(this.handleWidth)
|
||
return width - this.textWidth() - handleWidth[0]
|
||
},
|
||
mwidgetWidth() {
|
||
return this.sizeDeal(this.widgetWidth)[2];
|
||
},
|
||
mwidgetHeight() {
|
||
return this.sizeDeal(this.widgetHeight)[2];
|
||
},
|
||
moffset() {
|
||
let off = this.sizeDeal(this.widgetOffset);
|
||
// console.log(off)
|
||
switch(this.widgetPos) {
|
||
case 'top':
|
||
return this.sizeDeal(this.mhandleHeight)[0] + off[0] + 'px'
|
||
case 'right':
|
||
return this.sizeDeal(this.mhandleWidth)[0] + off[0] + 'px'
|
||
case 'bottom':
|
||
return this.sizeDeal(this.mhandleHeight)[0] + off[0] + 'px'
|
||
case 'left':
|
||
return this.sizeDeal(this.mhandleWidth)[0] + off[0] + 'px'
|
||
}
|
||
return 0
|
||
},
|
||
mwidgetBorderRadius() {
|
||
return this.sizeDeal(this.widgetBorderRadius)[2];
|
||
},
|
||
mwidgetAngle() {
|
||
return "rotate("+Number(this.widgetAngle)+"deg)"
|
||
}
|
||
},
|
||
methods: {
|
||
prevent(e) {
|
||
console.log(1)
|
||
},
|
||
updateRect() {
|
||
// #ifndef APP-NVUE
|
||
/**
|
||
* 非NVUE movable-area 滑动事件获取到的位置是相对于文档的,获取组件位置,用于计算滑块位置
|
||
*/
|
||
let query = uni.createSelectorQuery().in(this)
|
||
query.select('.bing-progress').boundingClientRect(data => {
|
||
this.mainInfo.top = data.top
|
||
this.mainInfo.left = data.left
|
||
this.mainInfo.bottom = data.bottom
|
||
this.mainInfo.right = data.right
|
||
}).exec()
|
||
// #endif
|
||
},
|
||
touchstart(e) {
|
||
if(!this.disabled) {
|
||
// #ifdef APP-NVUE
|
||
e.stopPropagation()
|
||
e.target.attr.preventGesture = true
|
||
if(this.direction == 'vertical' && e.target.attr.id != 'bp-mview' && (e.timestamp - this.lastTouchTime > 100)) {
|
||
this.moveable = false
|
||
}
|
||
this.lastTouchTime = e.timestamp
|
||
// #endif
|
||
// #ifndef APP-NVUE
|
||
/**
|
||
* 防止组件在文档流中的位置被修改,导致组件进度值异常
|
||
*/
|
||
this.updateRect()
|
||
// #endif
|
||
// 阻止组件信息异常情况下的进度值修改
|
||
if(this.mainInfo.top > this.screenHeight) {
|
||
this.$emit("dragstart", {bpname: this.bpname,type: 'dragstart',value:this.showValue,subValue:this.msubValue})
|
||
return
|
||
}
|
||
this.touchState = true
|
||
let detail = e.changedTouches[0]
|
||
this.handleMove(detail)
|
||
this.$emit("dragstart", {bpname: this.bpname,type: 'dragstart',value:this.showValue,subValue:this.msubValue})
|
||
}
|
||
},
|
||
touchmove(e) {
|
||
if(!this.disabled) {
|
||
let detail = e.changedTouches[0]
|
||
this.handleMove(detail)
|
||
this.$emit("dragging", {bpname: this.bpname,type: 'dragging',value:this.showValue,subValue:this.msubValue})
|
||
}
|
||
},
|
||
touchend(e) {
|
||
if(!this.disabled) {
|
||
// #ifdef APP-NVUE
|
||
if(!this.moveable) {
|
||
this.moveable = true
|
||
return
|
||
}
|
||
// #endif
|
||
let detail = e.changedTouches[0]
|
||
this.handleMove(detail)
|
||
this.touchState = false
|
||
this.$emit("dragend", {bpname: this.bpname,type: 'dragend',value:this.showValue,subValue:this.msubValue})
|
||
}
|
||
},
|
||
handleMove(detail) {
|
||
let width = this.sizeDeal(this.width)[0]
|
||
let handleWidth = this.sizeDeal(this.handleWidth)
|
||
let percent
|
||
if(this.direction!='vertical') {
|
||
if(this.infoAlign=='left') {
|
||
// #ifndef APP-NVUE
|
||
percent = (detail.pageX - this.mainInfo.left - this.textWidth() - handleWidth[0]/2)/ this.barMaxLength
|
||
// #endif
|
||
// #ifdef APP-NVUE
|
||
percent = (detail.pageX - handleWidth[0]/2)/ this.barMaxLength
|
||
// #endif
|
||
}
|
||
else {
|
||
// #ifndef APP-NVUE
|
||
percent = (detail.pageX - this.mainInfo.left - handleWidth[0]/2)/ this.barMaxLength
|
||
// #endif
|
||
// #ifdef APP-NVUE
|
||
percent = (detail.pageX - handleWidth[0]/2)/ this.barMaxLength
|
||
// #endif
|
||
}
|
||
}
|
||
else {
|
||
// #ifdef APP-NVUE
|
||
percent = 1 - (detail.pageY - handleWidth[0]/2- 1) / this.barMaxLength
|
||
// #endif
|
||
// #ifndef APP-NVUE
|
||
percent = 1 - (detail.clientY - this.mainInfo.top - handleWidth[0]/2)/ this.barMaxLength
|
||
// #endif
|
||
}
|
||
percent = percent > 0 ? percent : 0
|
||
percent = percent < 1 ? percent : 1
|
||
if(this.reverse) {
|
||
this.percent = 1 - percent
|
||
}
|
||
else {
|
||
this.percent = percent
|
||
}
|
||
},
|
||
showValueState() {
|
||
if(this.direction != 'vertical' && this.showInfo && (this.infoAlign=='left' || this.infoAlign=='right')) {
|
||
return true
|
||
}
|
||
return false
|
||
},
|
||
valueSetBoundary(value) {
|
||
// 控制value在合法范围内
|
||
if(this.mmax > this.min) {
|
||
value = value < this.mmax ? value : this.mmax
|
||
value = value > this.min ? value : this.min
|
||
}
|
||
else {
|
||
value = value > this.mmax ? value : this.mmax
|
||
value = value < this.min ? value : this.min
|
||
}
|
||
return value
|
||
},
|
||
/**
|
||
* @param {Object} v
|
||
* @param {Object} isSub 是否是副副进度条
|
||
*/
|
||
valueFormat (v,isSub){
|
||
// set step
|
||
v = this.valueSetBoundary(v)
|
||
let stepInfo = this.stepInfo(isSub)
|
||
v = Number(v - this.min).toFixed(stepInfo[1])
|
||
let step = stepInfo[0] * 10 ** stepInfo[1]
|
||
let valueE = v * 10 ** stepInfo[1]
|
||
let remainder = valueE % step
|
||
let remainderInt = Math.floor(remainder)
|
||
// 对余数四舍五入0-1
|
||
let sub = Math.round(remainder / step)
|
||
let value = (Math.floor(valueE) - remainderInt + sub*step) / (10 ** stepInfo[1])
|
||
value = Number((value + this.min).toFixed(stepInfo[1]))
|
||
return value
|
||
},
|
||
/**
|
||
* @param {Object} v
|
||
* @param {Object} isSub 是否是副副进度条
|
||
*/
|
||
stepInfo(isSub) {
|
||
// return step, decimal位数
|
||
let step
|
||
if(isSub) {
|
||
step = Number(this.subStep)
|
||
}
|
||
else {
|
||
step = Number(this.step)
|
||
}
|
||
|
||
if (step <= 0 || !step){
|
||
return [1, 0]
|
||
}
|
||
else{
|
||
let steps = step.toString().split('.')
|
||
if (steps.length == 1){
|
||
return [step,0]
|
||
}
|
||
else {
|
||
return [step,steps[1].length]
|
||
}
|
||
}
|
||
},
|
||
textWidth() {
|
||
if(this.showValueState()) {
|
||
let numWidth = this.mmax.toString().length> this.min.toString().length? this.mmax.toString().length: this.min.toString().length
|
||
let textWidth = ((numWidth + this.stepInfo()[1]) * 0.7 + this.infoEndText.length) * this.sizeDeal(this.infoFontSize)[0]
|
||
return Number(textWidth.toFixed(2))
|
||
}
|
||
return 0
|
||
},
|
||
valueWidth() {
|
||
let numWidth = this.mmax.toString().length> this.min.toString().length? this.mmax.toString().length: this.min.toString().length
|
||
let textWidth = ((numWidth + this.stepInfo()[1]) * 0.7 + this.infoEndText.length) * this.sizeDeal(this.infoFontSize)[0]
|
||
return Number(textWidth.toFixed(2))
|
||
},
|
||
maxHeight() {
|
||
let h = []
|
||
if (this.direction!='vertical'){ // direction 为 vertical 时不显示info
|
||
let subt = this.infoEndText.match(/[^\x00-\xff]/g)
|
||
if (subt){
|
||
h.push(this.sizeDeal(this.infoFontSize)[0] * 1.1)
|
||
}
|
||
else{
|
||
h.push(this.sizeDeal(this.infoFontSize)[0])
|
||
}
|
||
}
|
||
h.push(this.sizeDeal(this.strokeWidth)[0])
|
||
h.push(this.sizeDeal(this.handleHeight)[0])
|
||
h.sort(function(a, b) {
|
||
return b - a
|
||
}) // 降序
|
||
return [h[0], 'px', h[0] + 'px']
|
||
},
|
||
sizeDeal(size) {
|
||
// 分离字体大小和单位,rpx 转 px
|
||
let s = Number.isNaN(parseFloat(size)) ? 0 : parseFloat(size)
|
||
let u = size.toString().replace(/[0-9\.]/g, '')
|
||
if (u == 'rpx') {
|
||
s /= this.px2rpx
|
||
u = 'px'
|
||
}else if (u == 'vw') {
|
||
u = 'px'
|
||
s = s / 100 * this.screenWidth
|
||
} else if(u == 'vh') {
|
||
u = 'px'
|
||
s = s / 100 * this.screenHeight
|
||
} else{
|
||
u = 'px'
|
||
}
|
||
|
||
return [s, u, s + u]
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
@import "bing-progress.css"
|
||
</style>
|