Procházet zdrojové kódy

refactor(scale-ruler): 优化刻度尺组件布局与滚动逻辑

- 简化刻度线和文字的布局结构,去除冗余注释
- 调整 gridList 构建算法,减少重复网格数量
- 修改滚动偏移计算方式,提升指示器定位精度
- 移除不必要的 CSS 样式注释,精简样式代码
- 优化 currentValue 计算逻辑,提高响应速度
- 调整组件高度设置,改善视觉展示效果
mcbaiyun před 2 měsíci
rodič
revize
f686c7a564
1 změnil soubory, kde provedl 23 přidání a 39 odebrání
  1. 23 39
      src/components/scale-ruler.vue

+ 23 - 39
src/components/scale-ruler.vue

@@ -5,14 +5,11 @@
       <view class="ruler-inner" :style="{ width: totalWidth + 'px' }">
         <view v-for="(g, idx) in gridList" :key="idx" class="grid-item" :class="{ long: g.isLongGrid }"
           :style="{ width: props.gutter + 'px' }">
-          <!-- 刻度线(位于上方) -->
           <view class="tick" :class="{ long: g.isLongGrid }"></view>
-          <!-- 刻度文字放在刻度线下面 -->
           <text v-if="g.showText" class="grid-num">{{ g.displayNum }}</text>
         </view>
       </view>
     </scroll-view>
-    <!-- 中心指示器:上方显示当前值的方框,下方显示指向刻度的三角形 -->
     <view class="indicator">
       <view class="value-box"><text class="value-text">{{ currentValue }}</text></view>
       <view class="indicator-triangle"></view>
@@ -31,10 +28,10 @@ interface GridItem { num: number; displayNum: number | string; isLongGrid: boole
 const props = defineProps({
   min: { type: Number, default: 0 },
   max: { type: Number, default: 100 },
-  step: { type: Number, default: 1 }, // value step
+  step: { type: Number, default: 1 }, 
   unit: { type: String, default: '' },
   initialValue: { type: Number, default: 0 },
-  gutter: { type: Number, default: 10 }, // px per unit
+  gutter: { type: Number, default: 10 }, 
   visible: { type: Boolean, default: true },
   useAnimation: { type: Boolean, default: true }
 })
@@ -44,13 +41,13 @@ const emit = defineEmits(['update:value', 'change'])
 const instance = getCurrentInstance()
 const scrollLeft = ref(0)
 const actualScrollLeft = ref(0)
-// 当前中心值(整数)
+
 const currentValue = ref(Math.round(props.initialValue || props.min))
 
-// prepare grid
+
 const totalUnits = computed(() => Math.round((props.max - props.min) / props.step))
 
-// extra grids to fill screen on both sides
+
 const extraGridCount = Math.ceil((uni?.getSystemInfoSync?.().windowWidth || 375) / props.gutter)
 
 const gridList = ref<GridItem[]>([])
@@ -61,8 +58,8 @@ const gridItemStyle = computed(() => ({ width: props.gutter + 'px', height: '24p
 function buildGrid() {
   const count = totalUnits.value
   const arr: GridItem[] = []
-  for (let i = 0; i <= count + extraGridCount * 2; i++) {
-    const numIndex = i - extraGridCount
+  for (let i = 0; i <= count + extraGridCount * 1; i++) {
+    const numIndex = i - extraGridCount /2
     const num = props.min + numIndex * props.step
     const displayNum = num
     const isLongGrid = (numIndex % 10 === 0)
@@ -75,59 +72,57 @@ function buildGrid() {
 
 buildGrid()
 
-// offsetScroll: amount to offset due to extra grids on left
-const offsetScroll = computed(() => extraGridCount * props.gutter)
+const offsetScroll = computed(() => extraGridCount * props.gutter/2)
 
-// window width and half (indicator is centered horizontally)
 const windowWidth = uni?.getSystemInfoSync?.().windowWidth || 375
 const halfWindow = windowWidth / 2
 
-// initial position
+
 onMounted(() => {
-  // center on initial value (align cell center under indicator)
+
   const initIndex = Math.round((props.initialValue - props.min) / props.step)
-  // place the center of the initIndex cell under the center indicator
+
   scrollLeft.value = offsetScroll.value + initIndex * props.gutter + props.gutter / 2 - halfWindow
-  // 初始化当前显示值
+
   currentValue.value = Math.round(initIndex * props.step + props.min)
 })
 
 function onScroll(e: any) {
   const left = e?.detail?.scrollLeft ?? e?.detail?.scrollLeft ?? 0
   actualScrollLeft.value = left
-  // compute number index (units from min) under the centered indicator (based on cell center)
+
   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)
   emit('update:value', value)
 }
 
 function adjustScrollPosition() {
-  // snap so the nearest tick is centered under the indicator
+
   const left = actualScrollLeft.value
-  // compute number index under center
+
   const numIndex = Math.round((left + halfWindow - offsetScroll.value - props.gutter / 2) / props.gutter)
-  // compute target scrollLeft that centers this index's center under the indicator
+
   const targetLeft = offsetScroll.value + numIndex * props.gutter + props.gutter / 2 - halfWindow
-  // clamp to valid scroll range
+
   const maxScroll = Math.max(0, totalWidth.value - windowWidth)
   const clamped = Math.min(Math.max(targetLeft, 0), maxScroll)
   scrollLeft.value = clamped
 }
 
 function onTouchEnd() {
-  // adjust position on touch end
+
   adjustScrollPosition()
-  // compute value and emit change
+
   const left = scrollLeft.value
   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)
   emit('change', value)
 }
@@ -136,7 +131,6 @@ function onTouchEnd() {
 <style scoped>
 .ruler-wrapper {
   position: relative;
-  /* 增高以给刻度线下面留白 */
   height: 260rpx;
   display: flex;
   align-items: flex-start;
@@ -150,23 +144,20 @@ function onTouchEnd() {
 
 .ruler-inner {
   display: flex;
-  /* 让刻度线靠上排列,文字在下方 */
   align-items: flex-start;
 }
 
 .grid-item {
   width: 10px;
-  /* 不固定高度,让内部内容控制布局 */
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: flex-start;
   padding-top: 8rpx;
-  /* 给刻度线一点顶部间距 */
 }
 
 
-/* 刻度线样式,短刻度和长刻度高度不同 */
+
 .tick {
   width: 2px;
   height: 40rpx;
@@ -184,7 +175,7 @@ function onTouchEnd() {
   font-size: 28rpx;
   color: #666;
   margin-top: 8rpx;
-  /* 刻度线下面的间距 */
+
 }
 
 .indicator {
@@ -205,7 +196,6 @@ function onTouchEnd() {
   margin-top: -4px;
   margin-left: 1px;
   height: 15px;
-  /* 可视为指示器从 value box 底部到 triangle 顶部的线长,可调整 */
   background: #ff6a00;
 }
 
@@ -215,17 +205,14 @@ function onTouchEnd() {
   border-left: 8px solid transparent;
   border-right: 8px solid transparent;
   border-top: 10px solid #ff6a00;
-  /* 向上的三角形 */
   margin-top: 60px;
 }
 
 .value-box {
   margin-top: 20rpx;
   position: absolute;
-  /* 将方框放在指示线之上,距离可根据值框高度调整 */
   left: 50%;
   transform: translateX(-50%);
-  /* background: #ff6a00; */
   padding: 6rpx 12rpx;
   border-radius: 6rpx;
   display: flex;
@@ -237,9 +224,6 @@ function onTouchEnd() {
   color: #000000;
   font-size: 28px;
   font-weight: 900;
-  /* 使用 24px 显示当前数值 */
   line-height: 1;
 }
-
-
 </style>