151 lines
3.7 KiB
Vue
151 lines
3.7 KiB
Vue
<template>
|
|
<section class="barContain">
|
|
<div class="slideBar" :style="getBarWidth"></div>
|
|
<div class="slideBlock" :style="getBlockPosition"></div>
|
|
<template v-if="showStops">
|
|
<span class="stops" :style="getStopsPosition(n)" v-for="n in stops" @click="changeValue(n)"></span>
|
|
<span class="stopsValue" :style="getStopsPosition(n)" v-for="n in stops" @click="changeValue(n)">
|
|
{{stopsValue(n)}}
|
|
</span>
|
|
</template>
|
|
</section>
|
|
</template>
|
|
<script>
|
|
var that = null;
|
|
export default {
|
|
name: "sliderBar",
|
|
props: {
|
|
min: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
max: {
|
|
type: Number,
|
|
default: 100
|
|
},
|
|
step: {
|
|
type: Number,
|
|
default: 1
|
|
},
|
|
showStops: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
unit: {
|
|
type: String
|
|
},
|
|
value: {
|
|
default: ''
|
|
}
|
|
},
|
|
created() {
|
|
that = this;
|
|
},
|
|
methods: {
|
|
stopsValue(n) {
|
|
return (this.min + this.step * (n - 1)) + this.unit
|
|
},
|
|
changeValue(n) {
|
|
var currentValue = this.min + this.step * (n - 1)
|
|
this.$emit('input', currentValue)
|
|
},
|
|
getStopsPosition(n) {
|
|
let left = (this.step * n - this.min) / (this.max - this.min) * 100 + "%";
|
|
let background, color, fontWeight;
|
|
if (this.value >= this.step * (n + 1) - this.min) background = "#4c82ff";
|
|
if (this.value == this.step * (n + 1) - this.min) {
|
|
color = "#4c82ff"
|
|
fontWeight = "bolder"
|
|
};
|
|
return {
|
|
left,
|
|
background,
|
|
color,
|
|
fontWeight
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
stops() {
|
|
return parseInt((this.max - this.min) / this.step) + 1
|
|
},
|
|
getBarWidth() {
|
|
var currentValue = this.value || this.min;
|
|
return {
|
|
width: (currentValue - this.min) / (this.max - this.min) * 100 + "%"
|
|
}
|
|
},
|
|
getBlockPosition() {
|
|
var currentValue = this.value || this.min;
|
|
return {
|
|
left: (currentValue - this.min) / (this.max - this.min) * 100 + "%"
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
</script>
|
|
<style lang="less" scoped>
|
|
.barContain {
|
|
height: 4px;
|
|
border-radius: 4px;
|
|
background: #d0d6d8;
|
|
position: relative;
|
|
z-index: 10;
|
|
margin: 12px 0 29px;
|
|
.slideBar {
|
|
height: 4px;
|
|
border-radius: 4px;
|
|
background: #4c82ff;
|
|
width: 0;
|
|
transition: width ease 0.2s;
|
|
}
|
|
.slideBlock {
|
|
width: 15px;
|
|
height: 15px;
|
|
border: 2px solid #fafcfc;
|
|
background: #4c82ff;
|
|
border-radius: 50%;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 0;
|
|
transform: translate(-50%, -50%);
|
|
transition: all ease 0.2s;
|
|
transform-origin: center center;
|
|
z-index: 12;
|
|
cursor: pointer;
|
|
&:hover {
|
|
transform: translate(-50%, -50%) scale(1.2, 1.2);
|
|
}
|
|
}
|
|
.stops {
|
|
width: 6px;
|
|
height: 6px;
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
border: 2px solid #fafcfc;
|
|
background: #d0d6d8;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
transition: background ease 0.2s;
|
|
z-index: 11;
|
|
cursor: pointer;
|
|
}
|
|
.stopsValue {
|
|
position: absolute;
|
|
background: transparent !important;
|
|
top: 4px;
|
|
height: 29px;
|
|
line-height: 29px;
|
|
color: #3d424d;
|
|
font-size: 12px;
|
|
transform: translateX(-50%);
|
|
cursor: pointer;
|
|
&:first-of-type {
|
|
transform: translateX(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|