topfans/frontend/components/lenticular/ManualTiltSlider.vue
2026-07-06 21:20:24 +08:00

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>