Files
aircox/radiocampus/assets/src/components/AProgress.vue

72 lines
2.2 KiB
Vue

<template>
<div class="a-progress m-0">
<time class="time-now">
<slot name="value" :value="value" :max="max">{{ format(value) }}</slot>
</time>
<div ref="bar" class="a-progress-bar-container" @click.stop="onClick" @mouseleave.stop="onMouseMove"
@mousemove.stop="onMouseMove">
<div :class="progressClass" :style="progressStyle">
<time v-if="hoverValue">
{{ format(hoverValue) }}
</time>
<template v-else>&nbsp;</template>
</div>
</div>
<time class="time-total">
<slot name="value" :value="valueDisplay" :max="max">{{ format(max) }}</slot>
</time>
</div>
</template>
<script>
export default {
data() {
return {
hoverValue: null,
}
},
props: {
value: Number,
max: Number,
format: { type: Function, default: x => x },
progressClass: { default: 'a-progress-bar' },
vertical: { type: Boolean, default: false },
},
computed: {
valueDisplay() { return this.hoverValue === null ? this.value : this.hoverValue; },
progressStyle() {
if(!this.max)
return null;
let value = this.max ? this.valueDisplay * 100 / this.max : 0;
return this.vertical ? { height: `${value}%` } : { width: `${value}%` };
},
},
methods: {
xToValue(x) { return x * this.max / this.$refs.bar.getBoundingClientRect().width },
yToValue(y) { return y * this.max / this.$refs.bar.getBoundingClientRect().height },
valueFromEvent(event) {
let rect = event.currentTarget.getBoundingClientRect()
return this.vertical ? this.yToValue(event.clientY - rect.y)
: this.xToValue(event.clientX - rect.x);
},
onClick(event) {
this.$emit('select', this.valueFromEvent(event));
},
onMouseMove(event) {
if(event.type == 'mouseleave')
this.hoverValue = null;
else {
this.hoverValue = this.valueFromEvent(event);
}
},
},
}
</script>