From 8a3f860213a0221383e68ed545712f30757516b6 Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Sat, 4 Dec 2021 20:35:08 +0900 Subject: [PATCH] fix(client): fix range slider rendering --- .../client/src/components/form-dialog.vue | 2 +- packages/client/src/components/form/range.vue | 28 +++++++++++++++---- packages/client/src/pages/settings/sounds.vue | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/client/src/components/form-dialog.vue b/packages/client/src/components/form-dialog.vue index fbf49af5d2..efd0da443d 100644 --- a/packages/client/src/components/form-dialog.vue +++ b/packages/client/src/components/form-dialog.vue @@ -40,7 +40,7 @@ <template #caption><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <option v-for="item in form[item].options" :key="item.value" :value="item.value">{{ item.label }}</option> </FormRadios> - <FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step" class="_formBlock"> + <FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step" :text-converter="form[item].textConverter" class="_formBlock"> <template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template> <template v-if="form[item].description" #caption>{{ form[item].description }}</template> </FormRange> diff --git a/packages/client/src/components/form/range.vue b/packages/client/src/components/form/range.vue index 79a83d6a93..3e02cacb9b 100644 --- a/packages/client/src/components/form/range.vue +++ b/packages/client/src/components/form/range.vue @@ -16,7 +16,7 @@ </template> <script lang="ts"> -import { computed, defineComponent, ref, watch } from 'vue'; +import { computed, defineComponent, onMounted, onUnmounted, ref, watch } from 'vue'; import * as os from '@/os'; export default defineComponent({ @@ -58,6 +58,9 @@ export default defineComponent({ }, setup(props, context) { + const containerEl = ref<HTMLElement>(); + const thumbEl = ref<HTMLElement>(); + const rawValue = ref((props.modelValue - props.min) / (props.max - props.min)); const steppedValue = computed(() => { if (props.step) { @@ -78,10 +81,25 @@ export default defineComponent({ if (thumbEl.value == null) return 0; return thumbEl.value!.offsetWidth; }); - const thumbPosition = computed(() => { - if (containerEl.value == null) return 0; - return (containerEl.value.offsetWidth - thumbWidth.value) * steppedValue.value; + const thumbPosition = ref(0); + const calcThumbPosition = () => { + if (containerEl.value == null) { + thumbPosition.value = 0; + } else { + thumbPosition.value = (containerEl.value.offsetWidth - thumbWidth.value) * steppedValue.value; + } + }; + watch([steppedValue, containerEl], calcThumbPosition); + onMounted(() => { + const ro = new ResizeObserver((entries, observer) => { + calcThumbPosition(); + }); + ro.observe(containerEl.value); + onUnmounted(() => { + ro.disconnect(); + }); }); + const steps = computed(() => { if (props.step) { return (props.max - props.min) / props.step; @@ -89,8 +107,6 @@ export default defineComponent({ return 0; } }); - const containerEl = ref<HTMLElement>(); - const thumbEl = ref<HTMLElement>(); const onMousedown = (ev: MouseEvent | TouchEvent) => { ev.preventDefault(); diff --git a/packages/client/src/pages/settings/sounds.vue b/packages/client/src/pages/settings/sounds.vue index 1492a989a2..0977dd8322 100644 --- a/packages/client/src/pages/settings/sounds.vue +++ b/packages/client/src/pages/settings/sounds.vue @@ -119,6 +119,7 @@ export default defineComponent({ mim: 0, max: 1, step: 0.05, + textConverter: (v) => `${Math.floor(v * 100)}%`, label: this.$ts.volume, default: this.sounds[type].volume },