From ad6d6225a1c563e4e0160c0f97a1801f81f61f62 Mon Sep 17 00:00:00 2001 From: hdx Date: Fri, 1 Sep 2023 12:01:45 +0800 Subject: [PATCH] =?UTF-8?q?long-list:=20=E6=9B=B4=E6=96=B0=E6=8C=87?= =?UTF-8?q?=E7=A4=BA=E5=99=A8=E7=BA=BF=EF=BC=8C=E4=BD=BF=E7=94=A8=20transf?= =?UTF-8?q?orm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/template/long-list/long-list.uvue | 87 ++++++++++----------- pages/template/swiper-list/swiper-list.uvue | 47 ++++++----- 2 files changed, 64 insertions(+), 70 deletions(-) diff --git a/pages/template/long-list/long-list.uvue b/pages/template/long-list/long-list.uvue index 9ea3d7bd..93439183 100644 --- a/pages/template/long-list/long-list.uvue +++ b/pages/template/long-list/long-list.uvue @@ -4,21 +4,19 @@ - + + - + {{item.name}} - - - + - @@ -69,9 +67,8 @@ } as SwiperViewItem ] as SwiperViewItem[], swiperIndex: -1, - tabsScrollLeft: 0, - swiperIndicatorLineLeft: 0, - swiperIndicatorLineWidth: 0, + $tabScrollView: null as null | INode, + $indicatorNode: null as null | INode, $headerHeight: 0, $animationFinishIndex: 0, $swiperWidth: 0, @@ -79,6 +76,8 @@ } }, onReady() { + this.$tabScrollView = this.$refs.get('tabScroll') as INode + this.$indicatorNode = this.$refs.get('indicator') as INode this.$headerHeight = (this.$refs["header"] as INode).offsetHeight this.$swiperWidth = (this.$refs["swiper"] as INode).getBoundingClientRect().width this.queryTabItemsSize() @@ -88,40 +87,32 @@ onTabClick(index : number) { this.setSwiperIndex(index, false) }, - /// 兼容微信 skyline 和 webview, uni-app-x 和 webview 行为一致 - /// skyline 每项完成触发 Animationfinish,偏移值重置 - /// webview 全部完成触发 Animationfinish,偏移值累加 - /// 在滑动到下一个项的过程中,再次反向滑动,偏移值递减 onSwiperTransition(e : SwiperTransitionEvent) { + // 微信 skyline 每项完成触发 Animationfinish,偏移值重置 + // 微信 webview 全部完成触发 Animationfinish,偏移值累加 + // 在滑动到下一个项的过程中,再次反向滑动,偏移值递减 + // uni-app-x 微信 webview 行为一致 + const offset_x = e.detail.dx - // 重置差异,计算当前实时索引位置 + // 重置差异,计算当前索引 const current_offset_x = offset_x % this.$swiperWidth const current_offset_i = offset_x / this.$swiperWidth const current_index = this.$animationFinishIndex + current_offset_i.toInt() - // 边界检查 + // 更新索引及边界检查 let move_to_index = current_index - if (current_offset_x > 0) { - if (move_to_index < this.$swiperTabsRect.length - 1) { - move_to_index += 1 - } - } else if (current_offset_x < 0) { - if (move_to_index > 0) { - move_to_index -= 1 - } + if (current_offset_x > 0 && move_to_index < this.swiperList.length - 1) { + move_to_index += 1 + } else if (current_offset_x < 0 && move_to_index > 0) { + move_to_index -= 1 } - // 计算蛇形线位置和大小 + // 计算偏移百分比 const percentage = Math.abs(current_offset_x) / this.$swiperWidth - const current_size = this.$swiperTabsRect[current_index] - const move_to_size = this.$swiperTabsRect[move_to_index] - const indicator_line_l = current_size.x + (move_to_size.x - current_size.x) * percentage - const indicator_line_w = current_size.w + (move_to_size.w - current_size.w) * percentage - // 更新蛇形线位置和大小 - // 这代码写的不对,不能在拖动滚动中使用vue绑定样式,只能用ref+transform - // this.updateTabIndicator(indicator_line_l, indicator_line_w) + // 通知更新指示线 + this.updateTabIndicator(current_index, move_to_index, percentage) // 首次可见时初始化数据 this.initSwiperItemPage(move_to_index) @@ -144,18 +135,29 @@ if (this.swiperIndex === index) { return } + this.swiperIndex = index this.initSwiperItemPage(index) if (updateIndicator) { - this.updateTabIndicator(this.$swiperTabsRect[index].x, this.$swiperTabsRect[index].w) + this.updateTabIndicator(index, index, 1) } }, - updateTabIndicator(left : Number, width : Number) { - this.swiperIndicatorLineLeft = left - this.swiperIndicatorLineWidth = width - this.tabsScrollLeft = left + width / 2 - this.$swiperWidth / 2 + updateTabIndicator(current_index : number, move_to_index : number, percentage : number) { + // 计算指示线 + const current_size = this.$swiperTabsRect[current_index] + const move_to_size = this.$swiperTabsRect[move_to_index] + const indicator_line_l = current_size.x + (move_to_size.x - current_size.x) * percentage + const indicator_line_w = current_size.w + (move_to_size.w - current_size.w) * percentage + + // 更新指示线 + const x = indicator_line_l + indicator_line_w / 2 + this.$indicatorNode?.style?.setProperty('transform', `translateX(${x}px) scaleX(${indicator_line_w})`) + + // 将指示线滚动到水平中心位置 + const scroll_x = x - this.$swiperWidth / 2 + this.$tabScrollView?.setAttribute('scrollLeft', scroll_x) }, initSwiperItemPage(index : Number) { if (!this.swiperList[index].preload) { @@ -200,15 +202,8 @@ } .swiper-tabs-indicator { - position: relative; + width: 1px; height: 2px; - } - - .swiper-tabs-underline { - position: absolute; - top: 0; - bottom: 0; - width: 0; background-color: #007AFF; } diff --git a/pages/template/swiper-list/swiper-list.uvue b/pages/template/swiper-list/swiper-list.uvue index c7fc860f..f4e47f3b 100644 --- a/pages/template/swiper-list/swiper-list.uvue +++ b/pages/template/swiper-list/swiper-list.uvue @@ -1,6 +1,7 @@