78 lines
1.6 KiB
Vue
78 lines
1.6 KiB
Vue
<template>
|
|
<view v-if="showReset" class="tilt-slider-row">
|
|
<view v-if="showReset" class="tilt-slider-reset" @tap="handleReset">
|
|
<text class="tilt-slider-reset-icon">↺</text>
|
|
</view>
|
|
<slider
|
|
class="tilt-slider"
|
|
:min="min"
|
|
:max="max"
|
|
:step="step"
|
|
:value="value"
|
|
:disabled="disabled"
|
|
:activeColor="activeColor"
|
|
:backgroundColor="backgroundColor"
|
|
:show-value="false"
|
|
@change="handleChange"
|
|
/>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
defineProps({
|
|
value: { type: Number, default: 0.5, validator: v => v >= 0 && v <= 1 },
|
|
disabled: { type: Boolean, default: false },
|
|
showReset: { type: Boolean, default: true },
|
|
min: { type: Number, default: 0 },
|
|
max: { type: Number, default: 1 },
|
|
step: { type: Number, default: 0.01 },
|
|
activeColor: { type: String, default: '#6E7AFF' },
|
|
backgroundColor: { type: String, default: '#E5E7EB' },
|
|
})
|
|
|
|
const emit = defineEmits(['change', 'reset'])
|
|
|
|
function handleChange(e) {
|
|
const v = Number(e.detail.value)
|
|
if (!Number.isFinite(v)) {
|
|
console.warn('[ManualTiltSlider] non-finite value', e.detail.value)
|
|
return
|
|
}
|
|
if (v < 0 || v > 1) {
|
|
console.warn('[ManualTiltSlider] value out of [0,1]', v)
|
|
return
|
|
}
|
|
emit('change', v)
|
|
}
|
|
|
|
function handleReset() {
|
|
emit('reset')
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.tilt-slider-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12rpx;
|
|
padding: 8rpx 16rpx;
|
|
height: 48rpx;
|
|
}
|
|
.tilt-slider-reset {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
.tilt-slider-reset-icon {
|
|
font-size: 28rpx;
|
|
color: #6B7280;
|
|
}
|
|
.tilt-slider {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
</style>
|