Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
ad6d6225
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
5995
Star
90
Fork
162
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
18
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
18
Issue
18
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
ad6d6225
编写于
9月 01, 2023
作者:
H
hdx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
long-list: 更新指示器线,使用 transform
上级
7779add1
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
64 addition
and
70 deletion
+64
-70
pages/template/long-list/long-list.uvue
pages/template/long-list/long-list.uvue
+41
-46
pages/template/swiper-list/swiper-list.uvue
pages/template/swiper-list/swiper-list.uvue
+23
-24
未找到文件。
pages/template/long-list/long-list.uvue
浏览文件 @
ad6d6225
...
@@ -4,21 +4,19 @@
...
@@ -4,21 +4,19 @@
<input placeholder="搜索..." />
<input placeholder="搜索..." />
</view>
</view>
<view class="swiper-list">
<view class="swiper-list">
<scroll-view class="swiper-tabs" :scroll-left="tabsScrollLeft" :scroll-x="true" :show-scrollbar="false">
<scroll-view ref="tabScroll" class="swiper-tabs" :scroll-x="true" :show-scrollbar="false">
<!-- TODO 多一层 view -->
<view>
<view>
<view class="flex-row">
<view class="flex-row">
<text class="swiper-tabs-item" :class="swiperIndex==index ? 'swiper-tabs-item-active' : ''"
<text
ref="swipertab"
class="swiper-tabs-item" :class="swiperIndex==index ? 'swiper-tabs-item-active' : ''"
v-for="(item, index) in swiperList"
ref="swipertab"
:key="index" @click="onTabClick(index)">
v-for="(item, index) in swiperList" :key="index" @click="onTabClick(index)">
{{item.name}}
{{item.name}}
</text>
</text>
</view>
</view>
<view class="swiper-tabs-indicator">
<view ref="indicator" class="swiper-tabs-indicator"></view>
<view class="swiper-tabs-underline"
:style="{left: swiperIndicatorLineLeft + 'px', width: swiperIndicatorLineWidth + 'px'}"></view>
</view>
</view>
</view>
</scroll-view>
</scroll-view>
<swiper
class="swiper-view" ref="swiper
" :current="swiperIndex" @transition="onSwiperTransition"
<swiper
ref="swiper" class="swiper-view
" :current="swiperIndex" @transition="onSwiperTransition"
@animationfinish="onSwiperAnimationfinish">
@animationfinish="onSwiperAnimationfinish">
<swiper-item class="swiper-item" v-for="(item, index) in swiperList" :key="index">
<swiper-item class="swiper-item" v-for="(item, index) in swiperList" :key="index">
<long-page ref="longPage" :type="item.type" :preload="item.preload"></long-page>
<long-page ref="longPage" :type="item.type" :preload="item.preload"></long-page>
...
@@ -69,9 +67,8 @@
...
@@ -69,9 +67,8 @@
} as SwiperViewItem
} as SwiperViewItem
] as SwiperViewItem[],
] as SwiperViewItem[],
swiperIndex: -1,
swiperIndex: -1,
tabsScrollLeft: 0,
$tabScrollView: null as null | INode,
swiperIndicatorLineLeft: 0,
$indicatorNode: null as null | INode,
swiperIndicatorLineWidth: 0,
$headerHeight: 0,
$headerHeight: 0,
$animationFinishIndex: 0,
$animationFinishIndex: 0,
$swiperWidth: 0,
$swiperWidth: 0,
...
@@ -79,6 +76,8 @@
...
@@ -79,6 +76,8 @@
}
}
},
},
onReady() {
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.$headerHeight = (this.$refs["header"] as INode).offsetHeight
this.$swiperWidth = (this.$refs["swiper"] as INode).getBoundingClientRect().width
this.$swiperWidth = (this.$refs["swiper"] as INode).getBoundingClientRect().width
this.queryTabItemsSize()
this.queryTabItemsSize()
...
@@ -88,40 +87,32 @@
...
@@ -88,40 +87,32 @@
onTabClick(index : number) {
onTabClick(index : number) {
this.setSwiperIndex(index, false)
this.setSwiperIndex(index, false)
},
},
/// 兼容微信 skyline 和 webview, uni-app-x 和 webview 行为一致
/// skyline 每项完成触发 Animationfinish,偏移值重置
/// webview 全部完成触发 Animationfinish,偏移值累加
/// 在滑动到下一个项的过程中,再次反向滑动,偏移值递减
onSwiperTransition(e : SwiperTransitionEvent) {
onSwiperTransition(e : SwiperTransitionEvent) {
// 微信 skyline 每项完成触发 Animationfinish,偏移值重置
// 微信 webview 全部完成触发 Animationfinish,偏移值累加
// 在滑动到下一个项的过程中,再次反向滑动,偏移值递减
// uni-app-x 微信 webview 行为一致
const offset_x = e.detail.dx
const offset_x = e.detail.dx
// 重置差异,计算当前
实时索引位置
// 重置差异,计算当前
索引
const current_offset_x = offset_x % this.$swiperWidth
const current_offset_x = offset_x % this.$swiperWidth
const current_offset_i = offset_x / this.$swiperWidth
const current_offset_i = offset_x / this.$swiperWidth
const current_index = this.$animationFinishIndex + current_offset_i.toInt()
const current_index = this.$animationFinishIndex + current_offset_i.toInt()
// 边界检查
//
更新索引及
边界检查
let move_to_index = current_index
let move_to_index = current_index
if (current_offset_x > 0) {
if (current_offset_x > 0 && move_to_index < this.swiperList.length - 1) {
if (move_to_index < this.$swiperTabsRect.length - 1) {
move_to_index += 1
move_to_index += 1
} else if (current_offset_x < 0 && move_to_index > 0) {
}
move_to_index -= 1
} else if (current_offset_x < 0) {
if (move_to_index > 0) {
move_to_index -= 1
}
}
}
// 计算
蛇形线位置和大小
// 计算
偏移百分比
const percentage = Math.abs(current_offset_x) / this.$swiperWidth
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(current_index, move_to_index, percentage)
// this.updateTabIndicator(indicator_line_l, indicator_line_w)
// 首次可见时初始化数据
// 首次可见时初始化数据
this.initSwiperItemPage(move_to_index)
this.initSwiperItemPage(move_to_index)
...
@@ -144,18 +135,29 @@
...
@@ -144,18 +135,29 @@
if (this.swiperIndex === index) {
if (this.swiperIndex === index) {
return
return
}
}
this.swiperIndex = index
this.swiperIndex = index
this.initSwiperItemPage(index)
this.initSwiperItemPage(index)
if (updateIndicator) {
if (updateIndicator) {
this.updateTabIndicator(
this.$swiperTabsRect[index].x, this.$swiperTabsRect[index].w
)
this.updateTabIndicator(
index, index, 1
)
}
}
},
},
updateTabIndicator(left : Number, width : Number) {
updateTabIndicator(current_index : number, move_to_index : number, percentage : number) {
this.swiperIndicatorLineLeft = left
// 计算指示线
this.swiperIndicatorLineWidth = width
const current_size = this.$swiperTabsRect[current_index]
this.tabsScrollLeft = left + width / 2 - this.$swiperWidth / 2
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) {
initSwiperItemPage(index : Number) {
if (!this.swiperList[index].preload) {
if (!this.swiperList[index].preload) {
...
@@ -200,15 +202,8 @@
...
@@ -200,15 +202,8 @@
}
}
.swiper-tabs-indicator {
.swiper-tabs-indicator {
position: relative
;
width: 1px
;
height: 2px;
height: 2px;
}
.swiper-tabs-underline {
position: absolute;
top: 0;
bottom: 0;
width: 0;
background-color: #007AFF;
background-color: #007AFF;
}
}
...
...
pages/template/swiper-list/swiper-list.uvue
浏览文件 @
ad6d6225
<template>
<template>
<view class="swiper-list">
<view class="swiper-list">
<scroll-view ref="tabScroll" class="swiper-tabs" :scroll-x="true" :show-scrollbar="false">
<scroll-view ref="tabScroll" class="swiper-tabs" :scroll-x="true" :show-scrollbar="false">
<!-- TODO 多一层 view -->
<view>
<view>
<view class="flex-row">
<view class="flex-row">
<text ref="swipertab" class="swiper-tabs-item" :class="swiperIndex==index ? 'swiper-tabs-item-active' : ''"
<text ref="swipertab" class="swiper-tabs-item" :class="swiperIndex==index ? 'swiper-tabs-item-active' : ''"
...
@@ -62,10 +63,10 @@
...
@@ -62,10 +63,10 @@
this.setSwiperIndex(index, false)
this.setSwiperIndex(index, false)
},
},
onSwiperTransition(e : SwiperTransitionEvent) {
onSwiperTransition(e : SwiperTransitionEvent) {
// skyline 每项完成触发 Animationfinish,偏移值重置
//
微信
skyline 每项完成触发 Animationfinish,偏移值重置
// webview 全部完成触发 Animationfinish,偏移值累加
//
微信
webview 全部完成触发 Animationfinish,偏移值累加
// 在滑动到下一个项的过程中,再次反向滑动,偏移值递减
// 在滑动到下一个项的过程中,再次反向滑动,偏移值递减
// uni-app-x 和 webview 行为一致
// uni-app-x 和
微信
webview 行为一致
const offset_x = e.detail.dx
const offset_x = e.detail.dx
...
@@ -74,29 +75,21 @@
...
@@ -74,29 +75,21 @@
const current_offset_i = offset_x / this.$swiperWidth
const current_offset_i = offset_x / this.$swiperWidth
const current_index = this.$animationFinishIndex + current_offset_i.toInt()
const current_index = this.$animationFinishIndex + current_offset_i.toInt()
// 边界检查
//
更新索引及
边界检查
let move_to_index = current_index
let move_to_index = current_index
if (current_offset_x > 0) {
if (current_offset_x > 0 && move_to_index < this.swiperList.length - 1) {
if (move_to_index < this.$swiperTabsRect.length - 1) {
move_to_index += 1
move_to_index += 1
} else if (current_offset_x < 0 && move_to_index > 0) {
}
move_to_index -= 1
} else if (current_offset_x < 0) {
if (move_to_index > 0) {
move_to_index -= 1
}
}
}
// 计算
指示线位置和大小
// 计算
偏移百分比
const percentage = Math.abs(current_offset_x) / this.$swiperWidth
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
//
更新指示线位置和大小
//
通知更新指示线
this.updateTabIndicator(
indicator_line_l, indicator_line_w
)
this.updateTabIndicator(
current_index, move_to_index, percentage
)
// console.log(current_index + "->" + move_to_index
+ " x=" + offset_x + " p=" + percentage
)
// console.log(current_index + "->" + move_to_index
+ " p=" + percentage + " x=" + offset_x
)
},
},
onSwiperAnimationfinish(e : SwiperAnimationFinishEvent) {
onSwiperAnimationfinish(e : SwiperAnimationFinishEvent) {
this.setSwiperIndex(e.detail.current, true)
this.setSwiperIndex(e.detail.current, true)
...
@@ -120,13 +113,19 @@
...
@@ -120,13 +113,19 @@
this.swiperIndex = index
this.swiperIndex = index
if (updateIndicator) {
if (updateIndicator) {
this.updateTabIndicator(
this.$swiperTabsRect[index].x, this.$swiperTabsRect[index].w
)
this.updateTabIndicator(
index, index, 1
)
}
}
},
},
updateTabIndicator(left : number, width : number) {
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 =
left + width
/ 2
const x =
indicator_line_l + indicator_line_w
/ 2
this.$indicatorNode?.style?.setProperty('transform', `translateX(${x}px) scaleX(${
width}px
)`)
this.$indicatorNode?.style?.setProperty('transform', `translateX(${x}px) scaleX(${
indicator_line_w}
)`)
// 将指示线滚动到水平中心位置
// 将指示线滚动到水平中心位置
const scroll_x = x - this.$swiperWidth / 2
const scroll_x = x - this.$swiperWidth / 2
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录