Просмотр исходного кода

fix(scale-ruler): 优化滚动位置计算逻辑

- 调整初始滚动位置计算方式,确保初始值右侧边缘对齐中心指示器
- 修改滚动事件中的索引计算逻辑,使用更准确的数值索引
- 统一调整滚动位置函数中的目标位置计算方法
- 修复触摸结束时的值计算问题,确保结果准确
- 移除旧的基于索引中间点的计算方式,改用右边缘对齐方案
mcbaiyun 2 месяцев назад
Родитель
Сommit
94c412b5e5
1 измененных файлов с 11 добавлено и 10 удалено
  1. 11 10
      src/components/scale-ruler.vue

+ 11 - 10
src/components/scale-ruler.vue

@@ -75,15 +75,16 @@ const halfWindow = windowWidth / 2
 onMounted(() => {
   // center on initial value
   const initIndex = Math.round((props.initialValue - props.min) / props.step)
-  scrollLeft.value = initIndex * props.gutter + offsetScroll.value - (uni?.getSystemInfoSync?.().windowWidth || 375) / 2 + props.gutter / 2
+  // place the right-edge of the initIndex cell under the center indicator
+  scrollLeft.value = offsetScroll.value + (initIndex + 1) * props.gutter - halfWindow
 })
 
 function onScroll(e: any) {
   const left = e?.detail?.scrollLeft ?? e?.detail?.scrollLeft ?? 0
   actualScrollLeft.value = left
-  // compute index under the centered indicator
-  const idx = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
-  let value = idx * props.step + props.min
+  // compute number index (units from min) under the centered indicator
+  const numIndex = Math.round((left + halfWindow - offsetScroll.value) / props.gutter) - 1
+  let value = numIndex * props.step + props.min
   if (value < props.min) value = props.min
   if (value > props.max) value = props.max
   emit('update:value', value)
@@ -92,10 +93,10 @@ function onScroll(e: any) {
 function adjustScrollPosition() {
   // snap so the nearest tick is centered under the indicator
   const left = actualScrollLeft.value
-  // compute index under center
-  const idx = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
-  // compute target scrollLeft that centers this index
-  const targetLeft = idx * props.gutter + offsetScroll.value - halfWindow + props.gutter / 2
+  // compute number index under center
+  const numIndex = Math.round((left + halfWindow - offsetScroll.value) / props.gutter) - 1
+  // compute target scrollLeft that centers this index's right-edge under the indicator
+  const targetLeft = offsetScroll.value + (numIndex + 1) * props.gutter - halfWindow
   // clamp to valid scroll range
   const maxScroll = Math.max(0, totalWidth.value - windowWidth)
   const clamped = Math.min(Math.max(targetLeft, 0), maxScroll)
@@ -107,8 +108,8 @@ function onTouchEnd() {
   adjustScrollPosition()
   // compute value and emit change
   const left = scrollLeft.value
-  const idx = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
-  let value = idx * props.step + props.min
+  const numIndex = Math.round((left + halfWindow - offsetScroll.value) / props.gutter) - 1
+  let value = numIndex * props.step + props.min
   if (value < props.min) value = props.min
   if (value > props.max) value = props.max
   emit('change', value)