|
@@ -45,7 +45,24 @@ const actualScrollLeft = ref(0)
|
|
|
const currentValue = ref(Math.round(props.initialValue || props.min))
|
|
const currentValue = ref(Math.round(props.initialValue || props.min))
|
|
|
|
|
|
|
|
|
|
|
|
|
-const totalUnits = computed(() => Math.round((props.max - props.min) / props.step))
|
|
|
|
|
|
|
+// Support decimal step: convert to integer space using scale factor
|
|
|
|
|
+function decimalPlaces(n: number) {
|
|
|
|
|
+ const s = String(n)
|
|
|
|
|
+ if (s.indexOf('e-') >= 0) {
|
|
|
|
|
+ const m = s.match(/e-(\d+)$/)
|
|
|
|
|
+ return m ? parseInt(m[1], 10) : 0
|
|
|
|
|
+ }
|
|
|
|
|
+ const idx = s.indexOf('.')
|
|
|
|
|
+ return idx >= 0 ? s.length - idx - 1 : 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const stepDecimals = decimalPlaces(props.step)
|
|
|
|
|
+const scaleFactor = Math.pow(10, stepDecimals)
|
|
|
|
|
+const intMin = Math.round(props.min * scaleFactor)
|
|
|
|
|
+const intMax = Math.round(props.max * scaleFactor)
|
|
|
|
|
+const intStep = Math.round(props.step * scaleFactor)
|
|
|
|
|
+
|
|
|
|
|
+const totalUnits = computed(() => Math.round((intMax - intMin) / intStep))
|
|
|
|
|
|
|
|
|
|
|
|
|
const extraGridCount = Math.ceil((uni?.getSystemInfoSync?.().windowWidth || 375) / props.gutter / 2) * 2
|
|
const extraGridCount = Math.ceil((uni?.getSystemInfoSync?.().windowWidth || 375) / props.gutter / 2) * 2
|
|
@@ -60,9 +77,11 @@ function buildGrid() {
|
|
|
const arr: GridItem[] = []
|
|
const arr: GridItem[] = []
|
|
|
for (let i = 0; i <= count + extraGridCount * 1; i++) {
|
|
for (let i = 0; i <= count + extraGridCount * 1; i++) {
|
|
|
const numIndex = i - extraGridCount / 2
|
|
const numIndex = i - extraGridCount / 2
|
|
|
- const num = props.min + numIndex * props.step
|
|
|
|
|
- const displayNum = num
|
|
|
|
|
- const isLongGrid = (numIndex % 10 === 0)
|
|
|
|
|
|
|
+ const intNum = intMin + numIndex * intStep
|
|
|
|
|
+ const num = intNum / scaleFactor
|
|
|
|
|
+ const displayNum = (Number.isInteger(num) ? num : Number(num.toFixed(stepDecimals)))
|
|
|
|
|
+ // mark long grid every 10 steps in integer space (10 * intStep)
|
|
|
|
|
+ const isLongGrid = ((intNum - intMin) % (intStep * 10) === 0)
|
|
|
const showText = isLongGrid && num >= props.min && num <= props.max
|
|
const showText = isLongGrid && num >= props.min && num <= props.max
|
|
|
arr.push({ num, displayNum, isLongGrid, showText })
|
|
arr.push({ num, displayNum, isLongGrid, showText })
|
|
|
}
|
|
}
|
|
@@ -80,7 +99,11 @@ const halfWindow = windowWidth / 2
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
|
|
|
|
|
- const initIndex = Math.round((props.initialValue - props.min) / props.step)
|
|
|
|
|
|
|
+ // initialize using integer index space
|
|
|
|
|
+ const initIndex = Math.round((Math.round((props.initialValue || props.min) * scaleFactor) - intMin) / intStep)
|
|
|
|
|
+ scrollLeft.value = offsetScroll.value + initIndex * props.gutter + props.gutter / 2 - halfWindow
|
|
|
|
|
+ const initVal = (intMin + initIndex * intStep) / scaleFactor
|
|
|
|
|
+ currentValue.value = Number(stepDecimals ? initVal.toFixed(stepDecimals) : String(initVal))
|
|
|
|
|
|
|
|
scrollLeft.value = offsetScroll.value + initIndex * props.gutter + props.gutter / 2 - halfWindow
|
|
scrollLeft.value = offsetScroll.value + initIndex * props.gutter + props.gutter / 2 - halfWindow
|
|
|
|
|
|
|
@@ -92,11 +115,11 @@ function onScroll(e: any) {
|
|
|
actualScrollLeft.value = left
|
|
actualScrollLeft.value = left
|
|
|
|
|
|
|
|
const numIndex = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
|
|
const numIndex = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
|
|
|
- let value = numIndex * props.step + props.min
|
|
|
|
|
- if (value < props.min) value = props.min
|
|
|
|
|
- if (value > props.max) value = props.max
|
|
|
|
|
-
|
|
|
|
|
- currentValue.value = Math.round(value)
|
|
|
|
|
|
|
+ let intValue = intMin + numIndex * intStep
|
|
|
|
|
+ if (intValue < intMin) intValue = intMin
|
|
|
|
|
+ if (intValue > intMax) intValue = intMax
|
|
|
|
|
+ const value = intValue / scaleFactor
|
|
|
|
|
+ currentValue.value = Number(stepDecimals ? value.toFixed(stepDecimals) : String(value))
|
|
|
emit('update:value', value)
|
|
emit('update:value', value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -119,11 +142,11 @@ function onTouchEnd() {
|
|
|
|
|
|
|
|
const left = scrollLeft.value
|
|
const left = scrollLeft.value
|
|
|
const numIndex = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
|
|
const numIndex = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
|
|
|
- let value = numIndex * props.step + props.min
|
|
|
|
|
- if (value < props.min) value = props.min
|
|
|
|
|
- if (value > props.max) value = props.max
|
|
|
|
|
-
|
|
|
|
|
- currentValue.value = Math.round(value)
|
|
|
|
|
|
|
+ let intValue = intMin + numIndex * intStep
|
|
|
|
|
+ if (intValue < intMin) intValue = intMin
|
|
|
|
|
+ if (intValue > intMax) intValue = intMax
|
|
|
|
|
+ const value = intValue / scaleFactor
|
|
|
|
|
+ currentValue.value = Number(stepDecimals ? value.toFixed(stepDecimals) : String(value))
|
|
|
emit('change', value)
|
|
emit('change', value)
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|