1 | <template>
|
---|
2 | <div class="root">
|
---|
3 | <button type="button" class="btn-fab theme-flat" :disabled="isDisabled"
|
---|
4 | @click="stepBack" @mousedown="onStepBackMouseDown" @mouseup="onStepperMouseUp">
|
---|
5 | <span class="material-icons mdi-s">arrow_back_ios_new</span>
|
---|
6 | </button>
|
---|
7 |
|
---|
8 | <span>{{ stringSliderValue }}</span>
|
---|
9 |
|
---|
10 | <button type="button" class="btn-fab theme-flat" :disabled="isDisabled"
|
---|
11 | @click="stepForward" @mousedown="onStepForwardMouseDown" @mouseup="onStepperMouseUp">
|
---|
12 | <span class="material-icons mdi-s">arrow_forward_ios</span>
|
---|
13 | </button>
|
---|
14 |
|
---|
15 | <input type="range" class="slider-continuous" v-model.number="sliderValue" min="0" :max="audioLength" step="0.01" :disabled="isDisabled" />
|
---|
16 | </div>
|
---|
17 | </template>
|
---|
18 |
|
---|
19 | <style lang="scss" scoped>
|
---|
20 | .root {
|
---|
21 | display: flex;
|
---|
22 | align-items: center;
|
---|
23 | gap: 0.5em;
|
---|
24 | }
|
---|
25 | </style>
|
---|
26 |
|
---|
27 | <script>
|
---|
28 | import AudioPlayback from "../js/AudioPlaybackModule"
|
---|
29 | import Util from "../js/Util"
|
---|
30 |
|
---|
31 | export default {
|
---|
32 | name: "AudioTimeBar",
|
---|
33 | props: {
|
---|
34 | modelValue: Number,
|
---|
35 | audioLength: Number,
|
---|
36 | isDisabled: Boolean
|
---|
37 | },
|
---|
38 | emits: [ "update:modelValue" ],
|
---|
39 | data() {
|
---|
40 | return {
|
---|
41 | stepperHeld: false,
|
---|
42 | stepperHeldTimeout: null
|
---|
43 | }
|
---|
44 | },
|
---|
45 | computed: {
|
---|
46 | sliderValue: {
|
---|
47 | get() {
|
---|
48 | if (this.modelValue > this.audioLength) {
|
---|
49 | return this.audioLength;
|
---|
50 | }
|
---|
51 | else if (this.modelValue < 0) {
|
---|
52 | return 0;
|
---|
53 | }
|
---|
54 | else {
|
---|
55 | return this.modelValue;
|
---|
56 | }
|
---|
57 | },
|
---|
58 | set(newValue) {
|
---|
59 | this.$emit("update:modelValue", newValue);
|
---|
60 | }
|
---|
61 | },
|
---|
62 | stringSliderValue() {
|
---|
63 | return Util.formatSecondsTimeString(this.sliderValue, false, 2);
|
---|
64 | }
|
---|
65 | },
|
---|
66 | methods: {
|
---|
67 | stepBack() {
|
---|
68 | AudioPlayback.scrub(this.modelValue - 0.1);
|
---|
69 | },
|
---|
70 | stepForward() {
|
---|
71 | AudioPlayback.scrub(this.modelValue + 0.1);
|
---|
72 | },
|
---|
73 | onStepBackMouseDown() {
|
---|
74 | this.stepperHeldTimeout = setTimeout(() => this.continuousStep(true, this), 500);
|
---|
75 | this.stepperHeld = true;
|
---|
76 | },
|
---|
77 | onStepForwardMouseDown() {
|
---|
78 | this.stepperHeldTimeout = setTimeout(() => this.continuousStep(false, this), 500);
|
---|
79 | this.stepperHeld = true;
|
---|
80 | },
|
---|
81 | onStepperMouseUp() {
|
---|
82 | this.stepperHeld = false;
|
---|
83 | clearTimeout(this.stepperHeldTimeout);
|
---|
84 | },
|
---|
85 | continuousStep(back, vm) {
|
---|
86 | (function run() {
|
---|
87 | if (!vm.stepperHeld) {
|
---|
88 | return;
|
---|
89 | }
|
---|
90 |
|
---|
91 | if (back) {
|
---|
92 | vm.stepBack();
|
---|
93 | }
|
---|
94 | else {
|
---|
95 | vm.stepForward();
|
---|
96 | }
|
---|
97 |
|
---|
98 | setTimeout(run, 25); // 40hz
|
---|
99 | })();
|
---|
100 | }
|
---|
101 | }
|
---|
102 | }
|
---|
103 | </script>
|
---|