sys 2 жил өмнө
parent
commit
0fc4162e24
100 өөрчлөгдсөн 8825 нэмэгдсэн , 1 устгасан
  1. 1 1
      pages/text/index.vue
  2. 21 0
      uni_modules/zebra-swiper/LICENSE
  3. 77 0
      uni_modules/zebra-swiper/README.md
  4. 235 0
      uni_modules/zebra-swiper/changelog.md
  5. 185 0
      uni_modules/zebra-swiper/components/z-swiper-item/z-swiper-item.vue
  6. 744 0
      uni_modules/zebra-swiper/components/z-swiper/z-swiper.vue
  7. 7 0
      uni_modules/zebra-swiper/components/zebra-swiper/zebra-swiper.vue
  8. 26 0
      uni_modules/zebra-swiper/index.js
  9. 39 0
      uni_modules/zebra-swiper/libs/check-overflow/index.js
  10. 52 0
      uni_modules/zebra-swiper/libs/classes/addClasses.js
  11. 6 0
      uni_modules/zebra-swiper/libs/classes/index.js
  12. 9 0
      uni_modules/zebra-swiper/libs/classes/removeClasses.js
  13. 565 0
      uni_modules/zebra-swiper/libs/core.js
  14. 174 0
      uni_modules/zebra-swiper/libs/core.scss
  15. 126 0
      uni_modules/zebra-swiper/libs/defaults.js
  16. 115 0
      uni_modules/zebra-swiper/libs/events-emitter.js
  17. 67 0
      uni_modules/zebra-swiper/libs/events/index.js
  18. 13 0
      uni_modules/zebra-swiper/libs/events/onClick.js
  19. 43 0
      uni_modules/zebra-swiper/libs/events/onResize.js
  20. 35 0
      uni_modules/zebra-swiper/libs/events/onScroll.js
  21. 147 0
      uni_modules/zebra-swiper/libs/events/onTouchEnd.js
  22. 228 0
      uni_modules/zebra-swiper/libs/events/onTouchMove.js
  23. 85 0
      uni_modules/zebra-swiper/libs/events/onTouchStart.js
  24. 6 0
      uni_modules/zebra-swiper/libs/grab-cursor/index.js
  25. 12 0
      uni_modules/zebra-swiper/libs/grab-cursor/setGrabCursor.js
  26. 9 0
      uni_modules/zebra-swiper/libs/grab-cursor/unsetGrabCursor.js
  27. 8 0
      uni_modules/zebra-swiper/libs/loop/index.js
  28. 51 0
      uni_modules/zebra-swiper/libs/loop/loopCreate.js
  29. 8 0
      uni_modules/zebra-swiper/libs/loop/loopDestroy.js
  30. 40 0
      uni_modules/zebra-swiper/libs/loop/loopFix.js
  31. 68 0
      uni_modules/zebra-swiper/libs/mixins/relation.js
  32. 41 0
      uni_modules/zebra-swiper/libs/moduleExtendParams.js
  33. 16 0
      uni_modules/zebra-swiper/libs/slide/index.js
  34. 29 0
      uni_modules/zebra-swiper/libs/slide/slideNext.js
  35. 63 0
      uni_modules/zebra-swiper/libs/slide/slidePrev.js
  36. 4 0
      uni_modules/zebra-swiper/libs/slide/slideReset.js
  37. 188 0
      uni_modules/zebra-swiper/libs/slide/slideTo.js
  38. 46 0
      uni_modules/zebra-swiper/libs/slide/slideToClickedSlide.js
  39. 28 0
      uni_modules/zebra-swiper/libs/slide/slideToClosest.js
  40. 10 0
      uni_modules/zebra-swiper/libs/slide/slideToLoop.js
  41. 8 0
      uni_modules/zebra-swiper/libs/transition/index.js
  42. 9 0
      uni_modules/zebra-swiper/libs/transition/setTransition.js
  43. 35 0
      uni_modules/zebra-swiper/libs/transition/transitionEmit.js
  44. 16 0
      uni_modules/zebra-swiper/libs/transition/transitionEnd.js
  45. 19 0
      uni_modules/zebra-swiper/libs/transition/transitionStart.js
  46. 23 0
      uni_modules/zebra-swiper/libs/translate/getTranslate.js
  47. 12 0
      uni_modules/zebra-swiper/libs/translate/index.js
  48. 3 0
      uni_modules/zebra-swiper/libs/translate/maxTranslate.js
  49. 3 0
      uni_modules/zebra-swiper/libs/translate/minTranslate.js
  50. 51 0
      uni_modules/zebra-swiper/libs/translate/setTranslate.js
  51. 90 0
      uni_modules/zebra-swiper/libs/translate/translateTo.js
  52. 20 0
      uni_modules/zebra-swiper/libs/update/index.js
  53. 102 0
      uni_modules/zebra-swiper/libs/update/updateActiveIndex.js
  54. 53 0
      uni_modules/zebra-swiper/libs/update/updateAutoHeight.js
  55. 35 0
      uni_modules/zebra-swiper/libs/update/updateClickedSlide.js
  56. 50 0
      uni_modules/zebra-swiper/libs/update/updateProgress.js
  57. 28 0
      uni_modules/zebra-swiper/libs/update/updateSize.js
  58. 311 0
      uni_modules/zebra-swiper/libs/update/updateSlides.js
  59. 119 0
      uni_modules/zebra-swiper/libs/update/updateSlidesClasses.js
  60. 11 0
      uni_modules/zebra-swiper/libs/update/updateSlidesOffset.js
  61. 45 0
      uni_modules/zebra-swiper/libs/update/updateSlidesProgress.js
  62. 35 0
      uni_modules/zebra-swiper/libs/utils/utils.js
  63. 50 0
      uni_modules/zebra-swiper/libs/vue2/get-changed-params.js
  64. 57 0
      uni_modules/zebra-swiper/libs/vue2/get-params.js
  65. 40 0
      uni_modules/zebra-swiper/libs/vue2/init-swiper.js
  66. 73 0
      uni_modules/zebra-swiper/libs/vue2/loop.js
  67. 123 0
      uni_modules/zebra-swiper/libs/vue2/params-list.js
  68. 167 0
      uni_modules/zebra-swiper/libs/vue2/update-swiper.js
  69. 60 0
      uni_modules/zebra-swiper/libs/vue2/utils.js
  70. 44 0
      uni_modules/zebra-swiper/libs/vue2/virtual.js
  71. 210 0
      uni_modules/zebra-swiper/modules/autoplay/autoplay.js
  72. 130 0
      uni_modules/zebra-swiper/modules/effect-cards/effect-cards.js
  73. 8 0
      uni_modules/zebra-swiper/modules/effect-cards/effect-cards.scss
  74. 66 0
      uni_modules/zebra-swiper/modules/effect-carousel/effect-carousel.js
  75. 6 0
      uni_modules/zebra-swiper/modules/effect-carousel/effect-carousel.scss
  76. 110 0
      uni_modules/zebra-swiper/modules/effect-coverflow/effect-coverflow.js
  77. 3 0
      uni_modules/zebra-swiper/modules/effect-coverflow/effect-coverflow.scss
  78. 178 0
      uni_modules/zebra-swiper/modules/effect-creative/effect-creative.js
  79. 9 0
      uni_modules/zebra-swiper/modules/effect-creative/effect-creative.scss
  80. 191 0
      uni_modules/zebra-swiper/modules/effect-cube/effect-cube.js
  81. 49 0
      uni_modules/zebra-swiper/modules/effect-cube/effect-cube.scss
  82. 78 0
      uni_modules/zebra-swiper/modules/effect-fade/effect-fade.js
  83. 11 0
      uni_modules/zebra-swiper/modules/effect-fade/effect-fade.scss
  84. 104 0
      uni_modules/zebra-swiper/modules/effect-flip/effect-flip.js
  85. 20 0
      uni_modules/zebra-swiper/modules/effect-flip/effect-flip.scss
  86. 63 0
      uni_modules/zebra-swiper/modules/effect-panorama/effect-panorama.js
  87. 3 0
      uni_modules/zebra-swiper/modules/effect-panorama/effect-panorama.scss
  88. 241 0
      uni_modules/zebra-swiper/modules/free-mode/free-mode.js
  89. 188 0
      uni_modules/zebra-swiper/modules/navigation/navigation.js
  90. 49 0
      uni_modules/zebra-swiper/modules/navigation/navigation.scss
  91. 510 0
      uni_modules/zebra-swiper/modules/pagination/pagination.js
  92. 149 0
      uni_modules/zebra-swiper/modules/pagination/pagination.scss
  93. 390 0
      uni_modules/zebra-swiper/modules/scrollbar/scrollbar.js
  94. 38 0
      uni_modules/zebra-swiper/modules/scrollbar/scrollbar.scss
  95. 240 0
      uni_modules/zebra-swiper/modules/thumbs/thumbs.js
  96. 10 0
      uni_modules/zebra-swiper/modules/thumbs/thumbs.scss
  97. 319 0
      uni_modules/zebra-swiper/modules/virtual/virtual.js
  98. 17 0
      uni_modules/zebra-swiper/modules/virtual/virtual.scss
  99. 20 0
      uni_modules/zebra-swiper/modules/will-change/will-change.js
  100. 96 0
      uni_modules/zebra-swiper/package.json

+ 1 - 1
pages/text/index.vue

@@ -1,6 +1,6 @@
 <template>
 	<view>
-		<user-content></user-content>
+
 	</view>
 </template>
 

+ 21 - 0
uni_modules/zebra-swiper/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 zebra-ui
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 77 - 0
uni_modules/zebra-swiper/README.md

@@ -0,0 +1,77 @@
+<p align="center">
+	<img alt="logo" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/logo.png" width="220" style="margin-bottom: 10px;">
+</p>
+
+<h1 align="center">ZebraSwiper</h1>
+
+<p align="center">基于uniapp,全面对标swiper,并实现全端兼容。</p>
+
+<p align="center">
+	🔥 <a href="https://swiper.zebraui.com/">文档网站</a>
+	&nbsp;
+	&nbsp;
+	🚀 <a href="https://zebraui.com/" target="_blank">zebraUI组件库</a>
+</p>
+
+## 介绍
+
+[zebra-swiper](https://github.com/zebra-ui/zebra-uniapp-swiper) 是基于uniapp开发的一款移动端轮播组件,已实现swiper组件90%的功能。
+
+[uniapp](https://uniapp.dcloud.io/README)的[swiper](https://uniapp.dcloud.io/component/swiper)组件存在很大的局限性,无法完成一些复杂的轮播效果。
+
+而zebra-swiper不仅可以实现一些3D轮播效果,还可以通过参数来定义你想要的效果。
+
+## 特性
+
+- 全面对标swiper,并实现全端兼容
+- 兼容多端,小程序也可以实现3D轮播效果
+- 可自定义3D效果
+- 多种示例,总有一种适合你
+
+## 安装
+
+### npm方式
+
+```bash
+npm i @zebra-ui/swiper
+```
+
+```js
+// pages.json
+
+{
+	"easycom": {
+		"^z-(.*)": "@zebra-ui/swiper/components/z-$1/z-$1.vue"
+	},
+	"pages": [...],
+	"globalStyle": {...}
+}
+```
+
+### uni_modules方式
+
+[插件市场](https://ext.dcloud.net.cn/plugin?id=7273)直接导入即可
+
+## 手机预览
+
+<div>
+	<img alt="wx" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/wx.jpg" width="200" />
+	<img alt="ali" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/ali.jpg" width="200" />
+	<img alt="h5" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/h5.png" width="200" />
+</div>
+
+## 预览
+<div style="display:flex;flex-wrap:wrap;margin-top:30px;">
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif1.gif" width="300" style="margin:20px;" />
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif2.gif" width="300" style="margin:20px;" />
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif3.gif" width="300" style="margin:20px;" />
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif4.gif" width="300" style="margin:20px;" />
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif5.gif" width="300" style="margin:20px;" />
+ <img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif6.gif" width="300" style="margin:20px;" />
+</div>
+
+## 群
+
+QQ群:947159437
+
+![image](https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/zebra-swiper-group-code.png)

+ 235 - 0
uni_modules/zebra-swiper/changelog.md

@@ -0,0 +1,235 @@
+## 2.2.6(2023-02-20)
+`2023-02-20`
+
+**Feat**
+
+- `panorama`全景切换效果新增`stretch`参数,用于控制slide之间的距离。
+
+**Fix**
+
+- 修复字节小程序3D样式失效的问题。
+- 修复`panorama`切换效果参数无效的问题。
+- 修复`autoHeight`高度自适应使用报错的问题。(`autoHeight`选项可以正常使用,且在大多数场景下可以正确获取高度)
+## 2.2.5(2022-11-10)
+`2022-11-10`
+
+**Feat**
+
+- `cards`卡片切换效果新增`perSlideRotate`,`perSlideOffset`参数用于控制卡片的偏移距离及旋转角度。
+- 微信小程序中默认使用虚拟节点渲染,即`virtualHost`: `true`。
+
+**Fix**
+
+- 修复`pagination`选项开启后,动态控制`swiper`禁用或启用报错的问题。
+- 修复支付宝小程序3D样式失效的问题。
+## 2.2.4(2022-09-23)
+`2022-09-23`
+
+**Feat**
+
+- 新增`noSwiping`参数控制是否禁止触摸。当禁止触摸开启时,不可通过滑动切换。可通过自动切换,`slideTo`等方法切换。
+
+**Fix**
+
+- 修复`vue3`下`app`触摸无效的问题。
+- 新增触摸事件`touchcancel`。
+## 2.2.3(2022-07-26)
+`2022-07-26`
+
+**Feat**
+
+- 卡片切换效果`cards`新增`rotate`参数,用于控制卡片切换时是否发生旋转。
+
+**Fix**
+
+- 修复微信小程序使用`zebra-swiper`时,页面无法滚动。
+- 修复`app`报错`toJSON`的问题。
+- 修复`swiper`在`vue3`中无法自动播放的问题。
+
+## 2.2.2(2022-07-01)
+`2022-07-01`
+
+**Feat**
+
+- 兼容`PC`浏览器端。
+- 初步兼容`VUE3`。
+
+**Fix**
+
+- 修复使用`zebra-swiper`时,页面无法滚动。(`zebra-swiper`将不再默认阻止事件冒泡)。
+## 2.2.1(2022-03-31)
+`2022-03-31`
+
+**Feat**
+
+- 新增`changeDirection`方法,该方法用于动态改变swiper方向。
+- `z-swiper-item`新增`swiperItemWidth` `swiperItemHeight` 属性,用于在swiper无法正确获取宽高的情况下设置swiper的宽高(如快手小程序)。
+
+**Fix**
+
+- 消除快手小程序itemPropWxs的警告。
+## 2.2.0(2022-03-21)
+`2022-03-21`
+
+**本次更新调整了组件的整体架构及组件入口逻辑。主要为性能优化,不涉及新功能。**
+
+不兼容性更新:
+
+- `z-swiper` 的 `customStyle` 由字符串类型更改为Object类型(与`z-swiper-item`保持一致)。
+- `z-swiper-item` 删除了加载的效果。
+
+**Fix**
+
+- 修复因数据改变而无法正确触发更新的问题。
+- 修复方法 `disable` `enable`  提示未定义的问题。
+
+**Perf**
+
+- 组件首次渲染速度优化。
+- loop模式处理数据后才开始加载swiper,确保数据的一致性。
+- 部分同步方法更改为异步,体验更流畅。
+## 2.1.4(2022-03-05)
+`2022-03-05`
+
+**Feat**
+
+- 高级案例加入开屏页。[点击预览](https://swiper.zebraui.com/h5/pages/demos/paper/index)
+
+**Fix**
+
+- 修复百度小程序高度计算错误的问题。
+## 2.1.3(2022-03-03)
+`2022-03-03`
+
+**Feat**
+
+- 新增高级案例模块。
+- 高级案例加入环游地球。[点击预览](https://swiper.zebraui.com/h5/pages/demos/travel-slider/index)
+- 微信小程序,qq小程序使用wxs赋值样式。
+## 2.1.2(2022-03-02)
+`2022-03-02`
+
+本次改版涉及所有开启loop的功能。请更新后删除手动拼接的数据。
+
+**Feat**
+
+- loop无限循环模式无需再手动拼接数据。
+## 2.1.1(2022-03-01)
+`2022-03-01`
+
+**Fix**
+
+- 修复字节小程序轮播内容不显示的问题。
+- 修复字节小程序获取位置信息错误的问题。
+
+**Docs**
+
+- [文档新增事件。](https://swiper.zebraui.com/basic/events/)
+## 2.1.0(2022-02-27)
+`2022-02-27`
+
+更新须知
+
+使用组件时,需在z-swiper标签上以`v-model`的形式传入list数据,也就是要循环的列表数据,该属性为强制性,不加会导致意外错误。例:
+
+之前的方式:
+
+```vue
+<z-swiper>
+        <z-swiper-item v-for="(item,index) in list" :key="index">
+		<image class="image" :src="item" mode="aspectFill">
+		</image>
+	</z-swiper-item>
+</z-swiper>
+```
+
+现在的方式:
+
+```vue
+<z-swiper v-model="list"> //这里传入的需和下方循环的保持一致
+	<z-swiper-item v-for="(item,index) in list" :key="index">
+		<image class="image" :src="item" mode="aspectFill">
+		</image>
+	</z-swiper-item>
+</z-swiper>
+```
+
+这个操作也为swiper接管数据操作铺垫,对后续很多新功能非常有用,也为loop无限循环的痛点提供了解决方案。
+
+**Fix**
+
+- 修复数据为空时报错。
+- 修复请求数据时swiper提前初始化的问题。
+
+**Feat**
+
+- 新增滚动条功能。
+## 2.0.1(2022-02-25)
+`2022-02-25`
+
+**Fix**
+
+- 修复插槽内容class样式不生效问题。
+
+**Feat**
+
+- 新增缩略图功能。
+## 2.0.0(2022-02-24)
+`2022-02-24`
+
+**Feat**
+
+- 该版本为破坏性改版,无法兼容1.0。
+- 代码重构,使用模块化将功能分割,大幅提升性能,方便后续维护。
+- 全面对标swiper组件,并实现全端兼容。小程序也可实现炫酷的轮播效果。
+- 所有切换效果全部支持loop无限循环。
+- 新增全景切换效果。
+- 新增轮播块功能,可自定义显示数量。
+- 新增进度条指示器。
+## 1.0.7(2022-01-25)
+`2022-01-25`
+
+**Feat**
+
+- 新增轮播切换器功能,可使用默认切换或自定义切换。
+- 示例项目新增切换器的使用及自定义切换器。
+## 1.0.6(2022-01-24)
+`2022-01-24`
+
+**Chore**
+
+- 示例项目新增指示器的使用及自定义指示器。
+## 1.0.5(2022-01-21)
+`2022-01-21`
+
+**Docs**
+
+- README.md新增手机预览,包含微信,支付宝小程序码,H5二维码。
+## 1.0.4(2022-01-20)
+`2022-01-20`
+
+**Style**
+
+- 示例项目首页px统一修改为rpx。
+## 1.0.3(2022-01-19)
+`2022-01-19`
+
+**Fix**
+
+- 修复轮播设置为纵向时,高度错误的问题。
+- 修复在百度小程序中样式错乱的问题。
+
+## 1.0.2(2022-01-18)
+`2022-01-18`
+**Docs**
+
+- README.md新增gif预览图
+- 修复因未知原因引起的uni_modules组件上传错误的问题。
+
+`2022-01-14`
+### [v1.0.1](https://github.com/zebra-ui/zebra-uniapp-swiper)
+**Feature**
+
+- 新增zebra-swiper,zebra-swiper-item组件。
+- 新增多种3D切换效果。包括渐变,方块,3D流,翻转,卡片,创意性等多种切换效果。
+- 新增[示例项目](https://swiper.zebraui.com),包含多种切换效果示例。

+ 185 - 0
uni_modules/zebra-swiper/components/z-swiper-item/z-swiper-item.vue

@@ -0,0 +1,185 @@
+<template>
+	<!-- #ifndef MP-WEIXIN || MP-QQ -->
+	<view :class="['swiper-slide',slideClass]" :style="[itemStyle,customStyle]" @click.stop="onClickSlide">
+		<!-- #endif -->
+		<!-- #ifdef MP-WEIXIN || MP-QQ -->
+		<view :class="['swiper-slide',slideClass]" :style="[itemStyle,customStyle]" @click.stop="onClickSlide"
+			:swiperItemTransform="wxsItemTransform" :change:swiperItemTransform="zSwiperWxs.wxsItemTransformObserver">
+			<!-- #endif -->
+			<slot></slot>
+		</view>
+</template>
+<!-- #ifdef MP-WEIXIN || MP-QQ  -->
+<script src="../../wxs/z-swiper-wxs.wxs" module="zSwiperWxs" lang="wxs"></script>
+<!-- #endif -->
+<script>
+	import {
+		ChildrenMixin
+	} from '../../libs/mixins/relation.js';
+	import {
+		getRect
+	} from '../../libs/utils/utils.js';
+	export default {
+		name: "z-swipe-item",
+		// #ifdef MP-WEIXIN
+		options: {
+			virtualHost: true
+		},
+		// #endif
+		mixins: [ChildrenMixin('zSwipe')],
+		props: {
+			customStyle: {
+				type: Object,
+				default: () => {
+					return {};
+				}
+			},
+			swiperItemWidth: {
+				type: [String, Number],
+				default: 0
+			},
+			swiperItemHeight: {
+				type: [String, Number],
+				default: 0
+			},
+		},
+		data() {
+			return {
+				wxsItemTransform: "",
+				itemStyle: {},
+				offsetLeft: 0,
+				offsetTop: 0,
+				itemClass: [],
+				width: 0,
+				height: 0,
+			};
+		},
+		mounted() {
+			this.getSize();
+		},
+		computed: {
+			slideClass() {
+				return this.itemClass.join(" ");
+			}
+		},
+		watch: {
+			swiperItemWidth: {
+				handler(val) {
+					if (val) {
+						this.$set(this.itemStyle, 'width', this.unitFormat(val, "rpx"))
+					}
+				},
+				immediate: true
+			},
+			swiperItemHeight: {
+				handler(val) {
+					if (val) {
+						this.$set(this.itemStyle, 'height', this.unitFormat(val, "rpx"))
+					}
+				},
+				immediate: true
+			}
+		},
+		methods: {
+			unitFormat(val, type) {
+				if (type == "rpx") {
+					if (val.includes("rpx") || val.includes("px")) {
+						return val;
+					} else {
+						return val + 'px';
+					}
+				}
+				if (type == "number") {
+					if (val.includes("rpx")) {
+						return uni.upx2px(parseInt(val.replace("rpx", "")))
+					} else if (!val.includes("rpx") && val.includes("px")) {
+						return parseInt(val.replace("px", ""))
+					} else {
+						return val;
+					}
+				}
+			},
+			onClickSlide(event) {
+				this.$emit("click", {
+					event,
+					index: this.index
+				});
+				this.parent.swiper.updateClickedSlide(this.index);
+				this.parent.swiper.emit("slideClick", this.index);
+			},
+			transform(value) {
+				// #ifndef MP-WEIXIN || MP-QQ
+				this.$set(this.itemStyle, 'transform', value)
+				// #endif
+				// #ifdef MP-WEIXIN || MP-QQ
+				this.wxsItemTransform = value
+				// #endif
+			},
+			transition(value) {
+				// #ifdef MP-BAIDU
+				this.$set(this.itemStyle, 'transitionDuration', `${value}ms`)
+				// #endif
+				// #ifndef MP-BAIDU
+				this.$set(this.itemStyle, 'transition-duration', `${value}ms`)
+				// #endif
+			},
+			willChange(value) {
+				this.$set(this.itemStyle, 'will-change', value)
+			},
+			css(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.itemStyle, item, value[item])
+				})
+			},
+			transitionEnd(callback, duration) {
+				setTimeout(callback, duration)
+			},
+			getSize() {
+				const query = uni.createSelectorQuery().in(this);
+				return new Promise((resolve, reject) => {
+					query.select('.swiper-slide').boundingClientRect(data => {
+						if (this.swiperItemWidth) {
+							this.width = this.unitFormat(this.swiperItemWidth, "number");
+							this.height = data.height;
+						}
+						if (this.swiperItemHeight) {
+							this.width = data.width;
+							this.height = this.unitFormat(this.swiperItemHeight, "number");
+						}
+						if (!this.swiperItemWidth && !this.swiperItemHeight) {
+							this.width = data.width;
+							this.height = data.height;
+						}
+						resolve({
+							width: this.width,
+							height: this.height
+						})
+					}).exec();
+				})
+			},
+			addClass(value) {
+				this.itemClass = Array.from(new Set([...this.itemClass, ...value.split(" ")]));
+			},
+			removeClass(value) {
+				this.itemClass = this.itemClass.filter(item => !value.split(" ").includes(item));
+			},
+			hasClass(value) {
+				return this.itemClass.includes(value);
+			},
+			nextAll() {
+				return this.parent.children.filter((item) => {
+					return item.index > this.index
+				})
+			},
+			prevAll() {
+				return this.parent.children.filter((item) => {
+					return item.index < this.index
+				}).reverse()
+			},
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	@import '../../libs/core.scss';
+</style>

+ 744 - 0
uni_modules/zebra-swiper/components/z-swiper/z-swiper.vue

@@ -0,0 +1,744 @@
+<template>
+	<view :id="'swiper'+_uid"
+		:class="['swiper',contentClass,containerClasses,options.direction === 'vertical'?'swiper-vertical':'']"
+		:style="[customStyle]">
+		<!-- #ifndef MP-WEIXIN || MP-QQ -->
+		<view :class="['swiper-wrapper']" :style="[wrapperStyle]" @click="onClickWrapper" @touchstart="onTouchStart"
+			@touchmove="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
+			<!-- #endif -->
+			<!-- #ifdef MP-WEIXIN || MP-QQ -->
+			<view :class="['swiper-wrapper']" :style="[wrapperStyle]" @click="onClickWrapper"
+				@touchstart="zSwiperWxs.onTouchStartWxs" @touchmove="zSwiperWxs.onTouchMoveWxs"
+				@touchend="zSwiperWxs.onTouchEndWxs" @touchcancel="zSwiperWxs.onTouchEndWxs"
+				:swiperTransform="wxsTransform" :change:swiperTransform="zSwiperWxs.wxsTransformObserver">
+				<!-- #endif -->
+				<slot></slot>
+				<!-- 在loop模式下,为group填充空白slide -->
+				<template v-if="loopBlankShow">
+					<z-swiper-item v-for="(item,index) in loopBlankNumber" :key="index">
+					</z-swiper-item>
+				</template>
+				<template v-if="cubeShadowShowWrapper">
+					<view class="swiper-cube-shadow" :style="[cubeShadowStyle]"></view>
+				</template>
+			</view>
+			<template v-if="cubeShadowShowRoot">
+				<view class="swiper-cube-shadow" :style="[cubeShadowStyle]"></view>
+			</template>
+			<slot name="indicator"></slot>
+			<template v-if="showIndicators">
+				<view :class="['swiper-pagination',paginationClass]" :style="[paginationStyle]">
+					<template v-if="paginationType == 'bullets'">
+						<view v-for="(item,index) in paginationContent" :key="index"
+							:class="[item.classContent.join(' ')]" :style="[item.styleContent]"
+							@click="paginationItemClick(index)">
+						</view>
+					</template>
+					<template v-if="paginationType == 'fraction'">
+						<text :class="paginationContent.currentClass">{{paginationContent.text}}</text>/<text
+							:class="paginationContent.totalClass">{{paginationContent.total}}</text>
+					</template>
+					<template v-if="paginationType == 'progressbar'">
+						<text :class="paginationContent.progressbarFillClass"
+							:style="[paginationContent.styleContent]"></text>
+					</template>
+				</view>
+			</template>
+			<template v-if="(showPrevButton||showPrevButtonSlot)">
+				<view :class="['swiper-button-prev',prevClass]" @click="prevClick">
+					<view v-if="!showPrevButtonSlot" class="zebra-icon zebra-icon-circle_chevron_left"></view>
+					<slot v-else name="pre-button"></slot>
+				</view>
+			</template>
+			<template v-if="(showNextButton||showNextButtonSlot)">
+				<view :class="['swiper-button-next',nextClass]" @click="nextClick">
+					<view v-if="!showNextButtonSlot" class="zebra-icon zebra-icon-circle_chevron_right"></view>
+					<slot v-else name="next-button"></slot>
+				</view>
+			</template>
+			<template v-if="scrollbarShow">
+				<view :class="['swiper-scrollbar',scrollbarClass]" :style="[scrollbarStyle]"
+					@click.stop="onClickScrollbar" @touchstart.stop="onTouchStartScrollbar"
+					@touchmove.stop.prevent="onTouchMoveScrollbar" @touchend.stop="onTouchEndScrollbar">
+					<view class="swiper-scrollbar-drag" :style="[scrollbarItemStyle]">
+
+					</view>
+				</view>
+			</template>
+		</view>
+</template>
+<!-- #ifdef MP-WEIXIN || MP-QQ -->
+<script src="../../wxs/z-swiper-wxs.wxs" module="zSwiperWxs" lang="wxs"></script>
+<!-- #endif -->
+<script>
+	import {
+		getAllRect,
+		getRect
+	} from '../../libs/utils/utils.js';
+	// vue2
+	import {
+		getParams
+	} from '../../libs/vue2/get-params.js';
+	import {
+		initSwiper,
+		mountSwiper
+	} from '../../libs/vue2/init-swiper.js';
+	import {
+		needsScrollbar,
+		needsNavigation,
+		needsPagination,
+		uniqueClasses,
+		extend,
+	} from '../../libs/vue2/utils.js';
+	import {
+		renderLoop,
+		calcLoopedSlides
+	} from '../../libs/vue2/loop.js';
+	import {
+		getChangedParams
+	} from '../../libs/vue2/get-changed-params.js';
+	import {
+		updateSwiper
+	} from '../../libs/vue2/update-swiper.js';
+	import {
+		renderVirtual,
+		updateOnVirtualData
+	} from '../../libs/vue2/virtual.js';
+	//mixin
+	import {
+		ParentMixin
+	} from '../../libs/mixins/relation.js';
+
+	export default {
+		name: "z-swipe",
+		// #ifdef MP-WEIXIN
+		options: {
+			virtualHost: true
+		},
+		// #endif
+		mixins: [
+			ParentMixin('zSwipe')
+		],
+		// #ifdef VUE3
+		emits: ['update:modelValue', 'touch-start', 'touch-move', 'touch-end', 'transitionend', 'slideClick',
+			'_beforeBreakpoint',
+			'_containerClasses',
+			'_slideClass',
+			'_slideClasses', '_swiper',
+			'activeIndexChange', 'afterInit', 'autoplay', 'autoplayStart', 'autoplayStop', 'autoplayPause',
+			'autoplayResume', 'beforeDestroy', 'beforeInit', 'beforeLoopFix', 'beforeResize', 'beforeSlideChangeStart',
+			'beforeTransitionStart', 'breakpoint', 'changeDirection', 'click', 'disable', 'doubleTap', 'doubleClick',
+			'destroy', 'enable', 'fromEdge', 'hashChange', 'hashSet', 'imagesReady', 'init', 'keyPress',
+			'lazyImageLoad', 'lazyImageReady', 'lock', 'loopFix', 'momentumBounce', 'navigationHide', 'navigationShow',
+			'observerUpdate', 'orientationchange', 'paginationHide', 'paginationRender', 'paginationShow',
+			'paginationUpdate', 'progress', 'reachBeginning', 'reachEnd', 'realIndexChange', 'resize', 'scroll',
+			'scrollbarDragEnd', 'scrollbarDragMove', 'scrollbarDragStart', 'setTransition', 'setTranslate',
+			'slideChange', 'slideChangeTransitionEnd', 'slideChangeTransitionStart', 'slideNextTransitionEnd',
+			'slideNextTransitionStart', 'slidePrevTransitionEnd', 'slidePrevTransitionStart',
+			'slideResetTransitionStart', 'slideResetTransitionEnd', 'sliderMove', 'sliderFirstMove',
+			'slidesLengthChange', 'slidesGridLengthChange', 'snapGridLengthChange', 'snapIndexChange', 'swiper', 'tap',
+			'toEdge', 'touchEnd', 'touchMove', 'touchMoveOpposite', 'touchStart', 'transitionEnd', 'transitionStart',
+			'unlock', 'update', 'zoomChange', 'beforeMount'
+		],
+		// #endif
+		props: {
+			customStyle: {
+				type: Object,
+				default: () => {
+					return {};
+				}
+			},
+			options: {
+				type: Object,
+				default: () => {
+					return {}
+				}
+			},
+			// #ifdef VUE2
+			value: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			// #endif
+			// #ifdef VUE3
+			modelValue: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			}
+			// #endif
+		},
+		data() {
+			return {
+				wxsTransform: "",
+				wrapperStyle: {},
+				contentClass: '',
+				nextElClass: [],
+				prevElClass: [],
+				paginationElClass: [],
+				paginationItemElClass: [],
+				loopBlankShow: false,
+				loopBlankNumber: 0,
+				cubeShadowShowWrapper: false,
+				cubeShadowShowRoot: false,
+				cubeShadowStyle: {},
+				eventsListeners: {},
+				showPrevButton: false,
+				showPrevButtonSlot: false,
+				showNextButton: false,
+				showNextButtonSlot: false,
+				showIndicators: false,
+				paginationContent: [],
+				paginationType: '',
+				paginationStyle: {},
+				scrollbarElClass: [],
+				scrollbarStyle: {},
+				scrollbarItemStyle: {},
+				rectInfo: null,
+
+				// vue2
+				containerClasses: 'swiper',
+				virtualData: null,
+				firstLoad: true,
+				originalDataList: [],
+				loopUpdateData: false
+			};
+		},
+		computed: {
+			// #ifdef VUE3
+			value() {
+				return this.modelValue
+			},
+			// #endif
+			// #ifdef VUE3
+			_uid() {
+				return this._.uid
+			},
+			// #endif
+			nextClass() {
+				return this.nextElClass.join(" ");
+			},
+			prevClass() {
+				return this.prevElClass.join(" ");
+			},
+			paginationClass() {
+				return this.paginationElClass.join(" ");
+			},
+			paginationItemClass() {
+				return this.paginationItemElClass.join(" ");
+			},
+			scrollbarClass() {
+				return this.scrollbarElClass.join(" ");
+			},
+			scrollbarShow() {
+				return needsScrollbar(this.options)
+			}
+		},
+		created() {
+			const {
+				params: swiperParams,
+				passedParams
+			} = getParams(this.options);
+			this.swiperElRef = 'swiper';
+			this.swiperParams = swiperParams;
+			this.oldPassedParamsRef = passedParams;
+			let slidesRef = this.slidesRef;
+
+			swiperParams.onAny = (event, ...args) => {
+				// #ifdef MP
+				// 字节小程序此处报错,因此无法使用v-on监听事件
+				// #ifndef MP-TOUTIAO
+				this.$emit(event, {}, ...args.filter((item, index) => {
+					return index > 0
+				}));
+				// #endif
+				// #endif
+				// #ifndef MP
+				this.$emit(event, ...args);
+				// #endif
+			};
+			Object.assign(swiperParams.on, {
+				_containerClasses(swiper, classes) {
+					this.containerClasses = classes;
+				},
+			});
+			this.$watch(() => {
+				return {
+					value: this.value,
+					options: this.options
+				}
+			}, (val) => {
+				// virtual模式处理
+				if (this.swiperParams && this.swiperParams.virtual) {
+					if (!this.virtualData && val.options.virtual.slides.length) {
+						this.swiperParams.virtual.slides = val.options.virtual.slides;
+						// this.swiperParams.virtual.slides = val.value;
+						const extendWith = {
+							cache: false,
+							slides: val.options.virtual.slides,
+							// slides: val.value,
+							renderExternal: data => {
+								console.log("最终数据", data)
+								this.virtualData = data;
+								this.$emit("input", data.slides);
+								// updateOnVirtualData(this.swiper);
+							},
+							renderExternalUpdate: false
+						};
+						extend(this.swiperParams.virtual, extendWith);
+						// this.$emit("input", [val.options.virtual.slides[0]]);
+						// this.virtualData = [val.options.virtual.slides[0]];
+						this.loadSwiper();
+						// console.log(this.swiper)
+					}
+					// extend(swiperRef.originalParams.virtual, extendWith);
+				}
+				// loop模式处理
+				if (this.swiperParams && this.swiperParams.loop) {
+					if (this.originalDataList.length && (this.originalDataList.toString() == val.value
+							.toString())) {
+						this.loopUpdateData = true;
+						// 百度小程序watch晚于子组件加载
+						// #ifdef MP-BAIDU
+						if (this.firstLoad) {
+							this.loadSwiper();
+						}
+						// #endif
+					} else {
+						this.loopUpdateData = false;
+						let slides = renderLoop(this, this.swiperParams, this.value);
+						if (this.swiperParams.loop && !this.loopUpdateData && slides.data.toString() !=
+							val.value.toString()) {
+							this.loopUpdateData = true;
+							// #ifdef VUE2
+							this.$emit("input", slides.data)
+							// #endif
+							// #ifdef VUE3
+							this.$emit("update:modelValue", slides.data)
+							// #endif
+							return
+						}
+					}
+				}
+				if (this.swiper && !this.firstLoad) {
+					if (this.virtualData && val.options.virtual.type == "cut") {
+						const style = this.swiper.isHorizontal() ? {
+							[this.swiper.rtlTranslate ? 'right' :
+								'left'
+							]: `${this.virtualData.offset}px`
+						} : {
+							top: `${this.virtualData.offset}px`
+						};
+						this.children
+							// .filter((slide, index) => index >= this.virtualData.from && index <= this
+							// 	.virtualData
+							// 	.to)
+							.map(slide => {
+								slide.css(style)
+								// if (!slide.props) slide.props = {};
+								// if (!slide.props.style) slide.props.style = {};
+								// slide.props.swiperRef = swiperRef;
+								// slide.props.style = style;
+								// return h(slide.type, {
+								// 	...slide.props
+								// }, slide.children);
+							});
+
+					}
+
+
+					this.updateSwiper(val.value, val.options, this.children);
+				}
+			}, {
+				deep: true,
+				immediate: true
+			})
+			this.$watch(() => {
+				return this.$data
+			}, (val) => {
+				if (this.swiper && this.swiper.native) {
+					Object.assign(this.swiper.native, {
+						val
+					});
+				}
+			}, {
+				deep: true
+			})
+			this.$watch(() => {
+				return this.virtualData
+			}, (val) => {
+				if (this.swiper && this.virtualData) {
+					updateOnVirtualData(this.swiper);
+				}
+			}, {
+				deep: true
+			})
+			uni.$on("childrenReady" + this._uid, async (children) => {
+				children.dataSwiperSlideIndex = children.index;
+				if (this.children.length == this.value.length) {
+					Promise.all(this.children.map((item) => {
+						return item.getSize();
+					})).then((res) => {
+						if (this.swiperParams && this.swiperParams.loop) {
+							if (this.originalDataList.length && (this.originalDataList
+									.toString() == this.value
+									.toString())) {
+								if (this.firstLoad) {
+									this.loadSwiper();
+								}
+							} else {
+								return
+							}
+						} else {
+							if (this.firstLoad) {
+								this.loadSwiper();
+							}
+						}
+						this.updateSwiper(this.value, this.options, this.children);
+					})
+				}
+			})
+		},
+		// #ifdef VUE2
+		beforeDestroy() {
+			if (this.swiper && !this.swiper.destroyed) {
+				this.swiper.destroy(true, false);
+			}
+		},
+		// #endif
+		// #ifdef VUE3
+		beforeUnmount() {
+			if (this.swiper && !this.swiper.destroyed) {
+				this.swiper.destroy(true, false);
+			}
+		},
+		// #endif
+		methods: {
+			loadSwiper() {
+				let swiperParams = this.swiperParams;
+				this.slidesRef = this.children;
+				this.oldSlidesRef = this.slidesRef;
+				let swiperRef = initSwiper(swiperParams, {
+					...this.$data,
+					...this.$props,
+					swiperElId: 'swiper' + this._uid,
+					emit: this.emit.bind(this),
+					updateData: this.updateData.bind(this),
+					getRect: this.getRect.bind(this),
+					getRectScrollbar: this.getRectScrollbar.bind(this),
+					willChange: this.willChange.bind(this),
+					transform: this.transform.bind(this),
+					transition: this.transition.bind(this),
+					scrollbarTransform: this.scrollbarTransform.bind(this),
+					scrollbarTransition: this.scrollbarTransition.bind(this),
+					scrollbarItemTransform: this.scrollbarItemTransform.bind(this),
+					scrollbarItemTransition: this.scrollbarItemTransition.bind(this),
+					addClass: this.addClass.bind(this),
+					removeClass: this.removeClass.bind(this),
+					addPaginationClass: this.addPaginationClass.bind(this),
+					removePaginationClass: this.removePaginationClass.bind(this),
+					addScrollbarClass: this.addScrollbarClass.bind(this),
+					removeScrollbarClass: this.removeScrollbarClass.bind(this),
+					setCss: this.setCss.bind(this),
+					css: this.setCss.bind(this),
+					paginationCss: this.setPaginationCss.bind(this),
+					scrollbarCss: this.scrollbarCss.bind(this),
+					scrollbarItemCss: this.scrollbarItemCss.bind(this),
+					addNextElClass: this.addNextElClass.bind(this),
+					addPrevElClass: this.addPrevElClass.bind(this),
+					removeNextElClass: this.removeNextElClass.bind(this),
+					removePrevElClass: this.removePrevElClass.bind(this),
+					cubeShadowCss: this.cubeShadowCss.bind(this),
+					cubeShadowTransform: this.cubeShadowTransform.bind(this),
+					cubeShadowTransition: this.cubeShadowTransition.bind(this),
+				});
+				this.swiper = swiperRef;
+				swiperRef.loopCreate = () => {};
+				swiperRef.loopDestroy = () => {};
+				if (swiperParams.loop) {
+					swiperRef.loopedSlides = calcLoopedSlides(this.slidesRef, swiperParams);
+				}
+
+				if (!this.swiper) return;
+				mountSwiper({
+						el: this.swiperElRef,
+						nextEl: this.nextElRef,
+						prevEl: this.prevElRef,
+						paginationEl: this.paginationElRef,
+						scrollbarEl: this.scrollbarElRef,
+						swiper: this.swiper,
+					},
+					this.swiperParams,
+				);
+				this.$emit('swiper');
+				this.firstLoad = false;
+			},
+			updateSwiper(value, options, children) {
+				this.swiper.slides = children;
+				this.slidesRef = children;
+				let initializedRef = this.initializedRef;
+				let swiperRef = this.swiper;
+				let slidesRef = this.slidesRef;
+				let oldPassedParamsRef = this.oldPassedParamsRef;
+				let oldSlidesRef = this.oldSlidesRef;
+				let breakpointChanged = this.breakpointChanged;
+				let nextElRef = this.nextElRef;
+				let prevElRef = this.prevElRef;
+				let paginationElRef = this.paginationElRef;
+				let scrollbarElRef = this.scrollbarElRef;
+				// set initialized flag
+				if (!initializedRef && swiperRef) {
+					swiperRef.emitSlidesClasses();
+					initializedRef = true;
+				}
+				// watch for params change
+				const {
+					passedParams: newPassedParams
+				} = getParams(options);
+				const changedParams = getChangedParams(
+					newPassedParams,
+					oldPassedParamsRef,
+					slidesRef,
+					oldSlidesRef,
+				);
+				this.oldPassedParamsRef = newPassedParams;
+				this.oldSlidesRef = slidesRef;
+				if (
+					(changedParams.length || breakpointChanged) &&
+					swiperRef &&
+					!swiperRef.destroyed
+				) {
+					updateSwiper({
+						swiper: swiperRef,
+						slides: slidesRef,
+						passedParams: newPassedParams,
+						changedParams,
+						nextEl: nextElRef,
+						prevEl: prevElRef,
+						scrollbarEl: scrollbarElRef,
+						paginationEl: paginationElRef,
+					});
+				}
+				breakpointChanged = false;
+			},
+			emit(event, data) {
+				this.$emit(event, ...data)
+			},
+			async getRect() {
+				let rectInfo = await getRect(this, '.swiper');
+				this.rectInfo = rectInfo;
+				return rectInfo;
+			},
+			async getRectScrollbar() {
+				let rectInfo = await getRect(this, '.swiper-scrollbar');
+				return rectInfo;
+			},
+			updateData(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this, item, value[item])
+				})
+			},
+			willChange(value) {
+				this.$set(this.wrapperStyle, 'will-change', value)
+			},
+			transform(value) {
+				// #ifndef MP-WEIXIN || MP-QQ
+				this.$set(this.wrapperStyle, 'transform', value)
+				// #endif
+				// #ifdef MP-WEIXIN || MP-QQ
+				this.wxsTransform = value;
+				// #endif
+			},
+			transition(value) {
+				// #ifdef MP-BAIDU
+				this.$set(this.wrapperStyle, 'transitionDuration', `${value}ms`)
+				// #endif
+				// #ifndef MP-BAIDU
+				this.$set(this.wrapperStyle, 'transition-duration', `${value}ms`)
+				// #endif
+			},
+			setCss(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.wrapperStyle, item, value[item])
+				})
+			},
+			scrollbarTransform(value) {
+				this.$set(this.scrollbarStyle, 'transform', value)
+			},
+			scrollbarTransition(value) {
+				this.$set(this.scrollbarStyle, 'transitionDuration', `${value}ms`)
+			},
+			scrollbarItemTransform(value) {
+				this.$set(this.scrollbarItemStyle, 'transform', value)
+			},
+			scrollbarItemTransition(value) {
+				this.$set(this.scrollbarItemStyle, 'transitionDuration', `${value}ms`)
+			},
+			addClass(value) {
+				// #ifdef MP-ALIPAY || MP-TOUTIAO
+				this.contentClass = Array.from(new Set([...this.contentClass.split(" "), ...value.split(" ")])).join(" ");
+				// #endif
+				// #ifndef MP-ALIPAY || MP-TOUTIAO
+				this.contentClass = Array.from(new Set([...this.contentClass, ...value.split(" ")]));
+				// #endif
+			},
+			removeClass(value) {
+				// #ifdef MP-ALIPAY || MP-TOUTIAO
+				this.contentClass = this.contentClass.split(" ").filter(item => !value.split(" ").includes(item)).join(
+					" ");
+				// #endif
+				// #ifndef MP-ALIPAY || MP-TOUTIAO
+				this.contentClass = this.contentClass.filter(item => !value.split(" ").includes(item));
+				// #endif
+			},
+			addPaginationClass(value) {
+				this.paginationElClass = Array.from(new Set([...this.paginationElClass, ...value.split(" ")]));
+			},
+			removePaginationClass(value) {
+				this.paginationElClass = this.paginationElClass.filter(item => !value.split(" ").includes(item));
+			},
+			addScrollbarClass(value) {
+				this.scrollbarElClass = Array.from(new Set([...this.scrollbarElClass, ...value.split(" ")]));
+			},
+			removeScrollbarClass(value) {
+				this.scrollbarElClass = this.scrollbarElClass.filter(item => !value.split(" ").includes(item));
+			},
+			setPaginationCss(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.paginationStyle, item, value[item])
+				})
+			},
+			scrollbarCss(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.scrollbarStyle, item, value[item])
+				})
+			},
+			scrollbarItemCss(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.scrollbarItemStyle, item, value[item])
+				})
+			},
+			addNextElClass(value) {
+				this.nextElClass = Array.from(new Set([...this.nextElClass, ...value.split(" ")]));
+			},
+			addPrevElClass(value) {
+				this.prevElClass = Array.from(new Set([...this.prevElClass, ...value.split(" ")]));
+			},
+			removeNextElClass(value) {
+				this.nextElClass = this.nextElClass.filter(item => !value.split(" ").includes(item));
+			},
+			removePrevElClass(value) {
+				this.prevElClass = this.prevElClass.filter(item => !value.split(" ").includes(item));
+			},
+			setSwiperOn(event, callback) {
+				if (!this.eventsListeners[event]) this.eventsListeners[event] = {};
+				this.eventsListeners[event] = callback;
+			},
+			paginationItemClick(index) {
+				this.swiper.emit("paginationItemClick", index)
+			},
+			prevClick() {
+				this.swiper.emit("prevClick");
+			},
+			nextClick() {
+				this.swiper.emit("nextClick");
+			},
+			onTouchStart(event) {
+				this.swiper.onTouchStart(event);
+			},
+			onTouchStartSwiperWxs(event) {
+				this.swiper.onTouchStart(event);
+			},
+			onTouchMove(event) {
+				this.swiper.onTouchMove(event);
+			},
+			onTouchMoveSwiperWxs(event) {
+				this.swiper.onTouchMove(event);
+			},
+			onTouchEnd(event) {
+				this.swiper.onTouchEnd(event);
+			},
+			onTouchEndSwiperWxs(event) {
+				this.swiper.onTouchEnd(event);
+			},
+			onClickWrapper(event) {
+				this.$emit("click", event);
+			},
+			onClickScrollbar(event) {
+				this.$emit("scrollbarClick", event);
+			},
+			onTouchStartScrollbar(event) {
+				this.swiper.emit('touchStartScrollbar', event);
+			},
+			onTouchMoveScrollbar(event) {
+				this.swiper.emit('touchMoveScrollbar', event);
+			},
+			onTouchEndScrollbar(event) {
+				this.swiper.emit('touchEndScrollbar', event);
+			},
+			cubeShadowCss(value) {
+				Object.keys(value).forEach((item) => {
+					this.$set(this.cubeShadowStyle, item, value[item])
+				})
+			},
+			cubeShadowTransform(value) {
+				this.$set(this.cubeShadowStyle, 'transform', value)
+			},
+			cubeShadowTransition(value) {
+				this.$set(this.cubeShadowStyle, 'transitionDuration', `${value}ms`)
+			},
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	@import '../../libs/core.scss';
+	@import "../../static/css/iconfont.css";
+
+	.swiper {
+		&__prev--button {
+			position: absolute;
+			left: 30rpx;
+			top: 50%;
+			display: flex;
+			color: #1989fa;
+			font-size: 44rpx;
+			z-index: 10;
+		}
+
+		&__prev--button--disable {
+			position: absolute;
+			left: 30rpx;
+			top: 50%;
+			display: flex;
+			color: #1989fa;
+			font-size: 44rpx;
+			opacity: .35;
+			z-index: 10;
+		}
+
+		&__next--button {
+			position: absolute;
+			right: 30rpx;
+			top: 50%;
+			display: flex;
+			color: #1989fa;
+			font-size: 44rpx;
+			z-index: 10;
+		}
+
+		&__next--button--disable {
+			position: absolute;
+			right: 30rpx;
+			top: 50%;
+			display: flex;
+			color: #1989fa;
+			font-size: 44rpx;
+			opacity: .35;
+			z-index: 10;
+		}
+	}
+</style>

+ 7 - 0
uni_modules/zebra-swiper/components/zebra-swiper/zebra-swiper.vue

@@ -0,0 +1,7 @@
+<!-- uni_modules发布插件时,components中必须有一个和父级名称一致的组件,否则提示指定目录不存在,这样做的具体原因未知。故此文件为无用文件,仅做为上传插件时消除错误使用。 -->
+<template>
+</template>
+<script>
+</script>
+<style>
+</style>

+ 26 - 0
uni_modules/zebra-swiper/index.js

@@ -0,0 +1,26 @@
+import Swiper from "./libs/core.js";
+import Autoplay from './modules/autoplay/autoplay.js';
+import FreeMode from './modules/free-mode/free-mode.js';
+import EffectFade from './modules/effect-fade/effect-fade.js';
+import EffectCube from './modules/effect-cube/effect-cube.js';
+import EffectCoverflow from './modules/effect-coverflow/effect-coverflow.js';
+import EffectFlip from './modules/effect-flip/effect-flip.js';
+import EffectCards from './modules/effect-cards/effect-cards.js';
+import EffectCreative from './modules/effect-creative/effect-creative.js';
+import EffectPanorama from './modules/effect-panorama/effect-panorama.js';
+import EffectCarousel from './modules/effect-carousel/effect-carousel.js';
+import Navigation from './modules/navigation/navigation.js';
+import Pagination from './modules/pagination/pagination.js';
+import Thumbs from './modules/thumbs/thumbs.js';
+import Scrollbar from './modules/scrollbar/scrollbar.js';
+import Virtual from './modules/virtual/virtual.js';
+import WillChange from './modules/will-change/will-change.js';
+export {
+	default as Swiper,
+	default
+}
+from './libs/core.js';
+const modules = [Autoplay, FreeMode, EffectFade, EffectCube, EffectCoverflow, EffectFlip, EffectCards, EffectCreative,
+	EffectPanorama, EffectCarousel, Navigation, Pagination, Thumbs, Scrollbar, WillChange, Virtual
+];
+Swiper.use(modules);

+ 39 - 0
uni_modules/zebra-swiper/libs/check-overflow/index.js

@@ -0,0 +1,39 @@
+function checkOverflow() {
+	const swiper = this;
+	const {
+		isLocked: wasLocked,
+		params
+	} = swiper;
+	const {
+		slidesOffsetBefore
+	} = params;
+
+	if (slidesOffsetBefore) {
+		const lastSlideIndex = swiper.slides.length - 1;
+		const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] +
+			slidesOffsetBefore * 2;
+		swiper.isLocked = swiper.size > lastSlideRightEdge;
+	} else {
+		swiper.isLocked = swiper.snapGrid.length === 1;
+	}
+
+	if (params.allowSlideNext === true) {
+		swiper.allowSlideNext = !swiper.isLocked;
+	}
+
+	if (params.allowSlidePrev === true) {
+		swiper.allowSlidePrev = !swiper.isLocked;
+	}
+
+	if (wasLocked && wasLocked !== swiper.isLocked) {
+		swiper.isEnd = false;
+	}
+
+	if (wasLocked !== swiper.isLocked) {
+		swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
+	}
+}
+
+export default {
+	checkOverflow
+};

+ 52 - 0
uni_modules/zebra-swiper/libs/classes/addClasses.js

@@ -0,0 +1,52 @@
+function prepareClasses(entries, prefix) {
+  const resultClasses = [];
+  entries.forEach(item => {
+    if (typeof item === 'object') {
+      Object.keys(item).forEach(classNames => {
+        if (item[classNames]) {
+          resultClasses.push(prefix + classNames);
+        }
+      });
+    } else if (typeof item === 'string') {
+      resultClasses.push(prefix + item);
+    }
+  });
+  return resultClasses;
+}
+
+export default function addClasses() {
+  const swiper = this;
+  const {
+    classNames,
+    params,
+    rtl,
+    $el,
+    device,
+    support
+  } = swiper; // prettier-ignore
+
+  const suffixes = prepareClasses(['initialized', params.direction, {
+    'pointer-events': !support.touch
+  }, {
+    'free-mode': swiper.params.freeMode && params.freeMode.enabled
+  }, {
+    'autoheight': params.autoHeight
+  }, {
+    'rtl': rtl
+  }, {
+    'grid': params.grid && params.grid.rows > 1
+  }, {
+    'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
+  }, {
+    'android': device.android
+  }, {
+    'ios': device.ios
+  }, {
+    'css-mode': params.cssMode
+  }, {
+    'centered': params.cssMode && params.centeredSlides
+  }], params.containerModifierClass);
+  classNames.push(...suffixes);
+  $el.addClass([...classNames].join(' '));
+  swiper.emitContainerClasses();
+}

+ 6 - 0
uni_modules/zebra-swiper/libs/classes/index.js

@@ -0,0 +1,6 @@
+import addClasses from './addClasses.js';
+import removeClasses from './removeClasses.js';
+export default {
+  addClasses,
+  removeClasses
+};

+ 9 - 0
uni_modules/zebra-swiper/libs/classes/removeClasses.js

@@ -0,0 +1,9 @@
+export default function removeClasses() {
+  const swiper = this;
+  const {
+    $el,
+    classNames
+  } = swiper;
+  $el.removeClass(classNames.join(' '));
+  swiper.emitContainerClasses();
+}

+ 565 - 0
uni_modules/zebra-swiper/libs/core.js

@@ -0,0 +1,565 @@
+import {
+	extend,
+	now,
+	deleteProps
+} from '../shared/utils.js';
+import {
+	getSupport
+} from '../shared/get-support.js';
+import {
+	getDevice
+} from '../shared/get-device.js';
+import {
+	getBrowser
+} from '../shared/get-browser.js';
+import moduleExtendParams from './moduleExtendParams.js';
+import eventsEmitter from './events-emitter.js';
+import update from './update/index.js';
+import translate from './translate/index.js';
+import transition from './transition/index.js';
+import defaults from './defaults.js';
+import classes from './classes/index.js';
+import checkOverflow from './check-overflow/index.js';
+import slide from './slide/index.js';
+import loop from './loop/index.js';
+import grabCursor from './grab-cursor/index.js';
+import events from './events/index.js';
+import {
+	getRect
+} from './utils/utils.js';
+const prototypes = {
+	eventsEmitter,
+	update,
+	checkOverflow,
+	slide,
+	loop,
+	translate,
+	transition,
+	grabCursor,
+	events,
+	classes
+};
+const extendedDefaults = {};
+class Swiper {
+	constructor(...args) {
+		const swiper = this;
+		let params;
+		let el;
+		let native;
+		if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) ===
+			'Object') {
+			params = args[0];
+		} else if (args.length === 2 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -
+				1) ===
+			'Object') {
+			params = args[0];
+			native = args[1];
+		} else {
+			[el, params, native] = args;
+		}
+		if (!params) params = {};
+		params = extend({}, params);
+		if (el && !params.el) params.el = el;
+
+		// Swiper Instance
+		swiper.__swiper__ = true;
+		swiper.support = getSupport();
+		swiper.device = getDevice({
+			userAgent: params.userAgent
+		});
+		swiper.browser = getBrowser();
+
+		swiper.eventsListeners = {};
+		swiper.eventsAnyListeners = [];
+		swiper.modules = [...swiper.__modules__];
+		swiper.native = native;
+		if (params.modules && Array.isArray(params.modules)) {
+			swiper.modules.push(...params.modules);
+		}
+		const allModulesParams = {};
+		swiper.modules.forEach(mod => {
+			mod({
+				swiper,
+				extendParams: moduleExtendParams(params, allModulesParams),
+				on: swiper.on.bind(swiper),
+				once: swiper.once.bind(swiper),
+				off: swiper.off.bind(swiper),
+				emit: swiper.emit.bind(swiper)
+			});
+		}); // Extend defaults with modules params
+		const swiperParams = extend({}, defaults, allModulesParams); // Extend defaults with passed params
+		swiper.params = extend({}, swiperParams, extendedDefaults, params);
+		swiper.originalParams = extend({}, swiper.params);
+		swiper.passedParams = extend({}, params); // add event listeners
+
+		if (swiper.params && swiper.params.on) {
+			Object.keys(swiper.params.on).forEach(eventName => {
+				swiper.on(eventName, swiper.params.on[eventName]);
+			});
+		}
+
+		if (swiper.params && swiper.params.onAny) {
+			swiper.onAny(swiper.params.onAny);
+		} // Save Dom lib
+
+		Object.assign(swiper, {
+			enabled: swiper.params.enabled,
+			el,
+			// Classes
+			classNames: [],
+			// Slides
+			slides: [],
+			slidesGrid: [],
+			snapGrid: [],
+			slidesSizesGrid: [],
+
+			// isDirection
+			isHorizontal() {
+				return swiper.params.direction === 'horizontal';
+			},
+
+			isVertical() {
+				return swiper.params.direction === 'vertical';
+			},
+
+			// Indexes
+			activeIndex: 0,
+			realIndex: 0,
+			//
+			isBeginning: true,
+			isEnd: false,
+			// Props
+			translate: 0,
+			previousTranslate: 0,
+			progress: 0,
+			velocity: 0,
+			animating: false,
+			// Locks
+			allowSlideNext: swiper.params.allowSlideNext,
+			allowSlidePrev: swiper.params.allowSlidePrev,
+			// Touch Events
+			touchEvents: function touchEvents() {
+				const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
+				const desktop = ['pointerdown', 'pointermove', 'pointerup'];
+				swiper.touchEventsTouch = {
+					start: touch[0],
+					move: touch[1],
+					end: touch[2],
+					cancel: touch[3]
+				};
+				swiper.touchEventsDesktop = {
+					start: desktop[0],
+					move: desktop[1],
+					end: desktop[2]
+				};
+				return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch :
+					swiper.touchEventsDesktop;
+			}(),
+			touchEventsData: {
+				isTouched: undefined,
+				isMoved: undefined,
+				allowTouchCallbacks: undefined,
+				touchStartTime: undefined,
+				isScrolling: undefined,
+				currentTranslate: undefined,
+				startTranslate: undefined,
+				allowThresholdMove: undefined,
+				// Form elements to match
+				focusableElements: swiper.params.focusableElements,
+				// Last click time
+				lastClickTime: now(),
+				clickTimeout: undefined,
+				// Velocities
+				velocities: [],
+				allowMomentumBounce: undefined,
+				isTouchEvent: undefined,
+				startMoving: undefined
+			},
+			// Clicks
+			allowClick: true,
+			// Touches
+			allowTouchMove: swiper.params.allowTouchMove,
+			touches: {
+				startX: 0,
+				startY: 0,
+				currentX: 0,
+				currentY: 0,
+				diff: 0
+			},
+			// Images
+			imagesToLoad: [],
+			imagesLoaded: 0,
+			virtualList: [],
+			virtualIndexList: [],
+		});
+		swiper.emit('_swiper'); // Init
+
+		if (swiper.params.init) {
+			swiper.init();
+		} // Return app instance
+		return swiper;
+
+
+	}
+
+	enable() {
+		const swiper = this;
+		if (swiper.enabled) return;
+		swiper.enabled = true;
+		if (swiper.params.grabCursor) {
+			swiper.setGrabCursor();
+		}
+		swiper.emit('enable');
+	}
+
+	disable() {
+		const swiper = this;
+		if (!swiper.enabled) return;
+		swiper.enabled = false;
+		if (swiper.params.grabCursor) {
+			swiper.unsetGrabCursor();
+		}
+		swiper.emit('disable');
+	}
+
+	setProgress(progress, speed) {
+		const swiper = this;
+		progress = Math.min(Math.max(progress, 0), 1);
+		const min = swiper.minTranslate();
+		const max = swiper.maxTranslate();
+		const current = (max - min) * progress + min;
+		swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
+		swiper.updateActiveIndex();
+		swiper.updateSlidesClasses();
+	}
+
+	emitContainerClasses() {
+		const swiper = this;
+		if (!swiper.params._emitClasses || !swiper.el) return;
+		const cls = swiper.native.contentClass.split(' ').filter(className => {
+			return className.indexOf('swiper') === 0 || className.indexOf(swiper.params
+				.containerModifierClass) === 0;
+		});
+		swiper.emit('_containerClasses', cls.join(' '));
+	}
+
+	getSlideClasses(slideEl) {
+		const swiper = this;
+		return slideEl.slideClass.split(' ').filter(className => {
+			return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params
+				.slideClass) === 0;
+		}).join(' ');
+	}
+
+	emitSlidesClasses() {
+		const swiper = this;
+		if (!swiper.params._emitClasses || !swiper.el) return;
+		const updates = [];
+		swiper.slides.forEach(slideEl => {
+			const classNames = swiper.getSlideClasses(slideEl);
+			updates.push({
+				slideEl,
+				classNames
+			});
+			swiper.emit('_slideClass', slideEl, classNames);
+		});
+		swiper.emit('_slideClasses', updates);
+	}
+
+	slidesPerViewDynamic(view = 'current', exact = false) {
+		const swiper = this;
+		const {
+			params,
+			slides,
+			slidesGrid,
+			slidesSizesGrid,
+			size: swiperSize,
+			activeIndex
+		} = swiper;
+		let spv = 1;
+		if (params.centeredSlides) {
+			let slideSize = slides[activeIndex].swiperSlideSize;
+			let breakLoop;
+			for (let i = activeIndex + 1; i < slides.length; i += 1) {
+				if (slides[i] && !breakLoop) {
+					slideSize += slides[i].swiperSlideSize;
+					spv += 1;
+					if (slideSize > swiperSize) breakLoop = true;
+				}
+			}
+			for (let i = activeIndex - 1; i >= 0; i -= 1) {
+				if (slides[i] && !breakLoop) {
+					slideSize += slides[i].swiperSlideSize;
+					spv += 1;
+					if (slideSize > swiperSize) breakLoop = true;
+				}
+			}
+		} else {
+			// eslint-disable-next-line
+			if (view === 'current') {
+				for (let i = activeIndex + 1; i < slides.length; i += 1) {
+					const slideInView = exact ?
+						slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize :
+						slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
+					if (slideInView) {
+						spv += 1;
+					}
+				}
+			} else {
+				// previous
+				for (let i = activeIndex - 1; i >= 0; i -= 1) {
+					const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
+					if (slideInView) {
+						spv += 1;
+					}
+				}
+			}
+		}
+		return spv;
+	}
+
+	changeDirection(newDirection, needUpdate) {
+		if (needUpdate === void 0) {
+			needUpdate = true;
+		}
+
+		const swiper = this;
+		const currentDirection = swiper.params.direction;
+
+		if (!newDirection) {
+			// eslint-disable-next-line
+			newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
+		}
+
+		if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
+			return swiper;
+		}
+
+		swiper.$wrapperEl.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`)
+		swiper.$wrapperEl.addClass(
+			`${swiper.params.containerModifierClass}${newDirection}`);
+		swiper.emitContainerClasses();
+		swiper.params.direction = newDirection;
+		swiper.slides.forEach(slideEl => {
+			if (newDirection === 'vertical') {
+				slideEl.css({
+					width: ''
+				})
+			} else {
+				slideEl.css({
+					height: ''
+				})
+			}
+		});
+		swiper.emit('changeDirection');
+		if (needUpdate) swiper.update();
+		return swiper;
+	}
+
+	async update(el) {
+		const swiper = this;
+		if (!swiper || swiper.destroyed) return;
+		const {
+			snapGrid,
+			params
+		} = swiper; // Breakpoints
+
+
+		el = await swiper.native.getRect();
+		if (!el) {
+			return false;
+		}
+		Object.assign(swiper, {
+			el,
+			$el: swiper.native,
+		});
+		swiper.emit('beforeUpdate');
+		if (params.breakpoints) {
+			swiper.setBreakpoint();
+		}
+		swiper.updateSize();
+		swiper.updateSlides();
+		swiper.updateProgress();
+		swiper.updateSlidesClasses();
+
+		function setTranslate() {
+			const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
+			const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
+			swiper.setTranslate(newTranslate);
+			swiper.updateActiveIndex();
+			swiper.updateSlidesClasses();
+		}
+
+		let translated;
+
+		if (swiper.params.freeMode && swiper.params.freeMode.enabled) {
+			setTranslate();
+
+			if (swiper.params.autoHeight) {
+				swiper.updateAutoHeight();
+			}
+		} else {
+			if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !
+				swiper.params.centeredSlides) {
+				translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
+			} else {
+				translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
+			}
+
+			if (!translated) {
+				setTranslate();
+			}
+		}
+
+		if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
+			swiper.checkOverflow();
+		}
+		swiper.emit('update');
+	}
+	async mount(el) {
+		const swiper = this;
+		if (swiper.mounted) return true; // Find el
+		el = await swiper.native.getRect();
+		if (!el) {
+			return false;
+		}
+		swiper.emit('beforeMount'); // Set breakpoint
+		// let $wrapperEl = new DomSimulation(swiper.native);
+		// let $el = new DomSimulation(swiper.native);
+		// if (swiper.native && swiper.native.children && swiper.native.children.length) {
+		// 	swiper.native.children.forEach((item) => {
+		// 		item.$itemEl = new ChildDomSimulation(item);
+		// 	})
+		// }
+		Object.assign(swiper, {
+			$el: swiper.native,
+			el,
+			$wrapperEl: swiper.native,
+			wrapperEl: swiper.native,
+			mounted: true,
+		});
+
+		return true;
+	}
+	async init(el) {
+		const swiper = this;
+		if (swiper.initialized) return swiper;
+		const mounted = await swiper.mount(el);
+		if (mounted === false) return swiper;
+		swiper.emit('beforeInit'); // Set breakpoint
+
+		swiper.addClasses(); // Create loop
+
+		if (swiper.params.loop) {
+			swiper.loopCreate();
+		} // Update size
+
+		swiper.updateSize(); // Update slides
+
+		swiper.updateSlides();
+
+		if (swiper.params.watchOverflow) {
+			swiper.checkOverflow();
+		} // Set Grab Cursor
+
+
+		if (swiper.params.grabCursor && swiper.enabled) {
+			swiper.setGrabCursor();
+		}
+
+		// if (swiper.params.loop) {
+		// 	swiper.on("update", () => {
+		// 		swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params
+		// 			.runCallbacksOnInit,
+		// 			false, true);
+		// 	})
+		// } else {
+		// 	swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
+		// } // Attach events
+		// Slide To Initial Slide
+		if (swiper.params.loop) {
+			swiper.slideTo(
+				swiper.params.initialSlide + swiper.loopedSlides,
+				0,
+				swiper.params.runCallbacksOnInit,
+				false,
+				true,
+			);
+		} else {
+			swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
+		}
+		swiper.attachEvents(); // Init Flag
+		swiper.initialized = true; // Emit
+		swiper.emit('init');
+		swiper.emit('afterInit');
+		return swiper;
+	}
+	destroy(deleteInstance = true, cleanStyles = true) {
+		const swiper = this;
+		const {
+			params,
+			$el,
+			$wrapperEl,
+			slides
+		} = swiper;
+
+		if (typeof swiper.params === 'undefined' || swiper.destroyed) {
+			return null;
+		}
+
+		swiper.emit('beforeDestroy'); // Init Flag
+
+		swiper.initialized = false; // Detach events
+
+		swiper.detachEvents(); // Destroy loop
+
+		if (params.loop) {
+			swiper.loopDestroy();
+		} // Cleanup styles
+
+		swiper.emit('destroy'); // Detach emitter events
+
+		Object.keys(swiper.eventsListeners).forEach(eventName => {
+			swiper.off(eventName);
+		});
+
+		if (deleteInstance !== false) {
+			deleteProps(swiper);
+		}
+
+		swiper.destroyed = true;
+		return null;
+	}
+	static extendDefaults(newDefaults) {
+		extend(extendedDefaults, newDefaults);
+	}
+	static get extendedDefaults() {
+		return extendedDefaults;
+	}
+	static get defaults() {
+		return defaults;
+	}
+	static installModule(mod) {
+		if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
+		const modules = Swiper.prototype.__modules__;
+
+		if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
+			modules.push(mod);
+		}
+	}
+	static use(module) {
+		if (Array.isArray(module)) {
+			module.forEach(m => Swiper.installModule(m));
+			return Swiper;
+		}
+
+		Swiper.installModule(module);
+		return Swiper;
+	}
+}
+Object.keys(prototypes).forEach(prototypeGroup => {
+	Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
+		Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
+	});
+});
+export default Swiper;

+ 174 - 0
uni_modules/zebra-swiper/libs/core.scss

@@ -0,0 +1,174 @@
+$themeColor: #007aff !default;
+
+:root {
+  --swiper-theme-color: #{$themeColor};
+}
+.swiper {
+  margin-left: auto;
+  margin-right: auto;
+  position: relative;
+  overflow: hidden;
+  list-style: none;
+  padding: 0;
+  /* Fix of Webkit flickering */
+  z-index: 1;
+}
+.swiper-vertical > .swiper-wrapper {
+  flex-direction: column;
+}
+.swiper-wrapper {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+  display: flex;
+  transition-property: transform;
+  box-sizing: content-box;
+}
+.swiper-android .swiper-slide,
+.swiper-wrapper {
+  transform: translate3d(0px, 0, 0);
+}
+.swiper-pointer-events {
+  touch-action: pan-y;
+  &.swiper-vertical {
+    touch-action: pan-x;
+  }
+}
+.swiper-slide {
+  flex-shrink: 0;
+  width: 100%;
+  height: 100%;
+  position: relative;
+  transition-property: transform;
+}
+.swiper-slide-invisible-blank {
+  visibility: hidden;
+}
+/* Auto Height */
+.swiper-autoheight {
+  &,
+  .swiper-slide {
+    height: auto;
+  }
+
+  .swiper-wrapper {
+    align-items: flex-start;
+    transition-property: transform, height;
+  }
+}
+  .swiper-slide-3d{
+	   transform-style: preserve-3d;
+  }
+/* 3D Effects */
+.swiper-3d {
+  &,
+  &.swiper-css-mode .swiper-wrapper {
+    perspective: 1200px;
+  }
+  .swiper-wrapper,
+  .swiper-slide,
+  .swiper-slide-shadow,
+  .swiper-slide-shadow-left,
+  .swiper-slide-shadow-right,
+  .swiper-slide-shadow-top,
+  .swiper-slide-shadow-bottom,
+  .swiper-cube-shadow {
+    transform-style: preserve-3d;
+  }
+  .swiper-slide-shadow,
+  .swiper-slide-shadow-left,
+  .swiper-slide-shadow-right,
+  .swiper-slide-shadow-top,
+  .swiper-slide-shadow-bottom {
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    pointer-events: none;
+    z-index: 10;
+  }
+  .swiper-slide-shadow {
+    background: rgba(0, 0, 0, 0.15);
+  }
+  .swiper-slide-shadow-left {
+    background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+  }
+  .swiper-slide-shadow-right {
+    background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+  }
+  .swiper-slide-shadow-top {
+    background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+  }
+  .swiper-slide-shadow-bottom {
+    background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+  }
+}
+
+/* CSS Mode */
+.swiper-css-mode {
+  > .swiper-wrapper {
+    overflow: auto;
+    scrollbar-width: none; /* For Firefox */
+    -ms-overflow-style: none; /* For Internet Explorer and Edge */
+    &::-webkit-scrollbar {
+      display: none;
+    }
+  }
+  > .swiper-wrapper > .swiper-slide {
+    scroll-snap-align: start start;
+  }
+}
+.swiper-horizontal.swiper-css-mode {
+  > .swiper-wrapper {
+    scroll-snap-type: x mandatory;
+  }
+}
+.swiper-vertical.swiper-css-mode {
+  > .swiper-wrapper {
+    scroll-snap-type: y mandatory;
+  }
+}
+.swiper-centered {
+  > .swiper-wrapper::before {
+    content: '';
+    flex-shrink: 0;
+    order: 9999;
+  }
+  &.swiper-horizontal {
+    > .swiper-wrapper > .swiper-slide:first-child {
+      margin-inline-start: var(--swiper-centered-offset-before);
+    }
+    > .swiper-wrapper::before {
+      height: 100%;
+      width: var(--swiper-centered-offset-after);
+    }
+  }
+  &.swiper-vertical {
+    > .swiper-wrapper > .swiper-slide:first-child {
+      margin-block-start: var(--swiper-centered-offset-before);
+    }
+    > .swiper-wrapper::before {
+      width: 100%;
+      height: var(--swiper-centered-offset-after);
+    }
+  }
+
+  > .swiper-wrapper > .swiper-slide {
+    scroll-snap-align: center center;
+  }
+}
+
+@import "../modules/effect-fade/effect-fade.scss";
+@import "../modules/effect-cube/effect-cube.scss";
+@import "../modules/effect-coverflow/effect-coverflow.scss";
+@import "../modules/effect-flip/effect-flip.scss";
+@import "../modules/effect-cards/effect-cards.scss";
+@import "../modules/effect-creative/effect-creative.scss";
+@import "../modules/effect-panorama/effect-panorama.scss";
+@import "../modules/effect-carousel/effect-carousel.scss";
+@import "../modules/navigation/navigation.scss";
+@import "../modules/pagination/pagination.scss";
+@import "../modules/thumbs/thumbs.scss";
+@import "../modules/scrollbar/scrollbar.scss";

+ 126 - 0
uni_modules/zebra-swiper/libs/defaults.js

@@ -0,0 +1,126 @@
+export default {
+	init: true,
+	direction: 'horizontal',
+	touchEventsTarget: 'wrapper',
+	initialSlide: 0,
+	speed: 300,
+	cssMode: false,
+	updateOnWindowResize: true,
+	resizeObserver: true,
+	nested: false,
+	createElements: false,
+	enabled: true,
+	focusableElements: 'input, select, option, textarea, button, video, label',
+	// Overrides
+	width: null,
+	height: null,
+	//
+	preventInteractionOnTransition: false,
+	// ssr
+	userAgent: null,
+	url: null,
+	// To support iOS's swipe-to-go-back gesture (when being used in-app).
+	edgeSwipeDetection: false,
+	edgeSwipeThreshold: 20,
+	// Autoheight
+	autoHeight: false,
+	// Set wrapper width
+	setWrapperSize: false,
+	// Virtual Translate
+	virtualTranslate: false,
+	virtualList: [],
+	virtualIndexList: [],
+	// Effects
+	effect: 'slide',
+	// 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
+	// Breakpoints
+	breakpoints: undefined,
+	breakpointsBase: 'window',
+	// Slides grid
+	spaceBetween: 0,
+	slidesPerView: 1,
+	slidesPerGroup: 1,
+	slidesPerGroupSkip: 0,
+	slidesPerGroupAuto: false,
+	centeredSlides: false,
+	centeredSlidesBounds: false,
+	slidesOffsetBefore: 0,
+	// in px
+	slidesOffsetAfter: 0,
+	// in px
+	normalizeSlideIndex: true,
+	centerInsufficientSlides: false,
+	// Disable swiper and hide navigation when container not overflow
+	watchOverflow: true,
+	// Round length
+	roundLengths: false,
+	// Touches
+	touchRatio: 1,
+	touchAngle: 45,
+	simulateTouch: true,
+	shortSwipes: true,
+	longSwipes: true,
+	longSwipesRatio: 0.5,
+	longSwipesMs: 300,
+	followFinger: true,
+	allowTouchMove: true,
+	threshold: 0,
+	touchMoveStopPropagation: false,
+	touchStartPreventDefault: true,
+	touchStartForcePreventDefault: false,
+	touchReleaseOnEdges: false,
+	// Unique Navigation Elements
+	uniqueNavElements: true,
+	// Resistance
+	resistance: true,
+	resistanceRatio: 0.85,
+	// Progress
+	watchSlidesProgress: false,
+	// Cursor
+	grabCursor: false,
+	// Clicks
+	preventClicks: true,
+	preventClicksPropagation: true,
+	slideToClickedSlide: false,
+	// Images
+	preloadImages: true,
+	updateOnImagesReady: true,
+	// loop
+	loop: false,
+	loopAdditionalSlides: 0,
+	loopedSlides: null,
+	loopFillGroupWithBlank: false,
+	loopPreventsSlide: true,
+	// rewind
+	rewind: false,
+	// Swiping/no swiping
+	allowSlidePrev: true,
+	allowSlideNext: true,
+	swipeHandler: null,
+	// '.swipe-handler',
+	noSwiping: false,
+	noSwipingClass: 'swiper-no-swiping',
+	noSwipingSelector: null,
+	// Passive Listeners
+	passiveListeners: true,
+	// NS
+	containerModifierClass: 'swiper-',
+	// NEW
+	slideClass: 'swiper-slide',
+	slideBlankClass: 'swiper-slide-invisible-blank',
+	slideActiveClass: 'swiper-slide-active',
+	slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
+	slideVisibleClass: 'swiper-slide-visible',
+	slideDuplicateClass: 'swiper-slide-duplicate',
+	slideNextClass: 'swiper-slide-next',
+	slideDuplicateNextClass: 'swiper-slide-duplicate-next',
+	slidePrevClass: 'swiper-slide-prev',
+	slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
+	wrapperClass: 'swiper-wrapper',
+	slideThumbsClass: 'swiper-slide-thumb',
+	// Callbacks
+	runCallbacksOnInit: true,
+	// Internals
+	_emitClasses: false,
+	willChange: false
+};

+ 115 - 0
uni_modules/zebra-swiper/libs/events-emitter.js

@@ -0,0 +1,115 @@
+/* eslint-disable no-underscore-dangle */
+export default {
+	on(events, handler, priority) {
+		const self = this;
+
+		if (typeof handler !== 'function') return self;
+		const method = priority ? 'unshift' : 'push';
+		events.split(' ').forEach(event => {
+			if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
+			self.eventsListeners[event][method](handler);
+		});
+
+		return self;
+	},
+
+	once(events, handler, priority) {
+		const self = this;
+		if (typeof handler !== 'function') return self;
+
+		function onceHandler(...args) {
+			self.off(events, onceHandler);
+
+			if (onceHandler.__emitterProxy) {
+				delete onceHandler.__emitterProxy;
+			}
+
+			handler.apply(self, args);
+		}
+
+		onceHandler.__emitterProxy = handler;
+		return self.on(events, onceHandler, priority);
+	},
+
+	onAny(handler, priority) {
+		const self = this;
+		if (typeof handler !== 'function') return self;
+		const method = priority ? 'unshift' : 'push';
+
+		if (self.eventsAnyListeners.indexOf(handler) < 0) {
+			self.eventsAnyListeners[method](handler);
+		}
+
+		return self;
+	},
+
+	offAny(handler) {
+		const self = this;
+		if (!self.eventsAnyListeners) return self;
+		const index = self.eventsAnyListeners.indexOf(handler);
+
+		if (index >= 0) {
+			self.eventsAnyListeners.splice(index, 1);
+		}
+
+		return self;
+	},
+
+	off(events, handler) {
+		const self = this;
+		if (!self.eventsListeners) return self;
+		events.split(' ').forEach(event => {
+			// self.native.off(event, handler);
+			if (typeof handler === 'undefined') {
+				self.eventsListeners[event] = [];
+			} else if (self.eventsListeners[event]) {
+				self.eventsListeners[event].forEach((eventHandler, index) => {
+					if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler
+						.__emitterProxy === handler) {
+						self.eventsListeners[event].splice(index, 1);
+					}
+				});
+			}
+		});
+		return self;
+	},
+
+	emit(...args) {
+		const self = this;
+		if (!self.eventsListeners) return self;
+		let events;
+		let data;
+		let context;
+
+		if (typeof args[0] === 'string' || Array.isArray(args[0])) {
+			events = args[0];
+			data = args.slice(1, args.length);
+			context = self;
+		} else {
+			events = args[0].events;
+			data = args[0].data;
+			context = args[0].context || self;
+		}
+
+		data.unshift(context);
+
+		const eventsArray = Array.isArray(events) ? events : events.split(' ');
+
+		eventsArray.forEach(event => {
+			// console.log(event)
+			if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
+				self.eventsAnyListeners.forEach(eventHandler => {
+					eventHandler.apply(context, [event, ...data]);
+				});
+			}
+			if (self.eventsListeners && self.eventsListeners[event]) {
+				self.eventsListeners[event].forEach(eventHandler => {
+					eventHandler.apply(context, data);
+				});
+			}
+		});
+
+		return self;
+	}
+
+};

+ 67 - 0
uni_modules/zebra-swiper/libs/events/index.js

@@ -0,0 +1,67 @@
+import onTouchStart from './onTouchStart.js';
+import onTouchMove from './onTouchMove.js';
+import onTouchEnd from './onTouchEnd.js';
+import onResize from './onResize.js';
+import onClick from './onClick.js';
+import onScroll from './onScroll.js';
+let dummyEventAttached = false;
+
+function dummyEventListener() {}
+
+const events = (swiper, method) => {
+	const {
+		params,
+		touchEvents,
+		wrapperEl,
+		device,
+		support
+	} = swiper;
+	let el = swiper.native;
+	const capture = !!params.nested;
+	const domMethod = method === 'on' ? 'on' : 'off';
+	const swiperMethod = method;
+	if (!support.touch) {
+		let desktopMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
+		if (document.querySelector(`#${swiper.$el.swiperElId}`)) {
+			document.querySelector(`#${swiper.$el.swiperElId}`)[desktopMethod](touchEvents.start, swiper
+				.onTouchStart,
+				false);
+		}
+		document[desktopMethod](touchEvents.move, swiper.onTouchMove, capture);
+		document[desktopMethod](touchEvents.end, swiper.onTouchEnd, false);
+	} else {
+		const passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params
+			.passiveListeners ? {
+				passive: true,
+				capture: false
+			} : false;
+	}
+};
+
+function attachEvents() {
+	const swiper = this;
+	const {
+		params,
+		support
+	} = swiper;
+	swiper.onTouchStart = onTouchStart.bind(swiper);
+	swiper.onTouchMove = onTouchMove.bind(swiper);
+	swiper.onTouchEnd = onTouchEnd.bind(swiper);
+	if (params.cssMode) {
+		swiper.onScroll = onScroll.bind(swiper);
+	}
+
+	swiper.onClick = onClick.bind(swiper);
+
+	events(swiper, 'on');
+}
+
+function detachEvents() {
+	const swiper = this;
+	events(swiper, 'off');
+}
+
+export default {
+	attachEvents,
+	detachEvents
+};

+ 13 - 0
uni_modules/zebra-swiper/libs/events/onClick.js

@@ -0,0 +1,13 @@
+export default function onClick(e) {
+  const swiper = this;
+  if (!swiper.enabled) return;
+
+  if (!swiper.allowClick) {
+    if (swiper.params.preventClicks) e.preventDefault();
+
+    if (swiper.params.preventClicksPropagation && swiper.animating) {
+      e.stopPropagation();
+      e.stopImmediatePropagation();
+    }
+  }
+}

+ 43 - 0
uni_modules/zebra-swiper/libs/events/onResize.js

@@ -0,0 +1,43 @@
+export default function onResize() {
+  const swiper = this;
+  const {
+    params,
+    el
+  } = swiper;
+  if (el && el.offsetWidth === 0) return;
+
+  if (params.breakpoints) {
+    swiper.setBreakpoint();
+  }
+
+
+  const {
+    allowSlideNext,
+    allowSlidePrev,
+    snapGrid
+  } = swiper;
+
+  swiper.allowSlideNext = true;
+  swiper.allowSlidePrev = true;
+  swiper.updateSize();
+  swiper.updateSlides();
+  swiper.updateSlidesClasses();
+
+  if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {
+    swiper.slideTo(swiper.slides.length - 1, 0, false, true);
+  } else {
+    swiper.slideTo(swiper.activeIndex, 0, false, true);
+  }
+
+  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
+    swiper.autoplay.run();
+  }
+
+
+  swiper.allowSlidePrev = allowSlidePrev;
+  swiper.allowSlideNext = allowSlideNext;
+
+  if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
+    swiper.checkOverflow();
+  }
+}

+ 35 - 0
uni_modules/zebra-swiper/libs/events/onScroll.js

@@ -0,0 +1,35 @@
+export default function onScroll() {
+  const swiper = this;
+  const {
+    wrapperEl,
+    rtlTranslate,
+    enabled
+  } = swiper;
+  if (!enabled) return;
+  swiper.previousTranslate = swiper.translate;
+
+  if (swiper.isHorizontal()) {
+    swiper.translate = -wrapperEl.scrollLeft;
+  } else {
+    swiper.translate = -wrapperEl.scrollTop;
+  } // eslint-disable-next-line
+
+
+  if (swiper.translate === -0) swiper.translate = 0;
+  swiper.updateActiveIndex();
+  swiper.updateSlidesClasses();
+  let newProgress;
+  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
+
+  if (translatesDiff === 0) {
+    newProgress = 0;
+  } else {
+    newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
+  }
+
+  if (newProgress !== swiper.progress) {
+    swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
+  }
+
+  swiper.emit('setTranslate', swiper.translate, false);
+}

+ 147 - 0
uni_modules/zebra-swiper/libs/events/onTouchEnd.js

@@ -0,0 +1,147 @@
+import {
+	now,
+	nextTick
+} from '../../shared/utils.js';
+export default function onTouchEnd(event) {
+	const swiper = this;
+	const data = swiper.touchEventsData;
+	const {
+		params,
+		touches,
+		rtlTranslate: rtl,
+		slidesGrid,
+		enabled
+	} = swiper;
+	if (!enabled) return;
+	let e = event;
+	if (e.originalEvent) e = e.originalEvent;
+
+	if (data.allowTouchCallbacks) {
+		swiper.emit('touch-end', e);
+	}
+
+	data.allowTouchCallbacks = false;
+
+	if (!data.isTouched) {
+		if (data.isMoved && params.grabCursor) {
+			swiper.setGrabCursor(false);
+		}
+
+		data.isMoved = false;
+		data.startMoving = false;
+		return;
+	}
+
+
+	if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper
+			.allowSlidePrev === true)) {
+		swiper.setGrabCursor(false);
+	}
+
+
+	const touchEndTime = now();
+	const timeDiff = touchEndTime - data.touchStartTime; // Tap, doubleTap, Click
+
+	if (swiper.allowClick) {
+		const pathTree = e.path || e.composedPath && e.composedPath();
+		// swiper.updateClickedSlide(pathTree && pathTree[0] || e.target);
+		swiper.emit('tap click', e);
+
+		if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
+			swiper.emit('doubleTap doubleClick', e);
+		}
+	}
+
+	data.lastClickTime = now();
+	nextTick(() => {
+		if (!swiper.destroyed) swiper.allowClick = true;
+	});
+
+	if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate ===
+		data.startTranslate) {
+		data.isTouched = false;
+		data.isMoved = false;
+		data.startMoving = false;
+		return;
+	}
+
+	data.isTouched = false;
+	data.isMoved = false;
+	data.startMoving = false;
+	let currentPos;
+
+	if (params.followFinger) {
+		currentPos = rtl ? swiper.translate : -swiper.translate;
+	} else {
+		currentPos = -data.currentTranslate;
+	}
+
+	if (params.cssMode) {
+		return;
+	}
+
+	if (swiper.params.freeMode && params.freeMode.enabled) {
+		swiper.freeMode.onTouchEnd({
+			currentPos
+		});
+		return;
+	}
+
+	let stopIndex = 0;
+	let groupSize = swiper.slidesSizesGrid[0];
+
+	for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
+		const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
+		if (typeof slidesGrid[i + increment] !== 'undefined') {
+			if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
+				stopIndex = i;
+				groupSize = slidesGrid[i + increment] - slidesGrid[i];
+			}
+		} else if (currentPos >= slidesGrid[i]) {
+			stopIndex = i;
+			groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
+		}
+	}
+
+
+	const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
+	const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
+	if (timeDiff > params.longSwipesMs) {
+		if (!params.longSwipes) {
+			swiper.slideTo(swiper.activeIndex);
+			return;
+		}
+
+		if (swiper.swipeDirection === 'next') {
+			if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + increment);
+			else swiper.slideTo(stopIndex);
+		}
+
+		if (swiper.swipeDirection === 'prev') {
+			if (ratio > 1 - params.longSwipesRatio) swiper.slideTo(stopIndex + increment);
+			else swiper.slideTo(stopIndex);
+		}
+	} else {
+		if (!params.shortSwipes) {
+			swiper.slideTo(swiper.activeIndex);
+			return;
+		}
+
+		const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper
+			.navigation.prevEl);
+
+		if (!isNavButtonTarget) {
+			if (swiper.swipeDirection === 'next') {
+				swiper.slideTo(stopIndex + increment);
+			}
+
+			if (swiper.swipeDirection === 'prev') {
+				swiper.slideTo(stopIndex);
+			}
+		} else if (e.target === swiper.navigation.nextEl) {
+			swiper.slideTo(stopIndex + increment);
+		} else {
+			swiper.slideTo(stopIndex);
+		}
+	}
+}

+ 228 - 0
uni_modules/zebra-swiper/libs/events/onTouchMove.js

@@ -0,0 +1,228 @@
+import {
+	now
+} from '../../shared/utils.js';
+export default function onTouchMove(event) {
+	const swiper = this;
+	const data = swiper.touchEventsData;
+	const {
+		params,
+		touches,
+		rtlTranslate: rtl,
+		enabled
+	} = swiper;
+	if (!enabled) return;
+	let e = event;
+	if (e.originalEvent) e = e.originalEvent;
+
+	if (!data.isTouched) {
+		if (data.startMoving && data.isScrolling) {
+			swiper.emit('touchMoveOpposite', e);
+		}
+
+		return;
+	}
+
+	if (data.isTouchEvent && e.type !== 'touchmove' && e.type !== 'touchMove' && e.type !== 'onTouchmove') return;
+	const targetTouch = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') && e.touches && (
+		e.touches[0] || e
+		.changedTouches[0]);
+	const pageX = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') ? targetTouch.pageX : e
+		.pageX;
+	const pageY = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') ? targetTouch.pageY : e
+		.pageY;
+
+	if (e.preventedByNestedSwiper) {
+		touches.startX = pageX;
+		touches.startY = pageY;
+		return;
+	}
+
+	if (!swiper.allowTouchMove) {
+		swiper.allowClick = false;
+
+		if (data.isTouched) {
+			Object.assign(touches, {
+				startX: pageX,
+				startY: pageY,
+				currentX: pageX,
+				currentY: pageY
+			});
+			data.touchStartTime = now();
+		}
+
+		return;
+	}
+
+	if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {
+		if (swiper.isVertical()) {
+			if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper
+				.translate >= swiper.minTranslate()) {
+				data.isTouched = false;
+				data.isMoved = false;
+				return;
+			}
+		} else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX &&
+			swiper.translate >= swiper.minTranslate()) {
+			return;
+		}
+	}
+
+	// if (data.isTouchEvent && document.activeElement) {
+	//   if (e.target === document.activeElement && $(e.target).is(data.focusableElements)) {
+	//     data.isMoved = true;
+	//     swiper.allowClick = false;
+	//     return;
+	//   }
+	// }
+
+	if (data.allowTouchCallbacks) {
+		swiper.emit('touch-move', e);
+	}
+
+	if (e.touches && e.touches.length > 1) return;
+	touches.currentX = pageX;
+	touches.currentY = pageY;
+	const diffX = touches.currentX - touches.startX;
+	const diffY = touches.currentY - touches.startY;
+	if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
+
+	if (typeof data.isScrolling === 'undefined') {
+		let touchAngle;
+
+		if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX ===
+			touches.startX) {
+			data.isScrolling = false;
+		} else {
+			if (diffX * diffX + diffY * diffY >= 25) {
+				touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
+				data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params
+					.touchAngle;
+			}
+		}
+	}
+
+	if (data.isScrolling) {
+		swiper.emit('touchMoveOpposite', e);
+	}
+
+	if (typeof data.startMoving === 'undefined') {
+		if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
+			data.startMoving = true;
+		}
+	}
+
+	if (data.isScrolling) {
+		data.isTouched = false;
+		return;
+	}
+
+	if (!data.startMoving) {
+		return;
+	}
+
+	swiper.allowClick = false;
+
+	if (!params.cssMode && e.cancelable) {
+		e.preventDefault();
+	}
+
+	if (params.touchMoveStopPropagation && !params.nested) {
+		e.stopPropagation();
+	}
+
+	if (!data.isMoved) {
+		if (params.loop && !params.cssMode) {
+			swiper.loopFix();
+		}
+
+		data.startTranslate = swiper.getTranslate();
+		swiper.setTransition(0);
+
+		if (swiper.animating) {
+			swiper.$wrapperEl.emit('transitionend', [swiper]);
+		}
+
+		data.allowMomentumBounce = false;
+
+		if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
+			swiper.setGrabCursor(true);
+		}
+
+		swiper.emit('sliderFirstMove', e);
+	}
+
+	swiper.emit('sliderMove', e);
+	data.isMoved = true;
+	let diff = swiper.isHorizontal() ? diffX : diffY;
+	touches.diff = diff;
+	diff *= params.touchRatio;
+	if (rtl) diff = -diff;
+	swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
+	data.currentTranslate = diff + data.startTranslate;
+	let disableParentSwiper = true;
+	let resistanceRatio = params.resistanceRatio;
+
+	if (params.touchReleaseOnEdges) {
+		resistanceRatio = 0;
+	}
+
+	if (diff > 0 && data.currentTranslate > swiper.minTranslate()) {
+		disableParentSwiper = false;
+		if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data
+			.startTranslate + diff) ** resistanceRatio;
+	} else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {
+		disableParentSwiper = false;
+		if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data
+			.startTranslate - diff) ** resistanceRatio;
+	}
+
+	if (disableParentSwiper) {
+		e.preventedByNestedSwiper = true;
+	}
+
+
+	if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
+		data.currentTranslate = data.startTranslate;
+	}
+
+	if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
+		data.currentTranslate = data.startTranslate;
+	}
+
+	if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
+		data.currentTranslate = data.startTranslate;
+	}
+
+
+	if (params.threshold > 0) {
+		if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
+			if (!data.allowThresholdMove) {
+				data.allowThresholdMove = true;
+				touches.startX = touches.currentX;
+				touches.startY = touches.currentY;
+				data.currentTranslate = data.startTranslate;
+				touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches
+					.startY;
+				return;
+			}
+		} else {
+			data.currentTranslate = data.startTranslate;
+			return;
+		}
+	}
+
+	if (!params.followFinger || params.cssMode) return;
+
+	if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
+		swiper.updateActiveIndex();
+		swiper.updateSlidesClasses();
+	}
+
+	if (swiper.params.freeMode && params.freeMode.enabled && swiper.freeMode) {
+		swiper.freeMode.onTouchMove();
+	}
+
+	swiper.updateProgress(data.currentTranslate);
+
+	swiper.setTranslate(data.currentTranslate);
+}

+ 85 - 0
uni_modules/zebra-swiper/libs/events/onTouchStart.js

@@ -0,0 +1,85 @@
+import {
+	now
+} from '../../shared/utils.js';
+
+export default function onTouchStart(event) {
+	const swiper = this;
+	const data = swiper.touchEventsData;
+	const {
+		params,
+		touches,
+		enabled
+	} = swiper;
+	if (!enabled) return;
+
+	if (swiper.animating && params.preventInteractionOnTransition) {
+		return;
+	}
+
+	if (!swiper.animating && params.cssMode && params.loop) {
+		swiper.loopFix();
+	}
+
+	let e = event;
+	if (e.originalEvent) e = e.originalEvent;
+
+	data.isTouchEvent = e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart';
+	if (!data.isTouchEvent && 'which' in e && e.which === 3) return;
+	if (!data.isTouchEvent && 'button' in e && e.button > 0) return;
+	if (data.isTouched && data.isMoved) return; // change target el for shadow root component
+
+	const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
+
+
+	const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
+	const isTargetShadow = !!(e.target && e.target
+		.shadowRoot
+	);
+
+	if (params.noSwiping) {
+		swiper.allowClick = true;
+		return;
+	}
+
+	if (params.swipeHandler) {
+		if (!$targetEl.closest(params.swipeHandler)[0]) return;
+	}
+
+	touches.currentX = (e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart') ? e.touches[0]
+		.pageX : e.pageX;
+	touches.currentY = (e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart') ? e.touches[0]
+		.pageY : e.pageY;
+	const startX = touches.currentX;
+	const startY = touches
+		.currentY;
+
+	const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
+	const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
+
+	Object.assign(data, {
+		isTouched: true,
+		isMoved: false,
+		allowTouchCallbacks: true,
+		isScrolling: undefined,
+		startMoving: undefined
+	});
+	touches.startX = startX;
+	touches.startY = startY;
+	data.touchStartTime = now();
+	swiper.allowClick = true;
+	swiper.updateSize();
+	swiper.swipeDirection = undefined;
+	if (params.threshold > 0) data.allowThresholdMove = false;
+	// if (e.type !== 'touchstart' && e.type !== 'touchStart') {
+	// let preventDefault = true;
+	// if ($targetEl.is(data.focusableElements)) preventDefault = false;
+
+	// const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
+
+	// if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) {
+	// e.preventDefault();
+	// }
+	// }
+
+	swiper.emit('touch-start', e);
+}

+ 6 - 0
uni_modules/zebra-swiper/libs/grab-cursor/index.js

@@ -0,0 +1,6 @@
+import setGrabCursor from './setGrabCursor.js';
+import unsetGrabCursor from './unsetGrabCursor.js';
+export default {
+  setGrabCursor,
+  unsetGrabCursor
+};

+ 12 - 0
uni_modules/zebra-swiper/libs/grab-cursor/setGrabCursor.js

@@ -0,0 +1,12 @@
+export default function setGrabCursor(moving) {
+	const swiper = this;
+	if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper
+		.params.cssMode) return;
+	const el = swiper.params.touchEventsTarget === 'container' ? swiper.$el : swiper.$wrapperEl;
+	el.setCss({
+		cursor: 'move',
+		cursor: moving ? '-webkit-grabbing' : '-webkit-grab',
+		cursor: moving ? '-moz-grabbin' : '-moz-grab',
+		cursor: moving ? 'grabbing' : 'grab',
+	})
+}

+ 9 - 0
uni_modules/zebra-swiper/libs/grab-cursor/unsetGrabCursor.js

@@ -0,0 +1,9 @@
+export default function unsetGrabCursor() {
+	const swiper = this;
+	if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
+		return;
+	}
+	swiper[swiper.params.touchEventsTarget === 'container' ? '$el' : '$wrapperEl'].setCss({
+		cursor: ''
+	});
+}

+ 8 - 0
uni_modules/zebra-swiper/libs/loop/index.js

@@ -0,0 +1,8 @@
+import loopCreate from './loopCreate.js';
+import loopFix from './loopFix.js';
+import loopDestroy from './loopDestroy.js';
+export default {
+  loopCreate,
+  loopFix,
+  loopDestroy
+};

+ 51 - 0
uni_modules/zebra-swiper/libs/loop/loopCreate.js

@@ -0,0 +1,51 @@
+export default function loopCreate() {
+	const swiper = this;
+	const {
+		params,
+		$wrapperEl,
+		native
+	} = swiper; // Remove duplicated slides
+	const $selector = $wrapperEl;
+	let slides = native.children;
+
+	if (params.loopFillGroupWithBlank) {
+		const blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup;
+
+		if (blankSlidesNum !== params.slidesPerGroup) {
+			native.loopBlankShow = true;
+			native.loopBlankNumber = blankSlidesNum;
+		}
+	}
+
+	if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;
+	swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));
+	swiper.loopedSlides += params.loopAdditionalSlides;
+
+	if (swiper.loopedSlides > slides.length) {
+		swiper.loopedSlides = slides.length;
+	}
+	const prependSlides = [];
+	const appendSlides = [];
+	slides.forEach((el, index) => {
+		const slide = el;
+		if (index < slides.length && index >= slides.length - swiper.loopedSlides) {
+			prependSlides.push(el);
+		}
+
+		if (index < swiper.loopedSlides) {
+			appendSlides.push(el);
+		}
+	});
+	let list = [...swiper.native.value];
+	let newList = [...list];
+	swiper.originalDataList = [...swiper.native.value];
+	for (let i = 0; i < appendSlides.length; i += 1) {
+		newList.push(list[appendSlides[i].index]);
+	}
+
+	for (let i = prependSlides.length - 1; i >= 0; i -= 1) {
+		newList.unshift(list[prependSlides[i].index]);
+	}
+	swiper.native.$emit("input", newList)
+	return true;
+}

+ 8 - 0
uni_modules/zebra-swiper/libs/loop/loopDestroy.js

@@ -0,0 +1,8 @@
+export default function loopDestroy() {
+	const swiper = this;
+	const {
+		$wrapperEl,
+		params,
+		slides
+	} = swiper;
+}

+ 40 - 0
uni_modules/zebra-swiper/libs/loop/loopFix.js

@@ -0,0 +1,40 @@
+export default function loopFix() {
+	const swiper = this;
+	swiper.emit('beforeLoopFix');
+	const {
+		activeIndex,
+		slides,
+		loopedSlides,
+		allowSlidePrev,
+		allowSlideNext,
+		snapGrid,
+		rtlTranslate: rtl
+	} = swiper;
+	let newIndex;
+	swiper.allowSlidePrev = true;
+	swiper.allowSlideNext = true;
+	const snapTranslate = -snapGrid[activeIndex];
+	const diff = snapTranslate - swiper.getTranslate();
+
+	if (activeIndex < loopedSlides) {
+		newIndex = slides.length - loopedSlides * 3 + activeIndex;
+		newIndex += loopedSlides;
+		const slideChanged = swiper.slideTo(newIndex, 0, false, true);
+
+		if (slideChanged && diff !== 0) {
+			swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
+		}
+	} else if (activeIndex >= slides.length - loopedSlides) {
+		newIndex = -slides.length + activeIndex + loopedSlides;
+		newIndex += loopedSlides;
+		const slideChanged = swiper.slideTo(newIndex, 0, false, true);
+
+		if (slideChanged && diff !== 0) {
+			swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
+		}
+	}
+
+	swiper.allowSlidePrev = allowSlidePrev;
+	swiper.allowSlideNext = allowSlideNext;
+	swiper.emit('loopFix');
+}

+ 68 - 0
uni_modules/zebra-swiper/libs/mixins/relation.js

@@ -0,0 +1,68 @@
+export function ChildrenMixin(parent, options = {}) {
+	const indexKey = options.indexKey || 'index';
+	return {
+		inject: {
+			[parent]: {
+				default: null,
+			},
+		},
+		mounted() {
+			this.parent = this[parent];
+			this.bindRelation();
+		},
+		// #ifdef VUE2
+		beforeDestroy() {
+			if (this.parent) {
+				this.parent.children = this.parent.children.filter(
+					(item) => item !== this
+				);
+				uni.$emit("childrenReady" + this.parent._uid, this);
+			}
+		},
+		// #endif
+		// #ifdef VUE3
+		beforeUnmount() {
+			if (this.parent) {
+				this.parent.children = this.parent.children.filter(
+					(item) => item !== this
+				);
+				uni.$emit("childrenReady" + this.parent._uid, this);
+			}
+		},
+		// #endif
+		methods: {
+			bindRelation() {
+				if (!this.parent || this.parent.children.indexOf(this) !== -1) {
+					return;
+				}
+				const children = [...this.parent.children, this];
+				this.parent.children = children;
+				this.index = this.parent.children.indexOf(this);
+				uni.$emit("childrenReady" + this.parent._uid, this);
+			},
+		},
+	};
+}
+
+export function ParentMixin(parent) {
+	return {
+		provide() {
+			return {
+				[parent]: this,
+			};
+		},
+		created() {
+			this.children = [];
+		},
+		// #ifdef VUE2
+		beforeDestroy() {
+			uni.$off("childrenReady" + this._uid)
+		},
+		// #endif
+		// #ifdef VUE3
+		beforeUnmount() {
+			uni.$off("childrenReady" + this._uid)
+		},
+		// #endif
+	};
+}

+ 41 - 0
uni_modules/zebra-swiper/libs/moduleExtendParams.js

@@ -0,0 +1,41 @@
+import {
+	extend
+} from '../shared/utils.js';
+export default function moduleExtendParams(params, allModulesParams) {
+	return function extendParams(obj = {}) {
+		const moduleParamName = Object.keys(obj)[0];
+		const moduleParams = obj[moduleParamName];
+
+		if (typeof moduleParams !== 'object' || moduleParams === null) {
+			extend(allModulesParams, obj);
+			return;
+		}
+
+		if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] ===
+			true) {
+			params[moduleParamName] = {
+				auto: true
+			};
+		}
+
+		if (!(moduleParamName in params && 'enabled' in moduleParams)) {
+			extend(allModulesParams, obj);
+			return;
+		}
+
+		if (params[moduleParamName] === true) {
+			params[moduleParamName] = {
+				enabled: true
+			};
+		}
+
+		if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
+			params[moduleParamName].enabled = true;
+		}
+
+		if (!params[moduleParamName]) params[moduleParamName] = {
+			enabled: false
+		};
+		extend(allModulesParams, obj);
+	};
+}

+ 16 - 0
uni_modules/zebra-swiper/libs/slide/index.js

@@ -0,0 +1,16 @@
+import slideTo from './slideTo.js';
+import slideToLoop from './slideToLoop.js';
+import slideNext from './slideNext.js';
+import slidePrev from './slidePrev.js';
+import slideReset from './slideReset.js';
+import slideToClosest from './slideToClosest.js';
+import slideToClickedSlide from './slideToClickedSlide.js';
+export default {
+	slideTo,
+	slideToLoop,
+	slideNext,
+	slidePrev,
+	slideReset,
+	slideToClosest,
+	slideToClickedSlide
+};

+ 29 - 0
uni_modules/zebra-swiper/libs/slide/slideNext.js

@@ -0,0 +1,29 @@
+export default function slideNext(speed = this.params.speed, runCallbacks = true, internal) {
+	const swiper = this;
+	const {
+		animating,
+		enabled,
+		params
+	} = swiper;
+	if (!enabled) return swiper;
+	let perGroup = params.slidesPerGroup;
+
+	if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
+		perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
+	}
+
+	const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
+
+	if (params.loop) {
+		if (animating && params.loopPreventsSlide) return false;
+		swiper.loopFix();
+	}
+
+	if (params.rewind && swiper.isEnd) {
+		return swiper.slideTo(0, speed, runCallbacks, internal);
+	}
+	setTimeout(() => {
+		swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal)
+	}, 0)
+	return true;
+}

+ 63 - 0
uni_modules/zebra-swiper/libs/slide/slidePrev.js

@@ -0,0 +1,63 @@
+export default function slidePrev(speed = this.params.speed, runCallbacks = true, internal) {
+	const swiper = this;
+	const {
+		params,
+		animating,
+		snapGrid,
+		slidesGrid,
+		rtlTranslate,
+		enabled
+	} = swiper;
+	if (!enabled) return swiper;
+
+	if (params.loop) {
+		if (animating && params.loopPreventsSlide) return false;
+		swiper.loopFix();
+
+	}
+
+	const translate = rtlTranslate ? swiper.translate : -swiper.translate;
+
+	function normalize(val) {
+		if (val < 0) return -Math.floor(Math.abs(val));
+		return Math.floor(val);
+	}
+
+	const normalizedTranslate = normalize(translate);
+	const normalizedSnapGrid = snapGrid.map(val => normalize(val));
+	let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
+
+	if (typeof prevSnap === 'undefined' && params.cssMode) {
+		let prevSnapIndex;
+		snapGrid.forEach((snap, snapIndex) => {
+			if (normalizedTranslate >= snap) {
+				prevSnapIndex = snapIndex;
+			}
+		});
+
+		if (typeof prevSnapIndex !== 'undefined') {
+			prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
+		}
+	}
+
+	let prevIndex = 0;
+
+	if (typeof prevSnap !== 'undefined') {
+		prevIndex = slidesGrid.indexOf(prevSnap);
+		if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
+
+		if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
+			prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
+			prevIndex = Math.max(prevIndex, 0);
+		}
+	}
+
+	if (params.rewind && swiper.isBeginning) {
+		return swiper.slideTo(swiper.slides.length - 1, speed, runCallbacks, internal);
+	}
+
+	setTimeout(() => {
+		swiper.slideTo(prevIndex, speed, runCallbacks, internal)
+	}, 30)
+	return true;
+}

+ 4 - 0
uni_modules/zebra-swiper/libs/slide/slideReset.js

@@ -0,0 +1,4 @@
+export default function slideReset(speed = this.params.speed, runCallbacks = true, internal) {
+  const swiper = this;
+  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
+}

+ 188 - 0
uni_modules/zebra-swiper/libs/slide/slideTo.js

@@ -0,0 +1,188 @@
+import {
+	animateCSSModeScroll
+} from '../../shared/utils.js';
+export default function slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {
+	if (typeof index !== 'number' && typeof index !== 'string') {
+		throw new Error(
+			`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);
+	}
+
+	if (typeof index === 'string') {
+		/**
+		 * The `index` argument converted from `string` to `number`.
+		 * @type {number}
+		 */
+		const indexAsNumber = parseInt(index, 10);
+		/**
+		 * Determines whether the `index` argument is a valid `number`
+		 * after being converted from the `string` type.
+		 * @type {boolean}
+		 */
+
+		const isValidNumber = isFinite(indexAsNumber);
+
+		if (!isValidNumber) {
+			throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);
+		} // Knowing that the converted `index` is a valid number,
+		// we can update the original argument's value.
+
+
+		index = indexAsNumber;
+	}
+
+	const swiper = this;
+	let slideIndex = index;
+	let timer;
+	if (slideIndex < 0) slideIndex = 0;
+	const {
+		params,
+		snapGrid,
+		slidesGrid,
+		previousIndex,
+		activeIndex,
+		rtlTranslate: rtl,
+		wrapperEl,
+		enabled
+	} = swiper;
+
+	if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
+		return false;
+	}
+
+	const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
+	let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
+	if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
+
+	if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
+		swiper.emit('beforeSlideChangeStart');
+	}
+	const translate = -snapGrid[snapIndex]; // Update progress
+
+	swiper.updateProgress(translate); // Normalize slideIndex
+
+	if (params.normalizeSlideIndex) {
+		for (let i = 0; i < slidesGrid.length; i += 1) {
+			const normalizedTranslate = -Math.floor(translate * 100);
+			const normalizedGrid = Math.floor(slidesGrid[i] * 100);
+			const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
+			if (typeof slidesGrid[i + 1] !== 'undefined') {
+				if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (
+						normalizedGridNext - normalizedGrid) / 2) {
+					slideIndex = i;
+				} else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
+					slideIndex = i + 1;
+				}
+			} else if (normalizedTranslate >= normalizedGrid) {
+				slideIndex = i;
+			}
+
+		}
+	} // Directions locks
+
+
+	if (swiper.initialized && slideIndex !== activeIndex) {
+		if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
+			return false;
+		}
+
+		if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
+			if ((activeIndex || 0) !== slideIndex) return false;
+		}
+	}
+
+	let direction;
+	if (slideIndex > activeIndex) direction = 'next';
+	else if (slideIndex < activeIndex) direction = 'prev';
+	else direction = 'reset'; // Update Index
+
+	if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
+		swiper.updateActiveIndex(slideIndex); // Update Height
+
+		if (params.autoHeight) {
+			setTimeout(() => {
+				swiper.updateAutoHeight();
+			}, 0)
+		}
+
+		swiper.updateSlidesClasses();
+
+		if (params.effect !== 'slide') {
+			swiper.setTranslate(translate);
+		}
+
+		if (direction !== 'reset') {
+			swiper.transitionStart(runCallbacks, direction);
+			swiper.transitionEnd(runCallbacks, direction);
+		}
+
+		return false;
+	}
+
+	if (params.cssMode) {
+		const isH = swiper.isHorizontal();
+		const t = rtl ? translate : -translate;
+
+		if (speed === 0) {
+			const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
+
+			if (isVirtual) {
+				swiper.wrapperEl.style.scrollSnapType = 'none';
+				swiper._immediateVirtual = true;
+			}
+
+			wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
+
+			if (isVirtual) {
+				requestAnimationFrame(() => {
+					swiper.wrapperEl.style.scrollSnapType = '';
+					swiper._swiperImmediateVirtual = false;
+				});
+			}
+		} else {
+			if (!swiper.support.smoothScroll) {
+				animateCSSModeScroll({
+					swiper,
+					targetPosition: t,
+					side: isH ? 'left' : 'top'
+				});
+				return true;
+			}
+
+			wrapperEl.scrollTo({
+				[isH ? 'left' : 'top']: t,
+				behavior: 'smooth'
+			});
+		}
+
+		return true;
+	}
+	swiper.setTransition(speed);
+	swiper.setTranslate(translate);
+	swiper.updateActiveIndex(slideIndex);
+	swiper.updateSlidesClasses();
+	swiper.emit('beforeTransitionStart', speed, internal);
+	swiper.transitionStart(runCallbacks, direction);
+
+	if (speed === 0) {
+		swiper.transitionEnd(runCallbacks, direction);
+	} else if (!swiper.animating) {
+		swiper.animating = true;
+
+		if (!swiper.onSlideToWrapperTransitionEnd) {
+			swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
+				if (!swiper || swiper.destroyed) return;
+				clearTimeout(timer)
+				swiper.onSlideToWrapperTransitionEnd = null;
+				delete swiper.onSlideToWrapperTransitionEnd;
+				swiper.transitionEnd(runCallbacks, direction);
+			};
+		}
+		timer = setTimeout(() => {
+			if (swiper.onSlideToWrapperTransitionEnd) {
+				swiper.onSlideToWrapperTransitionEnd();
+			}
+		}, speed)
+	}
+
+	return true;
+}

+ 46 - 0
uni_modules/zebra-swiper/libs/slide/slideToClickedSlide.js

@@ -0,0 +1,46 @@
+import {
+	nextTick
+} from '../../shared/utils.js';
+export default function slideToClickedSlide() {
+	const swiper = this;
+	const {
+		params,
+		$wrapperEl
+	} = swiper;
+	const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
+	let slideToIndex = swiper.clickedIndex;
+	let realIndex;
+
+	if (params.loop) {
+		if (swiper.animating) return;
+		// realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);
+		realIndex = parseInt(swiper.activeIndex, 10);
+
+		if (params.centeredSlides) {
+			if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper
+				.loopedSlides + slidesPerView / 2) {
+				swiper.loopFix();
+				slideToIndex = $wrapperEl.children(
+					`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`
+					).eq(0).index();
+				nextTick(() => {
+					swiper.slideTo(slideToIndex);
+				});
+			} else {
+				swiper.slideTo(slideToIndex);
+			}
+		} else if (slideToIndex > swiper.slides.length - slidesPerView) {
+			swiper.loopFix();
+			slideToIndex = $wrapperEl.children(
+					`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`)
+				.eq(0).index();
+			nextTick(() => {
+				swiper.slideTo(slideToIndex);
+			});
+		} else {
+			swiper.slideTo(slideToIndex);
+		}
+	} else {
+		swiper.slideTo(slideToIndex);
+	}
+}

+ 28 - 0
uni_modules/zebra-swiper/libs/slide/slideToClosest.js

@@ -0,0 +1,28 @@
+/* eslint no-unused-vars: "off" */
+export default function slideToClosest(speed = this.params.speed, runCallbacks = true, internal, threshold = 0.5) {
+  const swiper = this;
+  let index = swiper.activeIndex;
+  const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
+  const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
+  const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
+
+  if (translate >= swiper.snapGrid[snapIndex]) {
+    const currentSnap = swiper.snapGrid[snapIndex];
+    const nextSnap = swiper.snapGrid[snapIndex + 1];
+
+    if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
+      index += swiper.params.slidesPerGroup;
+    }
+  } else {
+    const prevSnap = swiper.snapGrid[snapIndex - 1];
+    const currentSnap = swiper.snapGrid[snapIndex];
+
+    if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
+      index -= swiper.params.slidesPerGroup;
+    }
+  }
+
+  index = Math.max(index, 0);
+  index = Math.min(index, swiper.slidesGrid.length - 1);
+  return swiper.slideTo(index, speed, runCallbacks, internal);
+}

+ 10 - 0
uni_modules/zebra-swiper/libs/slide/slideToLoop.js

@@ -0,0 +1,10 @@
+export default function slideToLoop(index = 0, speed = this.params.speed, runCallbacks = true, internal) {
+  const swiper = this;
+  let newIndex = index;
+
+  if (swiper.params.loop) {
+    newIndex += swiper.loopedSlides;
+  }
+
+  return swiper.slideTo(newIndex, speed, runCallbacks, internal);
+}

+ 8 - 0
uni_modules/zebra-swiper/libs/transition/index.js

@@ -0,0 +1,8 @@
+import setTransition from './setTransition.js';
+import transitionStart from './transitionStart.js';
+import transitionEnd from './transitionEnd.js';
+export default {
+	setTransition,
+	transitionStart,
+	transitionEnd
+};

+ 9 - 0
uni_modules/zebra-swiper/libs/transition/setTransition.js

@@ -0,0 +1,9 @@
+export default function setTransition(duration, byController) {
+	const swiper = this;
+	if (!swiper.$wrapperEl) return
+	if (!swiper.params.cssMode) {
+		swiper.$wrapperEl.transition(duration);
+	}
+
+	swiper.emit('setTransition', duration, byController);
+}

+ 35 - 0
uni_modules/zebra-swiper/libs/transition/transitionEmit.js

@@ -0,0 +1,35 @@
+export default function transitionEmit({
+	swiper,
+	runCallbacks,
+	direction,
+	step
+}) {
+	const {
+		activeIndex,
+		previousIndex
+	} = swiper;
+	let dir = direction;
+
+	if (!dir) {
+		if (activeIndex > previousIndex) dir = 'next';
+		else if (activeIndex < previousIndex) dir = 'prev';
+		else dir = 'reset';
+	}
+
+	swiper.emit(`transition${step}`);
+
+	if (runCallbacks && activeIndex !== previousIndex) {
+		if (dir === 'reset') {
+			swiper.emit(`slideResetTransition${step}`);
+			return;
+		}
+
+		swiper.emit(`slideChangeTransition${step}`);
+
+		if (dir === 'next') {
+			swiper.emit(`slideNextTransition${step}`);
+		} else {
+			swiper.emit(`slidePrevTransition${step}`);
+		}
+	}
+}

+ 16 - 0
uni_modules/zebra-swiper/libs/transition/transitionEnd.js

@@ -0,0 +1,16 @@
+import transitionEmit from './transitionEmit.js';
+export default function transitionEnd(runCallbacks = true, direction) {
+	const swiper = this;
+	const {
+		params
+	} = swiper;
+	swiper.animating = false;
+	if (params.cssMode) return;
+	swiper.setTransition(0);
+	transitionEmit({
+		swiper,
+		runCallbacks,
+		direction,
+		step: 'End'
+	});
+}

+ 19 - 0
uni_modules/zebra-swiper/libs/transition/transitionStart.js

@@ -0,0 +1,19 @@
+import transitionEmit from './transitionEmit.js';
+export default function transitionStart(runCallbacks = true, direction) {
+	const swiper = this;
+	const {
+		params
+	} = swiper;
+	if (params.cssMode) return;
+
+	if (params.autoHeight) {
+		swiper.updateAutoHeight();
+	}
+
+	transitionEmit({
+		swiper,
+		runCallbacks,
+		direction,
+		step: 'Start'
+	});
+}

+ 23 - 0
uni_modules/zebra-swiper/libs/translate/getTranslate.js

@@ -0,0 +1,23 @@
+import {
+	getTranslate
+} from '../../shared/utils.js';
+export default function getSwiperTranslate(axis = this.isHorizontal() ? 'x' : 'y') {
+	const swiper = this;
+	const {
+		params,
+		rtlTranslate: rtl,
+		translate,
+		$wrapperEl
+	} = swiper;
+
+	if (params.virtualTranslate) {
+		return rtl ? -translate : translate;
+	}
+
+	if (params.cssMode) {
+		return translate;
+	}
+	let currentTranslate = getTranslate(swiper, axis);
+	if (rtl) currentTranslate = -currentTranslate;
+	return currentTranslate || 0;
+}

+ 12 - 0
uni_modules/zebra-swiper/libs/translate/index.js

@@ -0,0 +1,12 @@
+import getTranslate from './getTranslate.js';
+import setTranslate from './setTranslate.js';
+import minTranslate from './minTranslate.js';
+import maxTranslate from './maxTranslate.js';
+import translateTo from './translateTo.js';
+export default {
+  getTranslate,
+  setTranslate,
+  minTranslate,
+  maxTranslate,
+  translateTo
+};

+ 3 - 0
uni_modules/zebra-swiper/libs/translate/maxTranslate.js

@@ -0,0 +1,3 @@
+export default function maxTranslate() {
+  return -this.snapGrid[this.snapGrid.length - 1];
+}

+ 3 - 0
uni_modules/zebra-swiper/libs/translate/minTranslate.js

@@ -0,0 +1,3 @@
+export default function minTranslate() {
+  return -this.snapGrid[0];
+}

+ 51 - 0
uni_modules/zebra-swiper/libs/translate/setTranslate.js

@@ -0,0 +1,51 @@
+export default function setTranslate(translate, byController) {
+	const swiper = this;
+	const {
+		rtlTranslate: rtl,
+		params,
+		$wrapperEl,
+		wrapperEl,
+		progress
+	} = swiper;
+	let x = 0;
+	let y = 0;
+	const z = 0;
+	if (isNaN(translate)) {
+		return
+	}
+	if (!$wrapperEl) return
+	if (swiper.isHorizontal()) {
+		x = rtl ? -translate : translate;
+	} else {
+		y = translate;
+	}
+
+	if (params.roundLengths) {
+		x = Math.floor(x);
+		y = Math.floor(y);
+	}
+
+	if (params.cssMode) {
+		wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
+	} else if (!params.virtualTranslate) {
+		$wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`);
+	}
+
+	swiper.previousTranslate = swiper.translate;
+	swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress
+
+	let newProgress;
+	const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
+
+	if (translatesDiff === 0) {
+		newProgress = 0;
+	} else {
+		newProgress = (translate - swiper.minTranslate()) / translatesDiff;
+	}
+
+	if (newProgress !== progress) {
+		swiper.updateProgress(translate);
+	}
+
+	swiper.emit('setTranslate', swiper.translate, byController);
+}

+ 90 - 0
uni_modules/zebra-swiper/libs/translate/translateTo.js

@@ -0,0 +1,90 @@
+import {
+	animateCSSModeScroll
+} from '../../shared/utils.js';
+export default function translateTo(translate = 0, speed = this.params.speed, runCallbacks = true, translateBounds =
+	true, internal) {
+	const swiper = this;
+	let timer;
+	const {
+		params,
+		wrapperEl
+	} = swiper;
+
+	if (swiper.animating && params.preventInteractionOnTransition) {
+		return false;
+	}
+
+	const minTranslate = swiper.minTranslate();
+	const maxTranslate = swiper.maxTranslate();
+	let newTranslate;
+	if (translateBounds && translate > minTranslate) newTranslate = minTranslate;
+	else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;
+	else newTranslate = translate; // Update progress
+
+	swiper.updateProgress(newTranslate);
+
+	if (params.cssMode) {
+		const isH = swiper.isHorizontal();
+
+		if (speed === 0) {
+			wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
+		} else {
+			if (!swiper.support.smoothScroll) {
+				animateCSSModeScroll({
+					swiper,
+					targetPosition: -newTranslate,
+					side: isH ? 'left' : 'top'
+				});
+				return true;
+			}
+
+			wrapperEl.scrollTo({
+				[isH ? 'left' : 'top']: -newTranslate,
+				behavior: 'smooth'
+			});
+		}
+
+		return true;
+	}
+
+	if (speed === 0) {
+		swiper.setTransition(0);
+		swiper.setTranslate(newTranslate);
+
+		if (runCallbacks) {
+			swiper.emit('beforeTransitionStart', speed, internal);
+			swiper.emit('transitionEnd');
+		}
+	} else {
+		swiper.setTransition(speed);
+		swiper.setTranslate(newTranslate);
+
+		if (runCallbacks) {
+			swiper.emit('beforeTransitionStart', speed, internal);
+			swiper.emit('transitionStart');
+		}
+
+		if (!swiper.animating) {
+			swiper.animating = true;
+
+			if (!swiper.onTranslateToWrapperTransitionEnd) {
+				swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
+					if (!swiper || swiper.destroyed) return;
+					if (e.target !== this) return;
+					clearTimeout(timer)
+					swiper.onTranslateToWrapperTransitionEnd = null;
+					delete swiper.onTranslateToWrapperTransitionEnd;
+
+					if (runCallbacks) {
+						swiper.emit('transitionEnd');
+					}
+				};
+			}
+			timer = setTimeout(() => {
+				swiper.onTranslateToWrapperTransitionEnd();
+			}, speed)
+		}
+	}
+
+	return true;
+}

+ 20 - 0
uni_modules/zebra-swiper/libs/update/index.js

@@ -0,0 +1,20 @@
+import updateSize from './updateSize.js';
+import updateSlides from './updateSlides.js';
+import updateAutoHeight from './updateAutoHeight.js';
+import updateSlidesOffset from './updateSlidesOffset.js';
+import updateSlidesProgress from './updateSlidesProgress.js';
+import updateProgress from './updateProgress.js';
+import updateSlidesClasses from './updateSlidesClasses.js';
+import updateActiveIndex from './updateActiveIndex.js';
+import updateClickedSlide from './updateClickedSlide.js';
+export default {
+	updateSize,
+	updateSlides,
+	updateAutoHeight,
+	updateSlidesOffset,
+	updateSlidesProgress,
+	updateProgress,
+	updateSlidesClasses,
+	updateActiveIndex,
+	updateClickedSlide
+};

+ 102 - 0
uni_modules/zebra-swiper/libs/update/updateActiveIndex.js

@@ -0,0 +1,102 @@
+export default function updateActiveIndex(newActiveIndex) {
+	const swiper = this;
+	const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
+	const {
+		slidesGrid,
+		snapGrid,
+		params,
+		activeIndex: previousIndex,
+		realIndex: previousRealIndex,
+		snapIndex: previousSnapIndex
+	} = swiper;
+	let activeIndex = newActiveIndex;
+	let snapIndex;
+
+	if (typeof activeIndex === 'undefined') {
+		for (let i = 0; i < slidesGrid.length; i += 1) {
+			if (typeof slidesGrid[i + 1] !== 'undefined') {
+				if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) /
+					2) {
+					activeIndex = i;
+				} else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
+					activeIndex = i + 1;
+				}
+			} else if (translate >= slidesGrid[i]) {
+				activeIndex = i;
+			}
+		} // Normalize slideIndex
+
+
+		if (params.normalizeSlideIndex) {
+			if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
+		}
+
+	}
+
+	if (snapGrid.indexOf(translate) >= 0) {
+		snapIndex = snapGrid.indexOf(translate);
+	} else {
+		const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
+		snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
+	}
+
+	if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
+
+
+
+	if (swiper.loopedSlides) {
+		swiper.slides.filter((item) => item.index >= swiper.loopedSlides && item.index < swiper.slides.length - swiper
+			.loopedSlides).forEach((item, index) => {
+			item.dataSwiperSlideIndex = item.index - swiper.loopedSlides;
+		})
+		swiper.slides.filter((item) => item.index < swiper.loopedSlides).forEach((item, index) => {
+			if (swiper.slides[swiper.slides.length - swiper.loopedSlides * 3 + index]) {
+				item.dataSwiperSlideIndex = swiper.slides[swiper.slides.length - swiper.loopedSlides * 3 +
+						index]
+					.index;
+			}
+		})
+		swiper.slides.filter((item) => item.index >= swiper.slides.length - swiper
+			.loopedSlides).forEach((item, index) => {
+			item.dataSwiperSlideIndex = swiper.slides[index].index;
+		})
+	}
+
+
+	if (activeIndex === previousIndex) {
+		if (snapIndex !== previousSnapIndex) {
+			swiper.snapIndex = snapIndex;
+			swiper.emit('snapIndexChange');
+		}
+
+		return;
+	} // Get real index
+
+	let realIndex;
+	if (swiper.virtual && params.virtual.enabled) {
+		realIndex = activeIndex;
+	} else {
+		if (swiper.slides[activeIndex].dataSwiperSlideIndex == undefined || swiper.slides[activeIndex]
+			.dataSwiperSlideIndex == null) {
+			realIndex = activeIndex;
+		} else {
+			realIndex = swiper.slides[activeIndex].dataSwiperSlideIndex;
+		}
+	}
+	Object.assign(swiper, {
+		snapIndex,
+		realIndex,
+		previousIndex,
+		activeIndex
+	});
+	swiper.emit('activeIndexChange');
+	swiper.emit('snapIndexChange');
+
+	if (previousRealIndex !== realIndex) {
+		swiper.emit('realIndexChange');
+	}
+
+	if (swiper.initialized || swiper.params.runCallbacksOnInit) {
+		swiper.emit('slideChange', activeIndex);
+	}
+}

+ 53 - 0
uni_modules/zebra-swiper/libs/update/updateAutoHeight.js

@@ -0,0 +1,53 @@
+export default async function updateAutoHeight(speed) {
+	const swiper = this;
+	const activeSlides = [];
+	const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
+	let newHeight = 0;
+	let i;
+
+	if (typeof speed === 'number') {
+		swiper.setTransition(speed);
+	} else if (speed === true) {
+		swiper.setTransition(swiper.params.speed);
+	}
+
+	const getSlideByIndex = index => {
+		if (isVirtual) {
+			return swiper.slides.filter(el => parseInt(el.getAttribute('data-swiper-slide-index'), 10) ===
+				index)[
+				0];
+		}
+
+		return swiper.slides[index];
+	}; // Find slides currently in view
+
+	if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
+		if (swiper.params.centeredSlides) {
+			swiper.visibleSlides.each(slide => {
+				activeSlides.push(slide);
+			});
+		} else {
+			for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
+				const index = swiper.activeIndex + i;
+				if (index > swiper.slides.length && !isVirtual) break;
+				activeSlides.push(getSlideByIndex(index));
+			}
+		}
+	} else {
+		activeSlides.push(getSlideByIndex(swiper.activeIndex));
+	} // Find new height from highest slide in view
+
+
+	for (i = 0; i < activeSlides.length; i += 1) {
+		if (typeof activeSlides[i] !== 'undefined') {
+			const size = await activeSlides[i].getSize();
+			const height = size.height;
+			newHeight = height > newHeight ? height : newHeight;
+		}
+	} // Update Height
+
+
+	if (newHeight || newHeight === 0) swiper.$wrapperEl.css({
+		height: `${newHeight?newHeight:''}px`
+	});
+}

+ 35 - 0
uni_modules/zebra-swiper/libs/update/updateClickedSlide.js

@@ -0,0 +1,35 @@
+export default function updateClickedSlide(e) {
+	const swiper = this;
+	const params = swiper.params;
+	const slide = swiper.slides[e];
+	let slideFound = false;
+	let slideIndex;
+
+	if (slide) {
+		for (let i = 0; i < swiper.slides.length; i += 1) {
+			if (swiper.slides[i] === slide) {
+				slideFound = true;
+				slideIndex = i;
+				break;
+			}
+		}
+	}
+
+	if (slide && slideFound) {
+		swiper.clickedSlide = slide;
+
+		if (swiper.virtual && swiper.params.virtual.enabled) {
+			swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10);
+		} else {
+			swiper.clickedIndex = slideIndex;
+		}
+	} else {
+		swiper.clickedSlide = undefined;
+		swiper.clickedIndex = undefined;
+		return;
+	}
+
+	if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
+		swiper.slideToClickedSlide();
+	}
+}

+ 50 - 0
uni_modules/zebra-swiper/libs/update/updateProgress.js

@@ -0,0 +1,50 @@
+export default function updateProgress(translate) {
+  const swiper = this;
+
+  if (typeof translate === 'undefined') {
+    const multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line
+
+    translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
+  }
+
+  const params = swiper.params;
+  const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
+  let {
+    progress,
+    isBeginning,
+    isEnd
+  } = swiper;
+  const wasBeginning = isBeginning;
+  const wasEnd = isEnd;
+
+  if (translatesDiff === 0) {
+    progress = 0;
+    isBeginning = true;
+    isEnd = true;
+  } else {
+    progress = (translate - swiper.minTranslate()) / translatesDiff;
+    isBeginning = progress <= 0;
+    isEnd = progress >= 1;
+  }
+
+  Object.assign(swiper, {
+    progress,
+    isBeginning,
+    isEnd
+  });
+  if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
+
+  if (isBeginning && !wasBeginning) {
+    swiper.emit('reachBeginning toEdge');
+  }
+
+  if (isEnd && !wasEnd) {
+    swiper.emit('reachEnd toEdge');
+  }
+
+  if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
+    swiper.emit('fromEdge');
+  }
+
+  swiper.emit('progress', progress);
+}

+ 28 - 0
uni_modules/zebra-swiper/libs/update/updateSize.js

@@ -0,0 +1,28 @@
+export default function updateSize() {
+	const swiper = this;
+	let width;
+	let height;
+	const el = swiper.el;
+	if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
+		width = swiper.params.width;
+	} else {
+		width = el.width;
+	}
+
+	if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
+		height = swiper.params.height;
+	} else {
+		height = el.height;
+	}
+
+	if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
+		return;
+	} // Subtract paddings
+	if (Number.isNaN(width)) width = 0;
+	if (Number.isNaN(height)) height = 0;
+	Object.assign(swiper, {
+		width,
+		height,
+		size: swiper.isHorizontal() ? width : height
+	});
+}

+ 311 - 0
uni_modules/zebra-swiper/libs/update/updateSlides.js

@@ -0,0 +1,311 @@
+import {
+	setCSSProperty
+} from '../../shared/utils.js';
+export default function updateSlides() {
+	const swiper = this;
+
+	function getDirectionLabel(property) {
+		if (swiper.isHorizontal()) {
+			return property;
+		} // prettier-ignore
+
+
+		return {
+			'width': 'height',
+			'margin-top': 'margin-left',
+			'margin-bottom ': 'margin-right',
+			'margin-left': 'margin-top',
+			'margin-right': 'margin-bottom',
+			'padding-left': 'padding-top',
+			'padding-right': 'padding-bottom',
+			'marginRight': 'marginBottom'
+		} [property];
+	}
+
+	function getDirectionPropertyValue(node, label) {
+		return parseFloat(node[getDirectionLabel(label)] || 0);
+	}
+
+	function getComputedStyle(native) {
+		return native.itemStyle;
+	}
+	const params = swiper.params;
+	const {
+		$wrapperEl,
+		size: swiperSize,
+		rtlTranslate: rtl,
+		wrongRTL
+	} = swiper;
+	const isVirtual = swiper.virtual && params.virtual.enabled;
+	const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
+	// const slides = $wrapperEl.children(`.${swiper.params.slideClass}`);
+	const slides = swiper.slides;
+	const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
+	let snapGrid = [];
+	const slidesGrid = [];
+	const slidesSizesGrid = [];
+	let offsetBefore = params.slidesOffsetBefore;
+
+	if (typeof offsetBefore === 'function') {
+		offsetBefore = params.slidesOffsetBefore.call(swiper);
+	}
+
+	let offsetAfter = params.slidesOffsetAfter;
+
+	if (typeof offsetAfter === 'function') {
+		offsetAfter = params.slidesOffsetAfter.call(swiper);
+	}
+
+	const previousSnapGridLength = swiper.snapGrid.length;
+	const previousSlidesGridLength = swiper.slidesGrid.length;
+	let spaceBetween = params.spaceBetween;
+	let slidePosition = -offsetBefore;
+	let prevSlideSize = 0;
+	let index = 0;
+
+	if (typeof swiperSize === 'undefined') {
+		return;
+	}
+
+	if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
+		spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
+	}
+
+	swiper.virtualSize = -spaceBetween; // reset margins
+
+	if (params.centeredSlides && params.cssMode) {
+		setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', '');
+		setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', '');
+	}
+
+	const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
+
+	if (gridEnabled) {
+		swiper.grid.initSlides(slidesLength);
+	}
+
+
+	let slideSize;
+	const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params
+		.breakpoints).filter(key => {
+		return typeof params.breakpoints[key].slidesPerView !== 'undefined';
+	}).length > 0;
+	Array(...Array(slidesLength)).forEach(async (item, i) => {
+		slideSize = 0;
+		const slide = slides[i];
+
+		if (gridEnabled) {
+			swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);
+		}
+		if (params.slidesPerView === 'auto') {
+			if (shouldResetSlideSize) {
+				slides[i].style[getDirectionLabel('width')] = ``;
+			}
+
+			const slideStyles = getComputedStyle(slide);
+			const currentTransform = slide.itemStyle.transform;
+			const currentWebKitTransform = slide.itemStyle.webkitTransform;
+
+			if (currentTransform) {
+				slide.itemStyle.transform = 'none';
+			}
+
+			if (currentWebKitTransform) {
+				slide.itemStyle.webkitTransform = 'none';
+			}
+
+			if (params.roundLengths) {
+				slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
+			} else {
+				const width = swiper.isHorizontal() ? slide.width : slide.height;
+				const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
+				const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
+				const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
+				const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
+				const boxSizing = slideStyles['box-sizing'];
+
+				if (boxSizing && boxSizing === 'border-box') {
+					slideSize = width + marginLeft + marginRight;
+				} else {
+					// slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight;
+					slideSize = width;
+				}
+			}
+
+			if (currentTransform) {
+				slide.itemStyle.transform = currentTransform;
+			}
+
+			if (currentWebKitTransform) {
+				slide.itemStyle.webkitTransform = currentWebKitTransform;
+			}
+
+			if (params.roundLengths) slideSize = Math.floor(slideSize);
+		} else {
+			slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
+			if (params.roundLengths) slideSize = Math.floor(slideSize);
+			slides[i] && slides[i].css({
+				[getDirectionLabel('width')]: `${slideSize}px`
+			})
+		}
+
+		if (slides[i]) {
+			slides[i].swiperSlideSize = slideSize;
+		}
+
+		if (params.autoHeight) {
+			slides[i] && slides[i].css({
+				height: 'auto'
+			})
+		}
+
+		slidesSizesGrid.push(slideSize);
+
+		if (params.centeredSlides) {
+			slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
+			if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 -
+				spaceBetween;
+			if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
+			if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
+			if (params.roundLengths) slidePosition = Math.floor(slidePosition);
+			if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
+			slidesGrid.push(slidePosition);
+		} else {
+			if (params.roundLengths) slidePosition = Math.floor(slidePosition);
+			if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params
+				.slidesPerGroup === 0)
+				snapGrid.push(slidePosition);
+			slidesGrid.push(slidePosition);
+			slidePosition = slidePosition + slideSize + spaceBetween;
+		}
+		swiper.virtualSize += slideSize + spaceBetween;
+		prevSlideSize = slideSize;
+		index += 1;
+	})
+	swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
+
+	if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
+		$wrapperEl.css({
+			width: `${swiper.virtualSize + params.spaceBetween}px`
+		});
+	}
+
+	if (params.setWrapperSize) {
+		$wrapperEl.css({
+			[getDirectionLabel('width')]: `${swiper.virtualSize + params.spaceBetween}px`
+		});
+	}
+
+	if (gridEnabled) {
+		swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel);
+	} // Remove last grid elements depending on width
+
+
+	if (!params.centeredSlides) {
+		const newSlidesGrid = [];
+
+		for (let i = 0; i < snapGrid.length; i += 1) {
+			let slidesGridItem = snapGrid[i];
+			if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
+
+			if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
+				newSlidesGrid.push(slidesGridItem);
+			}
+		}
+		snapGrid = newSlidesGrid;
+
+		if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
+			snapGrid.push(swiper.virtualSize - swiperSize);
+		}
+	}
+
+	if (snapGrid.length === 0) snapGrid = [0];
+
+	if (params.spaceBetween !== 0) {
+		// #ifdef MP-BAIDU
+		const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');
+		// #endif
+		// #ifndef MP-BAIDU
+		const key = swiper.isHorizontal() && rtl ? 'margin-left' : getDirectionLabel('margin-right');
+		// #endif
+		slides.filter((_, slideIndex) => {
+			if (!params.cssMode) return true;
+
+			if (slideIndex === slides.length - 1) {
+				return false;
+			}
+
+			return true;
+		}).forEach((item) => {
+			item.css({
+				[key]: `${spaceBetween}px`
+			})
+		});
+	}
+	if (params.centeredSlides && params.centeredSlidesBounds) {
+		let allSlidesSize = 0;
+		slidesSizesGrid.forEach(slideSizeValue => {
+			allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
+		});
+		allSlidesSize -= params.spaceBetween;
+		const maxSnap = allSlidesSize - swiperSize;
+		snapGrid = snapGrid.map(snap => {
+			if (snap < 0) return -offsetBefore;
+			if (snap > maxSnap) return maxSnap + offsetAfter;
+			return snap;
+		});
+	}
+
+	if (params.centerInsufficientSlides) {
+		let allSlidesSize = 0;
+		slidesSizesGrid.forEach(slideSizeValue => {
+			allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
+		});
+		allSlidesSize -= params.spaceBetween;
+
+		if (allSlidesSize < swiperSize) {
+			const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
+			snapGrid.forEach((snap, snapIndex) => {
+				snapGrid[snapIndex] = snap - allSlidesOffset;
+			});
+			slidesGrid.forEach((snap, snapIndex) => {
+				slidesGrid[snapIndex] = snap + allSlidesOffset;
+			});
+		}
+	}
+	Object.assign(swiper, {
+		slides,
+		snapGrid,
+		slidesGrid,
+		slidesSizesGrid
+	});
+
+	if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
+		setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
+		setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after',
+			`${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
+		const addToSnapGrid = -swiper.snapGrid[0];
+		const addToSlidesGrid = -swiper.slidesGrid[0];
+		swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
+		swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
+	}
+
+	if (slidesLength !== previousSlidesLength) {
+		swiper.emit('slidesLengthChange');
+	}
+
+	if (snapGrid.length !== previousSnapGridLength) {
+		if (swiper.params.watchOverflow) swiper.checkOverflow();
+		swiper.emit('snapGridLengthChange');
+	}
+
+	if (slidesGrid.length !== previousSlidesGridLength) {
+		swiper.emit('slidesGridLengthChange');
+	}
+
+	if (params.watchSlidesProgress) {
+		swiper.updateSlidesOffset();
+	}
+
+	return slides;
+}

+ 119 - 0
uni_modules/zebra-swiper/libs/update/updateSlidesClasses.js

@@ -0,0 +1,119 @@
+export default function updateSlidesClasses() {
+	const swiper = this;
+	const {
+		slides,
+		params,
+		$wrapperEl,
+		activeIndex,
+		realIndex
+	} = swiper;
+	if (!slides.length || !$wrapperEl) return;
+	const isVirtual = swiper.virtual && params.virtual.enabled;
+	for (var i = 0; i < slides.length; i++) {
+		slides[i].removeClass(
+			`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`
+		);
+	}
+
+	let activeSlide;
+
+	if (isVirtual) {
+		// activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`);
+		activeSlide = slides[slides.findIndex((item) => {
+			return item.dataSwiperSlideIndex == activeIndex
+		})];
+	} else {
+		activeSlide = slides[activeIndex];
+	} // Active classes
+
+	if (!activeSlide) return
+	activeSlide.addClass(params.slideActiveClass);
+
+	if (params.loop) {
+		if (activeSlide.hasClass(params.slideDuplicateClass)) {
+			// $wrapperEl.children[realIndex].addClass(params.slideDuplicateActiveClass);
+			let index = slides.findIndex((item) => {
+				return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == realIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicateActiveClass);
+		} else {
+			// $wrapperEl.children[realIndex].addClass(params.slideDuplicateActiveClass);
+			let index = slides.findIndex((item) => {
+				return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == realIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicateActiveClass);
+		}
+	} // Next Slide
+
+
+	let nextSlide = activeSlide.nextAll(`.${params.slideClass}`)[0];
+	if (nextSlide) {
+		nextSlide.addClass(params.slideNextClass);
+	} else {
+		if (params.loop && !nextSlide) {
+			nextSlide = slides[0];
+			nextSlide.addClass(params.slideNextClass);
+		} // Prev Slide
+	}
+
+
+
+	let prevSlide = activeSlide.prevAll(`.${params.slideClass}`)[0];
+	if (prevSlide) {
+		prevSlide.addClass(params.slidePrevClass);
+	} else {
+		if (params.loop && !prevSlide) {
+			prevSlide = slides[slides.length - 1];
+			prevSlide.addClass(params.slidePrevClass);
+		}
+	}
+
+
+	if (params.loop) {
+		// Duplicate to all looped slides
+		if (nextSlide.hasClass(params.slideDuplicateClass)) {
+			// $wrapperEl.children(
+			// 	nextSlide.dataSwiperSlideIndex
+			// ).addClass(params.slideDuplicateNextClass);
+
+			let index = slides.findIndex((item) => {
+				return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == nextSlide
+					.dataSwiperSlideIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicateNextClass);
+
+
+		} else {
+			// $wrapperEl.children(
+			// 	nextSlide.dataSwiperSlideIndex
+			// ).addClass(params.slideDuplicateNextClass);
+
+			let index = slides.findIndex((item) => {
+				return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == nextSlide
+					.dataSwiperSlideIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicateNextClass);
+		}
+		if (prevSlide.hasClass(params.slideDuplicateClass)) {
+			// $wrapperEl.children(
+			// 	prevSlide.dataSwiperSlideIndex
+			// ).addClass(params.slideDuplicatePrevClass);
+			let index = slides.findIndex((item) => {
+				return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == prevSlide
+					.dataSwiperSlideIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicatePrevClass);
+		} else {
+			// $wrapperEl.children(
+			// 	prevSlide.dataSwiperSlideIndex
+			// ).addClass(params.slideDuplicatePrevClass);
+			let index = slides.findIndex((item) => {
+				return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == prevSlide
+					.dataSwiperSlideIndex
+			})
+			slides[index] && slides[index].addClass(params.slideDuplicatePrevClass);
+		}
+	}
+
+	swiper.emitSlidesClasses();
+}

+ 11 - 0
uni_modules/zebra-swiper/libs/update/updateSlidesOffset.js

@@ -0,0 +1,11 @@
+export default async function updateSlidesOffset() {
+	const swiper = this;
+	const slides = swiper.slides;
+
+	for (let i = 0; i < slides.length; i += 1) {
+		let offset = (slides[i].swiperSlideSize + swiper.params.spaceBetween) * slides[i].index;
+		slides[i].swiperSlideOffset = swiper.isHorizontal() ? offset :
+			offset;
+	}
+
+}

+ 45 - 0
uni_modules/zebra-swiper/libs/update/updateSlidesProgress.js

@@ -0,0 +1,45 @@
+export default function updateSlidesProgress(translate = this && this.translate || 0) {
+	const swiper = this;
+	const params = swiper.params;
+	const {
+		slides,
+		rtlTranslate: rtl,
+		snapGrid
+	} = swiper;
+	if (slides.length === 0) return;
+	if (typeof slides[0].swiperSlideOffset === 'undefined' || typeof slides[slides.length - 1].swiperSlideOffset ===
+		'undefined') swiper
+		.updateSlidesOffset();
+	let offsetCenter = -translate;
+	if (rtl) offsetCenter = translate; // Visible Slides
+
+	swiper.visibleSlidesIndexes = [];
+	swiper.visibleSlides = [];
+	
+	// slides.forEach((item)=>)
+
+	for (let i = 0; i < slides.length; i += 1) {
+		const slide = slides[i];
+		let slideOffset = slide.swiperSlideOffset;
+		if (params.cssMode && params.centeredSlides) {
+			slideOffset -= slides[0].swiperSlideOffset;
+		}
+
+		const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (
+			slide.swiperSlideSize + params.spaceBetween);
+		const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() :
+			0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween);
+		const slideBefore = -(offsetCenter - slideOffset);
+		const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
+		const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper
+			.size || slideBefore <= 0 && slideAfter >= swiper.size;
+		if (isVisible) {
+			swiper.visibleSlides.push(slide);
+			swiper.visibleSlidesIndexes.push(i);
+			slides[i].addClass(params.slideVisibleClass);
+		}
+
+		slide.progress = rtl ? -slideProgress : slideProgress;
+		slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
+	}
+}

+ 35 - 0
uni_modules/zebra-swiper/libs/utils/utils.js

@@ -0,0 +1,35 @@
+export function getAllRect(context, selector) {
+	return new Promise((resolve) => {
+		uni.createSelectorQuery()
+			.in(context)
+			.selectAll(selector)
+			.boundingClientRect()
+			.exec((rect = []) => resolve(rect[0]));
+	});
+}
+
+export function getRect(context, selector) {
+	return new Promise((resolve) => {
+		uni.createSelectorQuery()
+			.in(context)
+			.select(selector)
+			.boundingClientRect()
+			.exec((rect = []) => resolve(rect[0]));
+	});
+}
+
+export function requestAnimationFrame(cb) {
+	const systemInfo = uni.getSystemInfoSync();
+	if (systemInfo.platform === 'devtools') {
+		return setTimeout(() => {
+			cb();
+		}, 1000 / 30);
+	}
+	return uni
+		.createSelectorQuery()
+		.selectViewport()
+		.boundingClientRect()
+		.exec(() => {
+			cb();
+		});
+}

+ 50 - 0
uni_modules/zebra-swiper/libs/vue2/get-changed-params.js

@@ -0,0 +1,50 @@
+import {
+	paramsList
+} from './params-list.js';
+import {
+	isObject
+} from './utils.js';
+
+function getChangedParams(swiperParams, oldParams, children, oldChildren) {
+	const keys = [];
+	if (!oldParams) return keys;
+	const addKey = (key) => {
+		if (keys.indexOf(key) < 0) keys.push(key);
+	};
+	const oldChildrenKeys = oldChildren.map((child) => child.props && child.props.key);
+	const childrenKeys = children.map((child) => child.props && child.props.key);
+	if (oldChildrenKeys.join('') !== childrenKeys.join('')) keys.push('children');
+	if (oldChildren.length !== children.length) keys.push('children');
+	const watchParams = paramsList.filter((key) => key[0] === '_').map((key) => key.replace(/_/, ''));
+	watchParams.forEach((key) => {
+		if (key in swiperParams && key in oldParams) {
+			if (isObject(swiperParams[key]) && isObject(oldParams[key])) {
+				const newKeys = Object.keys(swiperParams[key]);
+				const oldKeys = Object.keys(oldParams[key]);
+				if (newKeys.length !== oldKeys.length) {
+					addKey(key);
+				} else {
+					newKeys.forEach((newKey) => {
+						if (swiperParams[key][newKey] !== oldParams[key][newKey]) {
+							addKey(key);
+						}
+					});
+					oldKeys.forEach((oldKey) => {
+						if (swiperParams[key][oldKey] !== oldParams[key][oldKey]) addKey(key);
+					});
+				}
+			} else if (swiperParams[key] !== oldParams[key]) {
+				addKey(key);
+			}
+		} else if (key in swiperParams && !(key in oldParams)) {
+			addKey(key);
+		} else if (!(key in swiperParams) && key in oldParams) {
+			addKey(key);
+		}
+	});
+	return keys;
+}
+
+export {
+	getChangedParams
+};

+ 57 - 0
uni_modules/zebra-swiper/libs/vue2/get-params.js

@@ -0,0 +1,57 @@
+import Swiper from '../../index.js';
+import {
+	isObject,
+	extend
+} from './utils.js';
+import {
+	paramsList
+} from './params-list.js';
+
+function getParams(obj = {}) {
+	const params = {
+		on: {},
+	};
+	const passedParams = {};
+	extend(params, Swiper.defaults);
+	extend(params, Swiper.extendedDefaults);
+	params._emitClasses = true;
+	params.init = false;
+
+	const rest = {};
+	const allowedParams = paramsList.map((key) => key.replace(/_/, ''));
+	// Prevent empty Object.keys(obj) array on ios.
+	const plainObj = Object.assign({}, obj);
+	Object.keys(plainObj).forEach((key) => {
+		if (typeof obj[key] === 'undefined') return;
+		if (allowedParams.indexOf(key) >= 0) {
+			if (isObject(obj[key])) {
+				params[key] = {};
+				passedParams[key] = {};
+				extend(params[key], obj[key]);
+				extend(passedParams[key], obj[key]);
+			} else {
+				params[key] = obj[key];
+				passedParams[key] = obj[key];
+			}
+		} else if (key.search(/on[A-Z]/) === 0 && typeof obj[key] === 'function') {
+			params.on[`${key[2].toLowerCase()}${key.substr(3)}`] = obj[key];
+		} else {
+			rest[key] = obj[key];
+		}
+	});
+
+	['navigation', 'pagination', 'scrollbar'].forEach((key) => {
+		if (params[key] === true) params[key] = {};
+		if (params[key] === false) delete params[key];
+	});
+
+	return {
+		params,
+		passedParams,
+		rest
+	};
+}
+
+export {
+	getParams
+};

+ 40 - 0
uni_modules/zebra-swiper/libs/vue2/init-swiper.js

@@ -0,0 +1,40 @@
+import Swiper from '../../index.js';
+import {
+	needsNavigation,
+	needsPagination,
+	needsScrollbar
+} from './utils.js';
+
+function initSwiper(swiperParams, native) {
+	return new Swiper(swiperParams, native);
+}
+
+function mountSwiper({
+	el,
+	nextEl,
+	prevEl,
+	paginationEl,
+	scrollbarEl,
+	swiper
+}, swiperParams) {
+	if (needsNavigation(swiperParams) && nextEl && prevEl) {
+		swiper.params.navigation.nextEl = nextEl;
+		swiper.originalParams.navigation.nextEl = nextEl;
+		swiper.params.navigation.prevEl = prevEl;
+		swiper.originalParams.navigation.prevEl = prevEl;
+	}
+	if (needsPagination(swiperParams) && paginationEl) {
+		swiper.params.pagination.el = paginationEl;
+		swiper.originalParams.pagination.el = paginationEl;
+	}
+	if (needsScrollbar(swiperParams) && scrollbarEl) {
+		swiper.params.scrollbar.el = scrollbarEl;
+		swiper.originalParams.scrollbar.el = scrollbarEl;
+	}
+	swiper.init(el);
+}
+
+export {
+	initSwiper,
+	mountSwiper
+};

+ 73 - 0
uni_modules/zebra-swiper/libs/vue2/loop.js

@@ -0,0 +1,73 @@
+import Swiper from '../../index.js';
+
+function calcLoopedSlides(slides, swiperParams) {
+	let slidesPerViewParams = swiperParams.slidesPerView;
+	if (swiperParams.breakpoints) {
+		const breakpoint = Swiper.prototype.getBreakpoint(swiperParams.breakpoints);
+		const breakpointOnlyParams =
+			breakpoint in swiperParams.breakpoints ? swiperParams.breakpoints[breakpoint] : undefined;
+		if (breakpointOnlyParams && breakpointOnlyParams.slidesPerView) {
+			slidesPerViewParams = breakpointOnlyParams.slidesPerView;
+		}
+	}
+	let loopedSlides = Math.ceil(parseFloat(swiperParams.loopedSlides || slidesPerViewParams, 10));
+
+	loopedSlides += swiperParams.loopAdditionalSlides;
+
+	if (loopedSlides > slides.length) {
+		loopedSlides = slides.length;
+	}
+	return loopedSlides;
+}
+
+function renderLoop(native, swiperParams, data) {
+	const modifiedValue = data;
+	if (swiperParams.loopFillGroupWithBlank) {
+		const blankSlidesNum =
+			swiperParams.slidesPerGroup - (modifiedValue.length % swiperParams.slidesPerGroup);
+		if (blankSlidesNum !== swiperParams.slidesPerGroup) {
+			for (let i = 0; i < blankSlidesNum; i += 1) {
+				const blankSlide = h('div', {
+					class: `${swiperParams.slideClass} ${swiperParams.slideBlankClass}`,
+				});
+				modifiedValue.push(blankSlide);
+			}
+		}
+	}
+
+	if (swiperParams.slidesPerView === 'auto' && !swiperParams.loopedSlides) {
+		swiperParams.loopedSlides = modifiedValue.length;
+	}
+
+	const loopedSlides = calcLoopedSlides(modifiedValue, swiperParams);
+
+	const prependSlides = [];
+	const appendSlides = [];
+	const prependValue = [];
+	const appendValue = [];
+	modifiedValue.forEach((child, index) => {
+		if (index < loopedSlides) {
+			if (!native.loopUpdateData) {
+				appendValue.push(child);
+			}
+		}
+		if (index < modifiedValue.length && index >= modifiedValue.length - loopedSlides) {
+			if (!native.loopUpdateData) {
+				prependValue.push(child);
+			}
+		}
+	})
+	if (native) {
+		if (!native.originalDataList) native.originalDataList = [];
+		native.originalDataList = [...prependValue, ...modifiedValue, ...appendValue];
+	}
+
+	return {
+		data: [...prependValue, ...modifiedValue, ...appendValue]
+	};
+}
+
+export {
+	calcLoopedSlides,
+	renderLoop
+};

+ 123 - 0
uni_modules/zebra-swiper/libs/vue2/params-list.js

@@ -0,0 +1,123 @@
+/* underscore in name -> watch for changes */
+const paramsList = [
+	'modules',
+	'init',
+	'_direction',
+	'touchEventsTarget',
+	'initialSlide',
+	'_speed',
+	'cssMode',
+	'updateOnWindowResize',
+	'resizeObserver',
+	'nested',
+	'focusableElements',
+	'_enabled',
+	'_width',
+	'_height',
+	'preventInteractionOnTransition',
+	'userAgent',
+	'url',
+	'_edgeSwipeDetection',
+	'_edgeSwipeThreshold',
+	'_freeMode',
+	'_autoHeight',
+	'setWrapperSize',
+	'virtualTranslate',
+	'_effect',
+	'breakpoints',
+	'_spaceBetween',
+	'_slidesPerView',
+	'maxBackfaceHiddenSlides',
+	'_grid',
+	'_slidesPerGroup',
+	'_slidesPerGroupSkip',
+	'_slidesPerGroupAuto',
+	'_centeredSlides',
+	'_centeredSlidesBounds',
+	'_slidesOffsetBefore',
+	'_slidesOffsetAfter',
+	'normalizeSlideIndex',
+	'_centerInsufficientSlides',
+	'_watchOverflow',
+	'roundLengths',
+	'touchRatio',
+	'touchAngle',
+	'simulateTouch',
+	'_shortSwipes',
+	'_longSwipes',
+	'longSwipesRatio',
+	'longSwipesMs',
+	'_followFinger',
+	'allowTouchMove',
+	'_threshold',
+	'touchMoveStopPropagation',
+	'touchStartPreventDefault',
+	'touchStartForcePreventDefault',
+	'touchReleaseOnEdges',
+	'uniqueNavElements',
+	'_resistance',
+	'_resistanceRatio',
+	'_watchSlidesProgress',
+	'_grabCursor',
+	'preventClicks',
+	'preventClicksPropagation',
+	'_slideToClickedSlide',
+	'_preloadImages',
+	'updateOnImagesReady',
+	'_loop',
+	'_loopAdditionalSlides',
+	'_loopedSlides',
+	'_loopFillGroupWithBlank',
+	'loopPreventsSlide',
+	'_rewind',
+	'_allowSlidePrev',
+	'_allowSlideNext',
+	'_swipeHandler',
+	'_noSwiping',
+	'noSwipingClass',
+	'noSwipingSelector',
+	'passiveListeners',
+	'containerModifierClass',
+	'slideClass',
+	'slideBlankClass',
+	'slideActiveClass',
+	'slideDuplicateActiveClass',
+	'slideVisibleClass',
+	'slideDuplicateClass',
+	'slideNextClass',
+	'slideDuplicateNextClass',
+	'slidePrevClass',
+	'slideDuplicatePrevClass',
+	'wrapperClass',
+	'runCallbacksOnInit',
+	'observer',
+	'observeParents',
+	'observeSlideChildren',
+
+	// modules
+	'a11y',
+	'_autoplay',
+	'_controller',
+	'coverflowEffect',
+	'cubeEffect',
+	'fadeEffect',
+	'flipEffect',
+	'creativeEffect',
+	'cardsEffect',
+	'panorama',
+	'hashNavigation',
+	'history',
+	'keyboard',
+	'lazy',
+	'mousewheel',
+	'_navigation',
+	'_pagination',
+	'parallax',
+	'_scrollbar',
+	'_thumbs',
+	'_virtual',
+	'zoom',
+];
+export {
+	paramsList
+};

+ 167 - 0
uni_modules/zebra-swiper/libs/vue2/update-swiper.js

@@ -0,0 +1,167 @@
+import {
+	isObject,
+	extend
+} from './utils.js';
+
+async function updateSwiper({
+	swiper,
+	slides,
+	passedParams,
+	changedParams,
+	nextEl,
+	prevEl,
+	paginationEl,
+	scrollbarEl,
+}) {
+	const updateParams = changedParams.filter((key) => key !== 'children' && key !== 'direction');
+	const {
+		params: currentParams,
+		pagination,
+		navigation,
+		scrollbar,
+		virtual,
+		thumbs
+	} = swiper;
+	let needThumbsInit;
+	let needControllerInit;
+	let needPaginationInit;
+	let needScrollbarInit;
+	let needNavigationInit;
+	if (
+		changedParams.includes('thumbs') &&
+		passedParams.thumbs &&
+		passedParams.thumbs.swiper &&
+		currentParams.thumbs &&
+		!currentParams.thumbs.swiper
+	) {
+		needThumbsInit = true;
+	}
+	if (
+		changedParams.includes('controller') &&
+		passedParams.controller &&
+		passedParams.controller.control &&
+		currentParams.controller &&
+		!currentParams.controller.control
+	) {
+		needControllerInit = true;
+	}
+	if (
+		changedParams.includes('pagination') &&
+		passedParams.pagination &&
+		(passedParams.pagination.el || paginationEl) &&
+		(currentParams.pagination || currentParams.pagination === false) &&
+		pagination &&
+		!pagination.el
+	) {
+		needPaginationInit = true;
+	}
+
+	if (
+		changedParams.includes('scrollbar') &&
+		passedParams.scrollbar &&
+		(passedParams.scrollbar.el || scrollbarEl) &&
+		(currentParams.scrollbar || currentParams.scrollbar === false) &&
+		scrollbar &&
+		!scrollbar.el
+	) {
+		needScrollbarInit = true;
+	}
+
+	if (
+		changedParams.includes('navigation') &&
+		passedParams.navigation &&
+		(passedParams.navigation.prevEl || prevEl) &&
+		(passedParams.navigation.nextEl || nextEl) &&
+		(currentParams.navigation || currentParams.navigation === false) &&
+		navigation &&
+		!navigation.prevEl &&
+		!navigation.nextEl
+	) {
+		needNavigationInit = true;
+	}
+
+	const destroyModule = (mod) => {
+		if (!swiper[mod]) return;
+		swiper[mod].destroy();
+		if (mod === 'navigation') {
+			currentParams[mod].prevEl = undefined;
+			currentParams[mod].nextEl = undefined;
+			swiper[mod].prevEl = undefined;
+			swiper[mod].nextEl = undefined;
+		} else {
+			currentParams[mod].el = undefined;
+			swiper[mod].el = undefined;
+		}
+	};
+
+	updateParams.forEach((key) => {
+		if (isObject(currentParams[key]) && isObject(passedParams[key])) {
+			extend(currentParams[key], passedParams[key]);
+		} else {
+			const newValue = passedParams[key];
+			if (
+				(newValue === true || newValue === false) &&
+				(key === 'navigation' || key === 'pagination' || key === 'scrollbar')
+			) {
+				if (newValue === false) {
+					destroyModule(key);
+				}
+			} else {
+				currentParams[key] = passedParams[key];
+			}
+		}
+	});
+	// if (changedParams.includes('virtual') && virtual && currentParams.virtual.enabled) {
+	// 	virtual.update();
+	// }
+	if (changedParams.includes('children') && virtual && currentParams.virtual.enabled) {
+		// virtual.slides = slides;
+		virtual.update(true);
+	} else if (changedParams.includes('children') && swiper.lazy && swiper.params.lazy.enabled) {
+		swiper.lazy.load();
+	}
+
+	if (needThumbsInit) {
+		const initialized = thumbs.init();
+		if (initialized) thumbs.update(true);
+	}
+
+	if (needControllerInit) {
+		swiper.controller.control = currentParams.controller.control;
+	}
+
+	if (needPaginationInit) {
+		if (paginationEl) currentParams.pagination.el = paginationEl;
+		pagination.init();
+		pagination.render();
+		pagination.update();
+	}
+
+	if (needScrollbarInit) {
+		if (scrollbarEl) currentParams.scrollbar.el = scrollbarEl;
+		scrollbar.init();
+		scrollbar.updateSize();
+		scrollbar.setTranslate();
+	}
+
+	if (needNavigationInit) {
+		if (nextEl) currentParams.navigation.nextEl = nextEl;
+		if (prevEl) currentParams.navigation.prevEl = prevEl;
+		navigation.init();
+		navigation.update();
+	}
+
+	if (changedParams.includes('allowSlideNext')) {
+		swiper.allowSlideNext = passedParams.allowSlideNext;
+	}
+	if (changedParams.includes('allowSlidePrev')) {
+		swiper.allowSlidePrev = passedParams.allowSlidePrev;
+	}
+	if (changedParams.includes('direction')) {
+		swiper.changeDirection(passedParams.direction, false);
+	}
+	swiper.update();
+}
+export {
+	updateSwiper
+};

+ 60 - 0
uni_modules/zebra-swiper/libs/vue2/utils.js

@@ -0,0 +1,60 @@
+function isObject(o) {
+	return (
+		typeof o === 'object' &&
+		o !== null &&
+		o.constructor &&
+		Object.prototype.toString.call(o).slice(8, -1) === 'Object'
+	);
+}
+
+function extend(target, src) {
+	const noExtend = ['__proto__', 'constructor', 'prototype'];
+	Object.keys(src)
+		.filter((key) => noExtend.indexOf(key) < 0)
+		.forEach((key) => {
+			if (typeof target[key] === 'undefined') target[key] = src[key];
+			else if (isObject(src[key]) && isObject(target[key]) && Object.keys(src[key]).length > 0) {
+				if (src[key].__swiper__) target[key] = src[key];
+				else extend(target[key], src[key]);
+			} else {
+				target[key] = src[key];
+			}
+		});
+}
+
+function needsNavigation(props = {}) {
+	return (
+		props.navigation &&
+		typeof props.navigation.nextEl === 'undefined' &&
+		typeof props.navigation.prevEl === 'undefined'
+	);
+}
+
+function needsPagination(props = {}) {
+	return props.pagination && typeof props.pagination.el === 'undefined';
+}
+
+function needsScrollbar(props = {}) {
+	return props.scrollbar;
+}
+
+function uniqueClasses(classNames = '') {
+	const classes = classNames
+		.split(' ')
+		.map((c) => c.trim())
+		.filter((c) => !!c);
+	const unique = [];
+	classes.forEach((c) => {
+		if (unique.indexOf(c) < 0) unique.push(c);
+	});
+	return unique.join(' ');
+}
+
+export {
+	isObject,
+	extend,
+	needsNavigation,
+	needsPagination,
+	needsScrollbar,
+	uniqueClasses
+};

+ 44 - 0
uni_modules/zebra-swiper/libs/vue2/virtual.js

@@ -0,0 +1,44 @@
+// import { h } from 'vue';
+
+function updateOnVirtualData(swiper) {
+	if (
+		!swiper ||
+		swiper.destroyed ||
+		!swiper.params.virtual ||
+		(swiper.params.virtual && !swiper.params.virtual.enabled)
+	) return;
+	swiper.updateSlides();
+	swiper.updateProgress();
+	swiper.updateSlidesClasses();
+	if (swiper.lazy && swiper.params.lazy.enabled) {
+		swiper.lazy.load();
+	}
+	if (swiper.parallax && swiper.params.parallax && swiper.params.parallax.enabled) {
+		swiper.parallax.setTranslate();
+	}
+}
+
+function renderVirtual(swiperRef, slides, virtualData) {
+	if (!virtualData) return null;
+	const style = swiperRef.isHorizontal() ? {
+		[swiperRef.rtlTranslate ? 'right' : 'left']: `${virtualData.offset}px`,
+	} : {
+		top: `${virtualData.offset}px`,
+	};
+	return slides
+		.filter((slide, index) => index >= virtualData.from && index <= virtualData.to)
+		.map((slide) => {
+			if (!slide.props) slide.props = {};
+			if (!slide.props.style) slide.props.style = {};
+			slide.props.swiperRef = swiperRef;
+			slide.props.style = style;
+			return h(slide.type, {
+				...slide.props
+			}, slide.children);
+		});
+}
+
+export {
+	renderVirtual,
+	updateOnVirtualData
+};

+ 210 - 0
uni_modules/zebra-swiper/modules/autoplay/autoplay.js

@@ -0,0 +1,210 @@
+import {
+	nextTick
+} from '../../shared/utils.js';
+export default function Autoplay({
+	swiper,
+	extendParams,
+	on,
+	emit
+}) {
+	let timeout;
+	swiper.autoplay = {
+		running: false,
+		paused: false
+	};
+	extendParams({
+		autoplay: {
+			enabled: false,
+			delay: 3000,
+			waitForTransition: true,
+			disableOnInteraction: true,
+			stopOnLastSlide: false,
+			reverseDirection: false,
+			pauseOnMouseEnter: false
+		}
+	});
+
+	function run() {
+		const $activeSlideEl = swiper.slides[swiper.activeIndex];
+		let delay = swiper.params.autoplay.delay;
+		clearTimeout(timeout);
+		timeout = nextTick(() => {
+			let autoplayResult;
+			if (swiper.params.autoplay.reverseDirection) {
+				if (swiper.params.loop) {
+					swiper.loopFix();
+					autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
+					emit('autoplay');
+				} else if (!swiper.isBeginning) {
+					autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
+					emit('autoplay');
+				} else if (!swiper.params.autoplay.stopOnLastSlide) {
+					autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
+					emit('autoplay');
+				} else {
+					stop();
+				}
+			} else if (swiper.params.loop) {
+				swiper.loopFix();
+				setTimeout(() => {
+					autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
+				}, 30)
+
+				emit('autoplay');
+			} else if (!swiper.isEnd) {
+				autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
+				emit('autoplay');
+			} else if (!swiper.params.autoplay.stopOnLastSlide) {
+				autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
+				emit('autoplay');
+			} else {
+				stop();
+			}
+
+			if (swiper.params.cssMode && swiper.autoplay.running) run();
+			else if (autoplayResult === false) {
+				run();
+			}
+		}, delay);
+	}
+
+	function start() {
+		if (typeof timeout !== 'undefined') return false;
+		if (swiper.autoplay.running) return false;
+		swiper.autoplay.running = true;
+		emit('autoplayStart');
+		run();
+		return true;
+	}
+
+	function stop() {
+		if (!swiper.autoplay.running) return false;
+		if (typeof timeout === 'undefined') return false;
+
+		if (timeout) {
+			clearTimeout(timeout);
+			timeout = undefined;
+		}
+
+		swiper.autoplay.running = false;
+		emit('autoplayStop');
+		return true;
+	}
+
+	function pause(speed) {
+		if (!swiper.autoplay.running) return;
+		if (swiper.autoplay.paused) return;
+		if (timeout) clearTimeout(timeout);
+		swiper.autoplay.paused = true;
+
+		if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
+			swiper.autoplay.paused = false;
+			run();
+		} else {
+			['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
+				swiper.on(event, onTransitionEnd);
+			});
+		}
+	}
+
+	function onVisibilityChange() {
+		// const document = getDocument();
+
+		// if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
+		// 	pause();
+		// }
+
+		// if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
+		// 	run();
+		// 	swiper.autoplay.paused = false;
+		// }
+	}
+
+	function onTransitionEnd(e) {
+		if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
+		// if (e.target !== swiper.$wrapperEl[0]) return;
+		['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
+			swiper.off(event, onTransitionEnd);
+		});
+		swiper.autoplay.paused = false;
+
+		if (!swiper.autoplay.running) {
+			stop();
+		} else {
+			run();
+		}
+	}
+
+	function onMouseEnter() {
+		if (swiper.params.autoplay.disableOnInteraction) {
+			stop();
+		} else {
+			pause();
+		}
+
+		// ['transitionend', 'webkitTransitionEnd'].forEach(event => {
+		// 	swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);
+		// });
+	}
+
+	function onMouseLeave() {
+		if (swiper.params.autoplay.disableOnInteraction) {
+			return;
+		}
+
+		swiper.autoplay.paused = false;
+		run();
+	}
+
+	function attachMouseEvents() {
+		if (swiper.params.autoplay.pauseOnMouseEnter) {}
+	}
+
+	function detachMouseEvents() {}
+
+	on('init update', () => {
+		if (swiper.params.autoplay.enabled) {
+			start();
+			attachMouseEvents();
+		}
+	});
+	on('beforeTransitionStart', (_s, speed, internal) => {
+		if (swiper.autoplay.running) {
+			if (internal || !swiper.params.autoplay.disableOnInteraction) {
+				swiper.autoplay.pause(speed);
+			} else {
+				if (!swiper.params.loop) {
+					stop();
+				}
+
+			}
+		}
+	});
+	on('sliderFirstMove', () => {
+		if (swiper.autoplay.running) {
+			if (swiper.params.autoplay.disableOnInteraction) {
+				stop();
+			} else {
+				pause();
+			}
+		}
+	});
+	on('touch-end', () => {
+		if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
+			run();
+		}
+	});
+	on('destroy', () => {
+		detachMouseEvents();
+
+		if (swiper.autoplay.running) {
+			stop();
+		}
+	});
+	Object.assign(swiper.autoplay, {
+		pause,
+		run,
+		start,
+		stop
+	});
+}

+ 130 - 0
uni_modules/zebra-swiper/modules/effect-cards/effect-cards.js

@@ -0,0 +1,130 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
+
+export default function EffectCards({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		cardsEffect: {
+			slideShadows: true,
+			transformEl: null,
+			rotate: true,
+			perSlideRotate: 2,
+			perSlideOffset: 8,
+		},
+	});
+
+	const setTranslate = () => {
+		const {
+			slides,
+			activeIndex
+		} = swiper;
+		const params = swiper.params.cardsEffect;
+		const {
+			startTranslate,
+			isTouched
+		} = swiper.touchEventsData;
+		const currentTranslate = swiper.translate;
+		for (let i = 0; i < slides.length; i += 1) {
+			const $slideEl = slides[i];
+			const slideProgress = $slideEl.progress;
+			const progress = Math.min(Math.max(slideProgress, -4), 4);
+			let offset = $slideEl.swiperSlideOffset;
+			if (swiper.params.centeredSlides && !swiper.params.cssMode) {
+				swiper.$wrapperEl.transform(`translateX(${swiper.minTranslate()}px)`);
+			}
+			if (swiper.params.centeredSlides && swiper.params.cssMode) {
+				offset -= slides.swiperSlideOffset;
+			}
+			let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
+			let tY = 0;
+			const tZ = -100 * Math.abs(progress);
+			let scale = 1;
+			let rotate = -params.perSlideRotate * progress;
+
+			let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
+
+			const isSwipeToNext =
+				(i === activeIndex || i === activeIndex - 1) &&
+				progress > 0 &&
+				progress < 1 &&
+				(isTouched || swiper.params.cssMode) &&
+				currentTranslate < startTranslate;
+			const isSwipeToPrev =
+				(i === activeIndex || i === activeIndex + 1) &&
+				progress < 0 &&
+				progress > -1 &&
+				(isTouched || swiper.params.cssMode) &&
+				currentTranslate > startTranslate;
+			if (isSwipeToNext || isSwipeToPrev) {
+				const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
+				rotate += -28 * progress * subProgress;
+				scale += -0.5 * subProgress;
+				tXAdd += 96 * subProgress;
+				tY = `${-25 * subProgress * Math.abs(progress)}%`;
+			}
+
+			if (progress < 0) {
+				// next
+				tX = `calc(${tX}px + (${tXAdd * Math.abs(progress)}%))`;
+			} else if (progress > 0) {
+				// prev
+				tX = `calc(${tX}px + (-${tXAdd * Math.abs(progress)}%))`;
+			} else {
+				tX = `${tX}px`;
+			}
+			if (!swiper.isHorizontal()) {
+				const prevY = tY;
+				tY = tX;
+				tX = prevY;
+			}
+
+			const scaleString =
+				progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
+			const transform =
+				`translate3d(${tX}, ${tY}, ${tZ}px) rotateZ(${params.rotate ? rotate : 0}deg) scale(${scaleString})`;
+
+			$slideEl.css({
+				zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
+			})
+			const $targetEl = effectTarget(params, $slideEl);
+			$targetEl.transform(transform);
+			if (swiper.params.willChange) {
+				$targetEl.willChange("transform");
+			}
+			slides[i].addClass('swiper-slide-cards')
+		}
+	};
+
+	const setTransition = (duration) => {
+		const {
+			transformEl
+		} = swiper.params.cardsEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (let i = 0; i < $transitionElements.length; i += 1) {
+			$transitionElements[i].transition(duration);
+		}
+
+		effectVirtualTransitionEnd({
+			swiper,
+			duration,
+			transformEl
+		});
+	};
+
+	effectInit({
+		effect: 'cards',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => true,
+		overwriteParams: () => ({
+			watchSlidesProgress: true,
+			virtualTranslate: !swiper.params.cssMode,
+		}),
+	});
+}

+ 8 - 0
uni_modules/zebra-swiper/modules/effect-cards/effect-cards.scss

@@ -0,0 +1,8 @@
+.swiper-cards {
+  overflow: visible;
+
+}
+.swiper-slide-cards {
+transform-origin: center bottom;
+backface-visibility: hidden;
+}

+ 66 - 0
uni_modules/zebra-swiper/modules/effect-carousel/effect-carousel.js

@@ -0,0 +1,66 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+export default function EffectCarousel({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		carouselEffect: {}
+	});
+
+	const setTranslate = () => {
+		const scaleStep = 0.2;
+		const zIndexMax = swiper.slides.length;
+		for (let i = 0; i < swiper.slides.length; i += 1) {
+			const slideEl = swiper.slides[i];
+			const slideProgress = swiper.slides[i].progress;
+			const absProgress = Math.abs(slideProgress);
+			let modify = 1;
+			if (absProgress > 1) {
+				modify = (absProgress - 1) * 0.3 + 1;
+			}
+			const translate = `${slideProgress * modify * 50}%`;
+			const scale = 1 - absProgress * scaleStep;
+			const zIndex = zIndexMax - Math.abs(Math.round(slideProgress));
+			const slideTransform = `translateX(${translate}) scale(${scale})`;
+			slideEl.transform(slideTransform);
+			slideEl.css({
+				zIndex: zIndex
+			})
+			if (absProgress > 3) {
+				slideEl.css({
+					opacity: 0
+				})
+			} else {
+				slideEl.css({
+					opacity: 1
+				})
+			}
+		}
+	};
+
+	const setTransition = duration => {
+		const {
+			transformEl
+		} = swiper.params.coverflowEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (var i = 0; i < $transitionElements.length; i++) {
+			$transitionElements[i].transition(duration);
+		}
+	};
+
+	effectInit({
+		effect: 'carousel',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => true,
+		overwriteParams: () => ({
+			watchSlidesProgress: true,
+			slidesPerView: 'auto',
+			centeredSlides: true,
+		})
+	});
+}

+ 6 - 0
uni_modules/zebra-swiper/modules/effect-carousel/effect-carousel.scss

@@ -0,0 +1,6 @@
+.swiper-slide-carousel {
+    backface-visibility: hidden;
+    overflow: hidden;
+    transition-property: transform, opacity, height;
+	 transform-style: preserve-3d;
+}

+ 110 - 0
uni_modules/zebra-swiper/modules/effect-coverflow/effect-coverflow.js

@@ -0,0 +1,110 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+export default function EffectCoverflow({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		coverflowEffect: {
+			rotate: 50,
+			stretch: 0,
+			depth: 100,
+			scale: 1,
+			modifier: 1,
+			slideShadows: true,
+			transformEl: null
+		}
+	});
+
+	const setTranslate = () => {
+		const {
+			width: swiperWidth,
+			height: swiperHeight,
+			slides,
+			slidesSizesGrid
+		} = swiper;
+		const params = swiper.params.coverflowEffect;
+		const isHorizontal = swiper.isHorizontal();
+		const transform = swiper.translate;
+		const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
+		const rotate = isHorizontal ? params.rotate : -params.rotate;
+		const translate = params.depth; // Each slide offset from center
+
+		for (let i = 0, length = slides.length; i < length; i += 1) {
+			const $slideEl = slides[i];
+			const slideSize = slidesSizesGrid[i];
+			const slideOffset = $slideEl.swiperSlideOffset;
+			const offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;
+			let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
+			let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0
+
+			let translateZ = -translate * Math.abs(offsetMultiplier);
+			let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders
+
+			if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
+				stretch = parseFloat(params.stretch) / 100 * slideSize;
+			}
+
+			let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
+			let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
+			let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values
+
+			if (Math.abs(translateX) < 0.001) translateX = 0;
+			if (Math.abs(translateY) < 0.001) translateY = 0;
+			if (Math.abs(translateZ) < 0.001) translateZ = 0;
+			if (Math.abs(rotateY) < 0.001) rotateY = 0;
+			if (Math.abs(rotateX) < 0.001) rotateX = 0;
+			if (Math.abs(scale) < 0.001) scale = 0;
+			const slideTransform =
+				`translate3d(${translateX}px,${translateY}px,${translateZ}px)  rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
+			const $targetEl = effectTarget(params, $slideEl);
+			$targetEl.transform(slideTransform);
+			$slideEl.css({
+				zIndex: -Math.abs(Math.round(offsetMultiplier)) + 1
+			})
+			if (swiper.params.willChange) {
+				$targetEl.willChange("transform");
+			}
+			$slideEl.addClass('swiper-slide-coverflow')
+			// if (params.slideShadows) {
+			//   // Set shadows
+			//   let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
+			//   let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
+
+			//   if ($shadowBeforeEl.length === 0) {
+			//     $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top');
+			//   }
+
+			//   if ($shadowAfterEl.length === 0) {
+			//     $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom');
+			//   }
+
+			//   if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
+			//   if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
+			// }
+		}
+	};
+
+	const setTransition = duration => {
+		const {
+			transformEl
+		} = swiper.params.coverflowEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (var i = 0; i < $transitionElements.length; i++) {
+			$transitionElements[i].transition(duration);
+		}
+	};
+
+	effectInit({
+		effect: 'coverflow',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => true,
+		overwriteParams: () => ({
+			watchSlidesProgress: true
+		})
+	});
+}

+ 3 - 0
uni_modules/zebra-swiper/modules/effect-coverflow/effect-coverflow.scss

@@ -0,0 +1,3 @@
+.swiper-slide-coverflow{
+	transform-style: preserve-3d;
+}

+ 178 - 0
uni_modules/zebra-swiper/modules/effect-creative/effect-creative.js

@@ -0,0 +1,178 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
+
+export default function EffectCreative({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		creativeEffect: {
+			transformEl: null,
+			limitProgress: 1,
+			shadowPerProgress: false,
+			progressMultiplier: 1,
+			perspective: true,
+			prev: {
+				translate: [0, 0, 0],
+				rotate: [0, 0, 0],
+				opacity: 1,
+				scale: 1,
+			},
+			next: {
+				translate: [0, 0, 0],
+				rotate: [0, 0, 0],
+				opacity: 1,
+				scale: 1,
+			},
+		},
+	});
+
+	const getTranslateValue = (value) => {
+		if (typeof value === 'string') return value;
+		return `${value}px`;
+	};
+
+	const setTranslate = () => {
+		const {
+			slides,
+			$wrapperEl,
+			slidesSizesGrid
+		} = swiper;
+		const params = swiper.params.creativeEffect;
+		const {
+			progressMultiplier: multiplier
+		} = params;
+
+		const isCenteredSlides = swiper.params.centeredSlides;
+
+		if (isCenteredSlides) {
+			const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
+			$wrapperEl.transform(`translateX(calc(50% - ${margin}px))`);
+		}
+
+		for (let i = 0; i < slides.length; i += 1) {
+			const $slideEl = slides[i];
+			const slideProgress = $slideEl.progress;
+			const progress = Math.min(
+				Math.max($slideEl.progress, -params.limitProgress),
+				params.limitProgress,
+			);
+			let originalProgress = progress;
+
+			if (!isCenteredSlides) {
+				originalProgress = Math.min(
+					Math.max($slideEl.originalProgress, -params.limitProgress),
+					params.limitProgress,
+				);
+			}
+
+			const offset = $slideEl.swiperSlideOffset;
+			const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
+			const r = [0, 0, 0];
+			let custom = false;
+			if (!swiper.isHorizontal()) {
+				t[1] = t[0];
+				t[0] = 0;
+			}
+			let data = {
+				translate: [0, 0, 0],
+				rotate: [0, 0, 0],
+				scale: 1,
+				opacity: 1,
+			};
+			if (progress < 0) {
+				data = params.next;
+				custom = true;
+			} else if (progress > 0) {
+				data = params.prev;
+				custom = true;
+			}
+			// set translate
+			t.forEach((value, index) => {
+				t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(
+          progress * multiplier,
+        )}))`;
+			});
+			// set rotates
+			r.forEach((value, index) => {
+				r[index] = data.rotate[index] * Math.abs(progress * multiplier);
+			});
+
+			// $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
+			$slideEl.css({
+				zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
+			})
+			const translateString = t.join(', ');
+			const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
+			const scaleString =
+				originalProgress < 0 ?
+				`scale(${1 + (1 - data.scale) * originalProgress * multiplier})` :
+				`scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
+			const opacityString =
+				originalProgress < 0 ?
+				1 + (1 - data.opacity) * originalProgress * multiplier :
+				1 - (1 - data.opacity) * originalProgress * multiplier;
+			const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
+
+			// Set shadows
+			// if ((custom && data.shadow) || !custom) {
+			//   let $shadowEl = $slideEl.children('.swiper-slide-shadow');
+			//   if ($shadowEl.length === 0 && data.shadow) {
+			//     $shadowEl = createShadow(params, $slideEl);
+			//   }
+			//   if ($shadowEl.length) {
+			//     const shadowOpacity = params.shadowPerProgress
+			//       ? progress * (1 / params.limitProgress)
+			//       : progress;
+			//     $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
+			//   }
+			// }
+
+			const $targetEl = effectTarget(params, $slideEl);
+			$targetEl.transform(transform);
+			$targetEl.css({
+				opacity: opacityString
+			});
+			if (data.origin) {
+				$targetEl.css({
+					'transform-origin': data.origin
+				});
+			}
+			if (swiper.params.willChange) {
+				slides[i].willChange("transform,opacity");
+			}
+			slides[i].addClass('swiper-slide-creative')
+		}
+	};
+
+	const setTransition = (duration) => {
+		const {
+			transformEl
+		} = swiper.params.creativeEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (let i = 0; i < $transitionElements.length; i += 1) {
+			$transitionElements[i].transition(duration);
+		}
+		effectVirtualTransitionEnd({
+			swiper,
+			duration,
+			transformEl,
+			allSlides: true
+		});
+	};
+
+	effectInit({
+		effect: 'creative',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => swiper.params.creativeEffect.perspective,
+		overwriteParams: () => ({
+			watchSlidesProgress: true,
+			virtualTranslate: !swiper.params.cssMode,
+		}),
+	});
+}

+ 9 - 0
uni_modules/zebra-swiper/modules/effect-creative/effect-creative.scss

@@ -0,0 +1,9 @@
+.swiper-creative {
+
+}
+  .swiper-slide-creative {
+    backface-visibility: hidden;
+    overflow: hidden;
+    transition-property: transform, opacity, height;
+	 transform-style: preserve-3d;
+  }

+ 191 - 0
uni_modules/zebra-swiper/modules/effect-cube/effect-cube.js

@@ -0,0 +1,191 @@
+import effectInit from '../../shared/effect-init.js';
+
+export default function EffectCube({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		cubeEffect: {
+			slideShadows: true,
+			shadow: true,
+			shadowOffset: 20,
+			shadowScale: 0.94,
+		},
+	});
+
+	const setTranslate = () => {
+		const {
+			$el,
+			$wrapperEl,
+			slides,
+			width: swiperWidth,
+			height: swiperHeight,
+			rtlTranslate: rtl,
+			size: swiperSize,
+			browser,
+		} = swiper;
+		const params = swiper.params.cubeEffect;
+		const isHorizontal = swiper.isHorizontal();
+		const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
+		let wrapperRotate = 0;
+		let $cubeShadowEl;
+		if (params.shadow) {
+			if (isHorizontal) {
+				// $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');
+				if (!swiper.native.cubeShadowShowWrapper) {
+					swiper.$wrapperEl.updateData({
+						cubeShadowShowWrapper: true
+					})
+				}
+				swiper.$wrapperEl.cubeShadowCss({
+					height: `${swiperWidth}px`
+				});
+			} else {
+				if (!swiper.native.cubeShadowShowRoot) {
+					swiper.$wrapperEl.updateData({
+						cubeShadowShowRoot: true
+					})
+				}
+			}
+		}
+		for (let i = 0; i < slides.length; i += 1) {
+			const $slideEl = slides[i];
+			let slideIndex = i;
+			if (isVirtual) {
+				slideIndex = parseInt(swiper.activeIndex, 10);
+			}
+			let slideAngle = slideIndex * 90;
+			let round = Math.floor(slideAngle / 360);
+			if (rtl) {
+				slideAngle = -slideAngle;
+				round = Math.floor(-slideAngle / 360);
+			}
+			const progress = Math.max(Math.min($slideEl.progress, 1), -1);
+
+			let tx = 0;
+			let ty = 0;
+			let tz = 0;
+			if (slideIndex % 4 === 0) {
+				tx = -round * 4 * swiperSize;
+				tz = 0;
+			} else if ((slideIndex - 1) % 4 === 0) {
+				tx = 0;
+				tz = -round * 4 * swiperSize;
+			} else if ((slideIndex - 2) % 4 === 0) {
+				tx = swiperSize + round * 4 * swiperSize;
+				tz = swiperSize;
+			} else if ((slideIndex - 3) % 4 === 0) {
+				tx = -swiperSize;
+				tz = 3 * swiperSize + swiperSize * 4 * round;
+			}
+			if (rtl) {
+				tx = -tx;
+			}
+
+			if (!isHorizontal) {
+				ty = tx;
+				tx = 0;
+			}
+
+			const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${
+        isHorizontal ? slideAngle : 0
+      }deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
+			if (progress <= 1 && progress > -1) {
+				wrapperRotate = slideIndex * 90 + progress * 90;
+				if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
+			}
+			$slideEl.transform(transform);
+			// if (params.slideShadows) {
+			// 	// Set shadows
+			// 	let shadowBefore = isHorizontal ?
+			// 		$slideEl.find('.swiper-slide-shadow-left') :
+			// 		$slideEl.find('.swiper-slide-shadow-top');
+			// 	let shadowAfter = isHorizontal ?
+			// 		$slideEl.find('.swiper-slide-shadow-right') :
+			// 		$slideEl.find('.swiper-slide-shadow-bottom');
+			// 	if (shadowBefore.length === 0) {
+			// 		shadowBefore = $(
+			// 			`<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`,
+			// 		);
+			// 		$slideEl.append(shadowBefore);
+			// 	}
+			// 	if (shadowAfter.length === 0) {
+			// 		shadowAfter = $(
+			// 			`<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`,
+			// 		);
+			// 		$slideEl.append(shadowAfter);
+			// 	}
+			// 	if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
+			// 	if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
+			// }
+			$slideEl.addClass('swiper-slide-cube')
+		}
+		$wrapperEl.css({
+			'-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`,
+			'transform-origin': `50% 50% -${swiperSize / 2}px`,
+		});
+
+		if (params.shadow) {
+			if (isHorizontal) {
+				swiper.$wrapperEl.cubeShadowTransform(
+					`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${
+            -swiperWidth / 2
+          }px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`,
+				);
+			} else {
+				const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
+				const multiplier =
+					1.5 -
+					(Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2 +
+						Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2);
+				const scale1 = params.shadowScale;
+				const scale2 = params.shadowScale / multiplier;
+				const offset = params.shadowOffset;
+				swiper.$wrapperEl.cubeShadowTransform(
+					`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${
+            -swiperHeight / 2 / scale2
+          }px) rotateX(-90deg)`,
+				);
+			}
+		}
+		const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;
+		$wrapperEl.transform(
+			`translate3d(0px,0,${zFactor}px) rotateX(${
+        swiper.isHorizontal() ? 0 : wrapperRotate
+      }deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`,
+		);
+	};
+	const setTransition = (duration) => {
+		const {
+			$el,
+			slides
+		} = swiper;
+
+		for (var i = 0; i < slides.length; i++) {
+			slides[i].transition(duration)
+		}
+
+		if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
+			swiper.$wrapperEl.cubeShadowTransition(duration);
+		}
+	};
+
+	effectInit({
+		effect: 'cube',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => true,
+		overwriteParams: () => ({
+			slidesPerView: 1,
+			slidesPerGroup: 1,
+			watchSlidesProgress: true,
+			resistanceRatio: 0,
+			spaceBetween: 0,
+			centeredSlides: false,
+			virtualTranslate: true,
+		}),
+	});
+}

+ 49 - 0
uni_modules/zebra-swiper/modules/effect-cube/effect-cube.scss

@@ -0,0 +1,49 @@
+.swiper-cube {
+  overflow: visible;
+  &.swiper-rtl .swiper-slide {
+    transform-origin: 100% 0;
+  }
+  .swiper-cube-shadow {
+    position: absolute;
+    left: 0;
+    bottom: 0px;
+    width: 100%;
+    height: 100%;
+    opacity: 0.6;
+    z-index: 0;
+
+    &:before {
+      content: '';
+      background: #000;
+      position: absolute;
+      left: 0;
+      top: 0;
+      bottom: 0;
+      right: 0;
+      -webkit-filter: blur(50px);
+      filter: blur(50px);
+    }
+  }
+}
+
+.swiper-slide-cube {
+    pointer-events: none;
+    backface-visibility: hidden;
+    z-index: 1;
+    visibility: hidden;
+    transform-origin: 0 0;
+    width: 100%;
+    height: 100%;
+	transform-style: preserve-3d;
+    .swiper-slide {
+      pointer-events: none;
+    }
+}
+  
+  .swiper-slide-cube.swiper-slide-active,
+  .swiper-slide-cube.swiper-slide-next,
+  .swiper-slide-cube.swiper-slide-prev,
+  .swiper-slide-cube.swiper-slide-next + .swiper-slide {
+    pointer-events: auto;
+    visibility: visible;
+  }

+ 78 - 0
uni_modules/zebra-swiper/modules/effect-fade/effect-fade.js

@@ -0,0 +1,78 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
+export default function EffectFade({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		fadeEffect: {
+			crossFade: false,
+			transformEl: null
+		}
+	});
+
+	const setTranslate = () => {
+		const {
+			slides
+		} = swiper;
+		const params = swiper.params.fadeEffect;
+		for (let i = 0; i < slides.length; i += 1) {
+			const $slideEl = swiper.slides[i];
+			const offset = $slideEl.swiperSlideOffset;
+			let tx = -offset;
+			if (!swiper.params.virtualTranslate) tx -= swiper.translate;
+			let ty = 0;
+
+			if (!swiper.isHorizontal()) {
+				ty = tx;
+				tx = 0;
+			}
+
+			const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl.progress), 0) :
+				1 + Math.min(Math.max($slideEl.progress, -1), 0);
+			const $targetEl = effectTarget(params, $slideEl);
+			$targetEl.css({
+				opacity: slideOpacity
+			})
+			$targetEl.transform(`translate3d(${tx}px, ${ty}px, 0px)`);
+			if (swiper.params.willChange) {
+				$targetEl.willChange("opacity");
+			}
+			slides[i].addClass('swiper-slide-fade')
+		}
+	};
+
+	const setTransition = duration => {
+		const {
+			transformEl
+		} = swiper.params.fadeEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (let i = 0; i < $transitionElements.length; i += 1) {
+			$transitionElements[i].transition(duration);
+		}
+
+		effectVirtualTransitionEnd({
+			swiper,
+			duration,
+			transformEl,
+			allSlides: true
+		});
+	};
+
+	effectInit({
+		effect: 'fade',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		overwriteParams: () => ({
+			slidesPerView: 1,
+			slidesPerGroup: 1,
+			watchSlidesProgress: true,
+			spaceBetween: 0,
+			virtualTranslate: !swiper.params.cssMode
+		})
+	});
+}

+ 11 - 0
uni_modules/zebra-swiper/modules/effect-fade/effect-fade.scss

@@ -0,0 +1,11 @@
+.swiper-slide-fade {
+	pointer-events: none;
+	transition-property: opacity;
+	.swiper-slide {
+	      pointer-events: none;
+	}
+}
+
+.swiper-slide-fade.swiper-slide-active {
+      pointer-events: auto;
+}

+ 104 - 0
uni_modules/zebra-swiper/modules/effect-flip/effect-flip.js

@@ -0,0 +1,104 @@
+import effectInit from '../../shared/effect-init.js';
+import effectTarget from '../../shared/effect-target.js';
+import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
+
+export default function EffectFlip({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		flipEffect: {
+			slideShadows: true,
+			limitRotation: true,
+			transformEl: null,
+		},
+	});
+
+	const setTranslate = () => {
+		const {
+			slides,
+			rtlTranslate: rtl
+		} = swiper;
+		const params = swiper.params.flipEffect;
+		for (let i = 0; i < slides.length; i += 1) {
+			const $slideEl = slides[i];
+			let progress = $slideEl.progress;
+			if (swiper.params.flipEffect.limitRotation) {
+				progress = Math.max(Math.min($slideEl.progress, 1), -1);
+			}
+			const offset = $slideEl.swiperSlideOffset;
+			const rotate = -180 * progress;
+			let rotateY = rotate;
+			let rotateX = 0;
+			let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
+			let ty = 0;
+			if (!swiper.isHorizontal()) {
+				ty = tx;
+				tx = 0;
+				rotateX = -rotateY;
+				rotateY = 0;
+			} else if (rtl) {
+				rotateY = -rotateY;
+			}
+			$slideEl.css({
+				zIndex: -Math.abs(Math.round(progress)) + slides.length
+			})
+			// if (params.slideShadows) {
+			//   // Set shadows
+			//   let shadowBefore = swiper.isHorizontal()
+			//     ? $slideEl.find('.swiper-slide-shadow-left')
+			//     : $slideEl.find('.swiper-slide-shadow-top');
+			//   let shadowAfter = swiper.isHorizontal()
+			//     ? $slideEl.find('.swiper-slide-shadow-right')
+			//     : $slideEl.find('.swiper-slide-shadow-bottom');
+			//   if (shadowBefore.length === 0) {
+			//     shadowBefore = createShadow(params, $slideEl, swiper.isHorizontal() ? 'left' : 'top');
+			//   }
+			//   if (shadowAfter.length === 0) {
+			//     shadowAfter = createShadow(params, $slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
+			//   }
+			//   if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
+			//   if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
+			// }
+			const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
+			const $targetEl = effectTarget(params, $slideEl);
+			$targetEl.transform(transform);
+			if (swiper.params.willChange) {
+				$targetEl.willChange("transform");
+			}
+			slides[i].addClass('swiper-slide-flip')
+		}
+	};
+
+	const setTransition = (duration) => {
+		const {
+			transformEl
+		} = swiper.params.flipEffect;
+		const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
+		for (let i = 0; i < $transitionElements.length; i += 1) {
+			$transitionElements[i].transition(duration);
+		}
+		effectVirtualTransitionEnd({
+			swiper,
+			duration,
+			transformEl
+		});
+	};
+
+	effectInit({
+		effect: 'flip',
+		swiper,
+		on,
+		setTranslate,
+		setTransition,
+		perspective: () => true,
+		overwriteParams: () => ({
+			slidesPerView: 1,
+			slidesPerGroup: 1,
+			watchSlidesProgress: true,
+			spaceBetween: 0,
+			virtualTranslate: !swiper.params.cssMode,
+		}),
+	});
+}

+ 20 - 0
uni_modules/zebra-swiper/modules/effect-flip/effect-flip.scss

@@ -0,0 +1,20 @@
+.swiper-flip {
+  overflow: visible;
+  .swiper-slide-shadow-top,
+  .swiper-slide-shadow-bottom,
+  .swiper-slide-shadow-left,
+  .swiper-slide-shadow-right {
+    z-index: 0;
+    backface-visibility: hidden;
+  }
+}
+
+.swiper-slide-flip {
+    pointer-events: none;
+    backface-visibility: hidden;
+    z-index: 1;
+	transform-style: preserve-3d;
+    .swiper-slide {
+      pointer-events: none;
+    }
+}

+ 63 - 0
uni_modules/zebra-swiper/modules/effect-panorama/effect-panorama.js

@@ -0,0 +1,63 @@
+export default function Panorama({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		panorama: {
+			depth: 200,
+			rotate: 30,
+			stretch: 1
+		},
+	});
+
+	on('beforeInit', () => {
+		if (swiper.params.effect !== 'panorama') return;
+		swiper.classNames.push(`${swiper.params.containerModifierClass}panorama`);
+		swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
+		const overwriteParams = {
+			watchSlidesProgress: true,
+		};
+		Object.assign(swiper.params, overwriteParams);
+		Object.assign(swiper.originalParams, overwriteParams);
+	});
+
+	on('progress', () => {
+		if (swiper.params.effect !== 'panorama') return;
+		const sizesGrid = swiper.slidesSizesGrid;
+		const {
+			depth = 200, rotate = 30, stretch = 1
+		} = swiper.params.panorama;
+		const angleRad = (rotate * Math.PI) / 180;
+		const halfAngleRad = angleRad / 2;
+		const angleModifier = 1 / (180 / rotate);
+
+		for (let i = 0; i < swiper.slides.length; i += 1) {
+			const slideEl = swiper.slides[i];
+			const slideProgress = slideEl.progress;
+			const slideSize = sizesGrid[i];
+			const progressModifier = swiper.params.centeredSlides ?
+				0 :
+				(swiper.params.slidesPerView - 1) * 0.5;
+			const modifiedProgress = slideProgress + progressModifier;
+			const angleCos = 1 - Math.cos(modifiedProgress * angleModifier * Math.PI);
+			const translateX = `${modifiedProgress * (stretch * slideSize / 3) * angleCos}px`;
+			const rotateY = modifiedProgress * rotate;
+			const radius = (slideSize * 0.5) / Math.sin(halfAngleRad);
+			const translateZ = `${radius * angleCos - depth}px`;
+			slideEl.transform(
+				`translateX(${translateX}) translateZ(${translateZ}) rotateY(${rotateY}deg)`);
+			if (swiper.params.willChange) {
+				slideEl.willChange("transform");
+			}
+			slideEl.addClass('swiper-slide-panorama')
+		}
+	});
+
+	on('setTransition', (s, duration) => {
+		if (swiper.params.effect !== 'panorama') return;
+		swiper.slides.forEach((slideEl) => {
+			slideEl.transition(duration);
+		});
+	});
+}

+ 3 - 0
uni_modules/zebra-swiper/modules/effect-panorama/effect-panorama.scss

@@ -0,0 +1,3 @@
+.swiper-panorama {
+  overflow: visible;
+}

+ 241 - 0
uni_modules/zebra-swiper/modules/free-mode/free-mode.js

@@ -0,0 +1,241 @@
+import {
+	now
+} from '../../shared/utils.js';
+export default function freeMode({
+	swiper,
+	extendParams,
+	emit,
+	once
+}) {
+	extendParams({
+		freeMode: {
+			enabled: false,
+			momentum: true,
+			momentumRatio: 1,
+			momentumBounce: true,
+			momentumBounceRatio: 1,
+			momentumVelocityRatio: 1,
+			sticky: false,
+			minimumVelocity: 0.02
+		}
+	});
+
+	function onTouchMove() {
+		const {
+			touchEventsData: data,
+			touches
+		} = swiper; // Velocity
+
+		if (data.velocities.length === 0) {
+			data.velocities.push({
+				position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
+				time: data.touchStartTime
+			});
+		}
+
+		data.velocities.push({
+			position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
+			time: now()
+		});
+	}
+
+	function onTouchEnd({
+		currentPos
+	}) {
+		const {
+			params,
+			$wrapperEl,
+			rtlTranslate: rtl,
+			snapGrid,
+			touchEventsData: data
+		} = swiper; // Time diff
+
+		const touchEndTime = now();
+		const timeDiff = touchEndTime - data.touchStartTime;
+
+		if (currentPos < -swiper.minTranslate()) {
+			swiper.slideTo(swiper.activeIndex);
+			return;
+		}
+
+		if (currentPos > -swiper.maxTranslate()) {
+			if (swiper.slides.length < snapGrid.length) {
+				swiper.slideTo(snapGrid.length - 1);
+			} else {
+				swiper.slideTo(swiper.slides.length - 1);
+			}
+
+			return;
+		}
+
+		if (params.freeMode.momentum) {
+			if (data.velocities.length > 1) {
+				const lastMoveEvent = data.velocities.pop();
+				const velocityEvent = data.velocities.pop();
+				const distance = lastMoveEvent.position - velocityEvent.position;
+				const time = lastMoveEvent.time - velocityEvent.time;
+				swiper.velocity = distance / time;
+				swiper.velocity /= 2;
+
+				if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
+					swiper.velocity = 0;
+				} // this implies that the user stopped moving a finger then released.
+				// There would be no events with distance zero, so the last event is stale.
+
+
+				if (time > 150 || now() - lastMoveEvent.time > 300) {
+					swiper.velocity = 0;
+				}
+			} else {
+				swiper.velocity = 0;
+			}
+
+			swiper.velocity *= params.freeMode.momentumVelocityRatio;
+			data.velocities.length = 0;
+			let momentumDuration = 1000 * params.freeMode.momentumRatio;
+			const momentumDistance = swiper.velocity * momentumDuration;
+			let newPosition = swiper.translate + momentumDistance;
+			if (rtl) newPosition = -newPosition;
+			let doBounce = false;
+			let afterBouncePosition;
+			const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
+			let needsLoopFix;
+
+			if (newPosition < swiper.maxTranslate()) {
+				if (params.freeMode.momentumBounce) {
+					if (newPosition + swiper.maxTranslate() < -bounceAmount) {
+						newPosition = swiper.maxTranslate() - bounceAmount;
+					}
+
+					afterBouncePosition = swiper.maxTranslate();
+					doBounce = true;
+					data.allowMomentumBounce = true;
+				} else {
+					newPosition = swiper.maxTranslate();
+				}
+
+				if (params.loop && params.centeredSlides) needsLoopFix = true;
+			} else if (newPosition > swiper.minTranslate()) {
+				if (params.freeMode.momentumBounce) {
+					if (newPosition - swiper.minTranslate() > bounceAmount) {
+						newPosition = swiper.minTranslate() + bounceAmount;
+					}
+
+					afterBouncePosition = swiper.minTranslate();
+					doBounce = true;
+					data.allowMomentumBounce = true;
+				} else {
+					newPosition = swiper.minTranslate();
+				}
+
+				if (params.loop && params.centeredSlides) needsLoopFix = true;
+			} else if (params.freeMode.sticky) {
+				let nextSlide;
+
+				for (let j = 0; j < snapGrid.length; j += 1) {
+					if (snapGrid[j] > -newPosition) {
+						nextSlide = j;
+						break;
+					}
+				}
+
+				if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) ||
+					swiper.swipeDirection === 'next') {
+					newPosition = snapGrid[nextSlide];
+				} else {
+					newPosition = snapGrid[nextSlide - 1];
+				}
+
+				newPosition = -newPosition;
+			}
+
+			if (needsLoopFix) {
+				once('transitionEnd', () => {
+					swiper.loopFix();
+				});
+			} // Fix duration
+
+
+			if (swiper.velocity !== 0) {
+				if (rtl) {
+					momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
+				} else {
+					momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
+				}
+
+				if (params.freeMode.sticky) {
+					const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
+					const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
+
+					if (moveDistance < currentSlideSize) {
+						momentumDuration = params.speed;
+					} else if (moveDistance < 2 * currentSlideSize) {
+						momentumDuration = params.speed * 1.5;
+					} else {
+						momentumDuration = params.speed * 2.5;
+					}
+				}
+			} else if (params.freeMode.sticky) {
+				swiper.slideToClosest();
+				return;
+			}
+
+			if (params.freeMode.momentumBounce && doBounce) {
+				swiper.updateProgress(afterBouncePosition);
+				swiper.setTransition(momentumDuration);
+				swiper.setTranslate(newPosition);
+				swiper.transitionStart(true, swiper.swipeDirection);
+				swiper.animating = true;
+				$wrapperEl.transitionEnd(() => {
+					if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
+					emit('momentumBounce');
+					swiper.setTransition(params.speed);
+					setTimeout(() => {
+						swiper.setTranslate(afterBouncePosition);
+						$wrapperEl.transitionEnd(() => {
+							if (!swiper || swiper.destroyed) return;
+							swiper.transitionEnd();
+						}, momentumDuration);
+					}, 0);
+				}, momentumDuration);
+			} else if (swiper.velocity) {
+				emit('_freeModeNoMomentumRelease');
+				swiper.updateProgress(newPosition);
+				swiper.setTransition(momentumDuration);
+				swiper.setTranslate(newPosition);
+				swiper.transitionStart(true, swiper.swipeDirection);
+
+				if (!swiper.animating) {
+					swiper.animating = true;
+					$wrapperEl.transitionEnd(() => {
+						if (!swiper || swiper.destroyed) return;
+						swiper.transitionEnd();
+					}, momentumDuration);
+				}
+			} else {
+				swiper.updateProgress(newPosition);
+			}
+
+			swiper.updateActiveIndex();
+			swiper.updateSlidesClasses();
+		} else if (params.freeMode.sticky) {
+			swiper.slideToClosest();
+			return;
+		} else if (params.freeMode) {
+			emit('_freeModeNoMomentumRelease');
+		}
+
+		if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
+			swiper.updateProgress();
+			swiper.updateActiveIndex();
+			swiper.updateSlidesClasses();
+		}
+	}
+
+	Object.assign(swiper, {
+		freeMode: {
+			onTouchMove,
+			onTouchEnd
+		}
+	});
+}

+ 188 - 0
uni_modules/zebra-swiper/modules/navigation/navigation.js

@@ -0,0 +1,188 @@
+export default function Navigation({
+	swiper,
+	extendParams,
+	on,
+	emit
+}) {
+	extendParams({
+		navigation: {
+			nextEl: null,
+			prevEl: null,
+
+			hideOnClick: false,
+			disabledClass: 'swiper-button-disabled',
+			hiddenClass: 'swiper-button-hidden',
+			lockClass: 'swiper-button-lock',
+		},
+	});
+
+	swiper.navigation = {
+		nextEl: null,
+		$nextEl: null,
+		prevEl: null,
+		$prevEl: null,
+	};
+
+	function toggleEl($el, disabled) {
+		if (!swiper.$wrapperEl) return
+		// debugger
+		const params = swiper.params.navigation;
+		if ($el) {
+			swiper.$wrapperEl[disabled ? `add${$el}` : `remove${$el}`](params.disabledClass);
+			if (swiper.params.watchOverflow && swiper.enabled) {
+				swiper.$wrapperEl[swiper.isLocked ? `add${$el}` : `remove${$el}`](params.lockClass);
+			}
+		}
+	}
+
+	function update() {
+		// Update Navigation Buttons
+		if (swiper.params.loop) return;
+		const {
+			$nextEl,
+			$prevEl
+		} = swiper.navigation;
+
+		toggleEl('PrevElClass', swiper.isBeginning && !swiper.params.rewind);
+		toggleEl('NextElClass', swiper.isEnd && !swiper.params.rewind);
+	}
+
+	function onPrevClick(e) {
+		// e.preventDefault();
+		if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
+		swiper.slidePrev();
+	}
+
+	function onNextClick() {
+		// e.preventDefault();
+		if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
+		swiper.slideNext();
+	}
+
+	function init() {
+		const params = swiper.params.navigation;
+		if (params.slot || params.custom) {
+			params.nextEl = true;
+			params.prevEl = true;
+		}
+		if (!(params.nextEl || params.prevEl) && !params.slot && !params.custom) return;
+		if (params.slot) {
+			swiper.native.updateData({
+				showPrevButtonSlot: true,
+				showNextButtonSlot: true
+			})
+		} else if (params.custom) {} else {
+			swiper.native.updateData({
+				showPrevButton: true,
+				showNextButton: true
+			})
+		}
+
+		const $nextEl = params.nextEl;
+		const $prevEl = params.prevEl;
+
+		if ($nextEl) {
+			swiper.on('nextClick', onNextClick);
+		}
+		if ($prevEl) {
+			swiper.on('prevClick', onPrevClick);
+		}
+
+		Object.assign(swiper.navigation, {
+			$nextEl,
+			nextEl: $nextEl,
+			$prevEl,
+			prevEl: $prevEl,
+		});
+
+		if (!swiper.enabled) {
+			if ($nextEl) swiper.$wrapperEl.addNextElClass(params.lockClass);
+			if ($prevEl) swiper.$wrapperEl.addPrevElClass(params.lockClass);
+		}
+	}
+
+	function destroy() {
+		const {
+			$nextEl,
+			$prevEl
+		} = swiper.navigation;
+		if ($nextEl) {
+			swiper.off('nextClick', onNextClick);
+			swiper.$wrapperEl.removeNextElClass(swiper.params.navigation.disabledClass);
+		}
+		if ($prevEl) {
+			swiper.off('prevClick', onPrevClick);
+			swiper.$wrapperEl.removePrevElClass(swiper.params.navigation.disabledClass);
+		}
+	}
+
+	on('init', () => {
+		init();
+		update();
+	});
+	on('toEdge fromEdge lock unlock', () => {
+		update();
+	});
+	on('destroy', () => {
+		destroy();
+	});
+	on('enable disable', () => {
+		const {
+			$nextEl,
+			$prevEl
+		} = swiper.navigation;
+		if ($nextEl) {
+			swiper.$wrapperEl[swiper.enabled ? 'removeNextElClass' : 'addNextElClass'](swiper.params.navigation
+				.lockClass);
+			// $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
+		}
+		if ($prevEl) {
+			swiper.$wrapperEl[swiper.enabled ? 'removePrevElClass' : 'addPrevElClass'](swiper.params.navigation
+				.lockClass);
+			// $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
+		}
+	});
+	// on('click', (_s, e) => {
+	// 	const {
+	// 		$nextEl,
+	// 		$prevEl
+	// 	} = swiper.navigation;
+	// 	const targetEl = e.target;
+	// 	if (
+	// 		swiper.params.navigation.hideOnClick &&
+	// 		!$(targetEl).is($prevEl) &&
+	// 		!$(targetEl).is($nextEl)
+	// 	) {
+	// 		if (
+	// 			swiper.pagination &&
+	// 			swiper.params.pagination &&
+	// 			swiper.params.pagination.clickable &&
+	// 			(swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))
+	// 		)
+	// 			return;
+	// 		let isHidden;
+	// 		if ($nextEl) {
+	// 			isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);
+	// 		} else if ($prevEl) {
+	// 			isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);
+	// 		}
+	// 		if (isHidden === true) {
+	// 			emit('navigationShow');
+	// 		} else {
+	// 			emit('navigationHide');
+	// 		}
+	// 		if ($nextEl) {
+	// 			$nextEl.toggleClass(swiper.params.navigation.hiddenClass);
+	// 		}
+	// 		if ($prevEl) {
+	// 			$prevEl.toggleClass(swiper.params.navigation.hiddenClass);
+	// 		}
+	// 	}
+	// });
+
+	Object.assign(swiper.navigation, {
+		update,
+		init,
+		destroy,
+	});
+}

+ 49 - 0
uni_modules/zebra-swiper/modules/navigation/navigation.scss

@@ -0,0 +1,49 @@
+.swiper-button-prev,
+.swiper-button-next {
+  position: absolute;
+  top: 50%;
+  // width: calc(80rpx / 44 * 27);
+  height: 80rpx;
+  margin-top: calc(0rpx - (80rpx / 2));
+  z-index: 10;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #007aff;
+  font-size: 50rpx;
+  &.swiper-button-disabled {
+    opacity: 0.35;
+    cursor: auto;
+    pointer-events: none;
+  }
+  &:after {
+    font-family: swiper-icons;
+    font-size: 80rpx;
+    text-transform: none !important;
+    letter-spacing: 0;
+    text-transform: none;
+    font-variant: initial;
+    line-height: 1;
+  }
+}
+.swiper-button-prev,
+.swiper-rtl .swiper-button-next {
+  // &:after {
+  //   content: 'prev';
+  // }
+  left: 10px;
+  right: auto;
+}
+.swiper-button-next,
+.swiper-rtl .swiper-button-prev {
+  // &:after {
+  //   content: 'next';
+  // }
+  right: 10px;
+  left: auto;
+}
+
+.swiper-button-lock {
+  display: none;
+}

+ 510 - 0
uni_modules/zebra-swiper/modules/pagination/pagination.js

@@ -0,0 +1,510 @@
+import classesToSelector from '../../shared/classes-to-selector.js';
+
+export default function Pagination({
+	swiper,
+	extendParams,
+	on,
+	emit
+}) {
+	const pfx = 'swiper-pagination';
+	extendParams({
+		pagination: {
+			el: null,
+			bulletElement: 'span',
+			clickable: false,
+			hideOnClick: false,
+			renderBullet: null,
+			renderProgressbar: null,
+			renderFraction: null,
+			renderCustom: null,
+			progressbarOpposite: false,
+			type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'
+			dynamicBullets: false,
+			dynamicMainBullets: 1,
+			formatFractionCurrent: (number) => number,
+			formatFractionTotal: (number) => number,
+			bulletClass: `${pfx}-bullet`,
+			bulletActiveClass: `${pfx}-bullet-active`,
+			modifierClass: `${pfx}-`,
+			currentClass: `${pfx}-current`,
+			totalClass: `${pfx}-total`,
+			hiddenClass: `${pfx}-hidden`,
+			progressbarFillClass: `${pfx}-progressbar-fill`,
+			progressbarOppositeClass: `${pfx}-progressbar-opposite`,
+			clickableClass: `${pfx}-clickable`,
+			lockClass: `${pfx}-lock`,
+			horizontalClass: `${pfx}-horizontal`,
+			verticalClass: `${pfx}-vertical`,
+		},
+	});
+
+	swiper.pagination = {
+		el: null,
+		$el: null,
+		bullets: [],
+	};
+
+	let bulletSize;
+	let dynamicBulletIndex = 0;
+
+	function isPaginationDisabled() {
+		return (
+			!swiper.params.pagination.el ||
+			!swiper.pagination.el ||
+			!swiper.pagination.$el
+		);
+	}
+
+	function setSideBullets($bulletEl, position) {
+
+		const {
+			bulletActiveClass
+		} = swiper.params.pagination;
+		const bullets = swiper.pagination.bullets;
+		if (bullets[$bulletEl.index + position]) {
+			bullets[$bulletEl.index + position].addPaginationItemClass(
+				`${bulletActiveClass}-${position>0?'next':'prev'}`);
+		}
+		if (bullets[$bulletEl.index + (position > 0 ? position + 1 : position -
+				1)]) {
+
+			bullets[$bulletEl.index + (position > 0 ? position + 1 : position - 1)].addPaginationItemClass(
+				`${bulletActiveClass}-${position>0?'next':'prev'}-${position>0?'next':'prev'}`);
+		}
+	}
+
+	function update() {
+		// Render || Update Pagination bullets/items
+		const rtl = swiper.rtl;
+		const params = swiper.params.pagination;
+		if (isPaginationDisabled()) return;
+		const slidesLength =
+			swiper.virtual && swiper.params.virtual.enabled ?
+			swiper.virtual.slides.length :
+			swiper.slides.length;
+		const $el = swiper.pagination.$el;
+		// Current/Total
+		let current;
+		const total = swiper.params.loop ?
+			Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
+			swiper.snapGrid.length;
+		if (swiper.params.loop) {
+			current = Math.ceil(
+				(swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup,
+			);
+			if (current > slidesLength - 1 - swiper.loopedSlides * 2) {
+				current -= slidesLength - swiper.loopedSlides * 2;
+			}
+			if (current > total - 1) current -= total;
+			if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
+		} else if (typeof swiper.snapIndex !== 'undefined') {
+			current = swiper.snapIndex;
+		} else {
+			current = swiper.activeIndex || 0;
+		}
+		// Types
+		if (
+			params.type === 'bullets' &&
+			swiper.pagination.bullets &&
+			swiper.pagination.bullets.length > 0
+		) {
+			const bullets = swiper.pagination.bullets;
+			let firstIndex;
+			let lastIndex;
+			let midIndex;
+			if (params.dynamicBullets) {
+				bulletSize = bullets[0][swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'];
+				swiper.$wrapperEl.paginationCss({
+					[swiper.isHorizontal() ? 'width' :
+						'height'
+					]: `${bulletSize * (params.dynamicMainBullets + 4)}px`
+				});
+				if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
+					dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0);
+					if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
+						dynamicBulletIndex = params.dynamicMainBullets - 1;
+					} else if (dynamicBulletIndex < 0) {
+						dynamicBulletIndex = 0;
+					}
+				}
+				firstIndex = Math.max(current - dynamicBulletIndex, 0);
+				lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
+				midIndex = (lastIndex + firstIndex) / 2;
+			}
+
+			bullets.forEach((item) => {
+				item.removePaginationItemClass(
+					['', '-next', '-next-next', '-prev', '-prev-prev', '-main']
+					.map((suffix) => `${params.bulletActiveClass}${suffix}`)
+					.join(' '),
+				);
+			})
+			if ($el.length > 1) {
+				bullets.each((bullet) => {
+					const $bullet = $(bullet);
+					const bulletIndex = $bullet.index();
+					if (bulletIndex === current) {
+						$bullet.addClass(params.bulletActiveClass);
+					}
+					if (params.dynamicBullets) {
+						if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
+							$bullet.addClass(`${params.bulletActiveClass}-main`);
+						}
+						if (bulletIndex === firstIndex) {
+							setSideBullets($bullet, 'prev');
+						}
+						if (bulletIndex === lastIndex) {
+							setSideBullets($bullet, 'next');
+						}
+					}
+				});
+			} else {
+				const $bullet = bullets[current];
+				const bulletIndex = $bullet.index;
+				$bullet.addPaginationItemClass(params.bulletActiveClass);
+				if (params.dynamicBullets) {
+					const $firstDisplayedBullet = bullets[firstIndex];
+					const $lastDisplayedBullet = bullets[lastIndex];
+					for (let i = firstIndex; i <= lastIndex; i += 1) {
+						bullets[i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
+					}
+					if (swiper.params.loop) {
+						if (bulletIndex >= bullets.length) {
+							for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
+								bullets[bullets.length - i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
+							}
+							bullets
+								[bullets.length - params.dynamicMainBullets - 1]
+								.addPaginationItemClass(`${params.bulletActiveClass}-prev`);
+						} else {
+							setSideBullets($firstDisplayedBullet, -1);
+							setSideBullets($lastDisplayedBullet, 1);
+						}
+					} else {
+						setSideBullets($firstDisplayedBullet, -1);
+						setSideBullets($lastDisplayedBullet, 1);
+					}
+				}
+			}
+			if (params.dynamicBullets) {
+				const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
+				const bulletsOffset =
+					(bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
+				const offsetProp = rtl ? 'right' : 'left';
+				bullets.forEach((item) => {
+					item.setCss({
+						[swiper.isHorizontal() ? offsetProp : 'top']: `${bulletsOffset}px`
+					})
+				})
+				// bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
+			}
+		}
+		if (params.type === 'fraction') {
+			// $el
+			// 	.find(classesToSelector(params.currentClass))
+			// 	.text(params.formatFractionCurrent(current + 1));
+			swiper.native.paginationContent.text = params.formatFractionCurrent(current + 1);
+			swiper.native.paginationContent.total = params.formatFractionTotal(total);
+			swiper.native.updateData({
+				paginationContent: swiper.native.paginationContent,
+			})
+			// $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total));
+		}
+		if (params.type === 'progressbar') {
+			let progressbarDirection;
+			if (params.progressbarOpposite) {
+				progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
+			} else {
+				progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
+			}
+			const scale = (current + 1) / total;
+			let scaleX = 1;
+			let scaleY = 1;
+			if (progressbarDirection === 'horizontal') {
+				scaleX = scale;
+			} else {
+				scaleY = scale;
+			}
+			// $el
+			// .find(classesToSelector(params.progressbarFillClass))
+			swiper.native.paginationContent.transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`);
+			swiper.native.paginationContent.transition(swiper.params.speed);
+			swiper.native.updateData({
+				paginationContent: swiper.native.paginationContent,
+			})
+		}
+		if (params.type === 'custom' && params.renderCustom) {
+			$el.html(params.renderCustom(swiper, current + 1, total));
+			emit('paginationRender', $el[0]);
+		} else {
+			emit('paginationUpdate', $el[0]);
+		}
+		if (swiper.params.watchOverflow && swiper.enabled) {
+			swiper.$wrapperEl[swiper.isLocked ? 'addPaginationClass' : 'removePaginationClass'](params.lockClass);
+		}
+	}
+
+	function render() {
+		// Render Container
+		const params = swiper.params.pagination;
+		if (isPaginationDisabled()) return;
+		const slidesLength =
+			swiper.virtual && swiper.params.virtual.enabled ?
+			swiper.virtual.slides.length :
+			swiper.slides.length;
+
+		const $el = swiper.pagination.$el;
+		let paginationHTML = 0;
+		if (params.type === 'bullets') {
+			let numberOfBullets = swiper.params.loop ?
+				Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
+				swiper.snapGrid.length;
+			if (
+				swiper.params.freeMode &&
+				swiper.params.freeMode.enabled &&
+				!swiper.params.loop &&
+				numberOfBullets > slidesLength
+			) {
+				numberOfBullets = slidesLength;
+			}
+			for (let i = 0; i < numberOfBullets; i += 1) {
+				if (params.renderBullet) {
+					paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
+				}
+				// else {
+				// 	paginationHTML +=
+				// 		`<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
+				// }
+				// paginationHTML += 1;
+				else {
+					swiper.native.paginationType = "bullets";
+					swiper.native.paginationContent.push({
+						index: i,
+						outerWidth: 16,
+						outerHeight: 16,
+						classContent: [params.bulletClass],
+						styleContent: {},
+						addPaginationItemClass: function(value) {
+							this.classContent = Array.from(new Set([...this.classContent,
+								...value.split(" ")
+							]));
+						},
+						removePaginationItemClass: function(value) {
+							this.classContent = this.classContent.filter(item => !value.split(
+								" ").includes(item));
+						},
+						setCss: function(value) {
+							// vueNative['itemStyle'] = {
+							// 	...vueNative['itemStyle'],
+							// 	...value
+							// };Object.keys(value).forEach((item) => {
+							Object.keys(value).forEach((item) => {
+								// this.$set(this.itemStyle, item, value[item])
+								this.styleContent[item] = value[item];
+							})
+
+							// this.$set(this.itemStyle, item, value[item])
+						}
+					});
+					swiper.native.updateData({
+						paginationType: swiper.native.paginationType,
+						paginationContent: swiper.native.paginationContent,
+					})
+				}
+
+			}
+			// $el.html(paginationHTML);
+
+			// swiper.$wrapperEl.addPaginationItemClass(params.bulletClass)
+
+			// swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass));
+			swiper.pagination.bullets = swiper.native.paginationContent;
+		}
+		if (params.type === 'fraction') {
+			if (params.renderFraction) {
+				paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
+			} else {
+				swiper.native.paginationType = "fraction";
+				// paginationHTML =
+				// 	`<span class="${params.currentClass}"></span>` +
+				// 	' / ' +
+				// 	`<span class="${params.totalClass}"></span>`;
+				swiper.native.paginationContent = {
+					currentClass: params.currentClass,
+					totalClass: params.totalClass
+				}
+				swiper.native.updateData({
+					paginationType: swiper.native.paginationType,
+					paginationContent: swiper.native.paginationContent,
+				})
+			}
+		}
+		if (params.type === 'progressbar') {
+			if (params.renderProgressbar) {
+				paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
+			} else {
+				swiper.native.paginationType = "progressbar";
+				// paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
+				swiper.native.paginationContent = {
+					progressbarFillClass: params.progressbarFillClass,
+					styleContent: {
+						transform: '',
+						transitionDuration: ''
+					},
+					transition: function(value) {
+						this.styleContent.transitionDuration = `${value}ms`;
+					},
+					transform: function(value) {
+						this.styleContent.transform = value;
+					},
+				}
+				swiper.native.updateData({
+					paginationType: swiper.native.paginationType,
+					paginationContent: swiper.native.paginationContent,
+				})
+			}
+			// $el.html(paginationHTML);
+		}
+		if (params.type !== 'custom') {
+			emit('paginationRender', swiper.pagination.$el[0]);
+		}
+	}
+
+	function init() {
+		const params = swiper.params.pagination;
+		if (!params.el) return;
+		// swiper.native.showIndicators = true;
+		swiper.native.updateData({
+			showIndicators: true
+		})
+		let $el = params.el;
+
+		if (params.type === 'bullets' && params.clickable) {
+			swiper.$wrapperEl.addPaginationClass(params.clickableClass);
+		}
+
+		swiper.$wrapperEl.addPaginationClass(params.modifierClass + params.type);
+		swiper.$wrapperEl.addPaginationClass(params.modifierClass + swiper.params.direction);
+
+		if (params.type === 'bullets' && params.dynamicBullets) {
+			swiper.$wrapperEl.addPaginationClass(`${params.modifierClass}${params.type}-dynamic`);
+			dynamicBulletIndex = 0;
+			if (params.dynamicMainBullets < 1) {
+				params.dynamicMainBullets = 1;
+			}
+		}
+		if (params.type === 'progressbar' && params.progressbarOpposite) {
+			swiper.$wrapperEl.addPaginationClass(params.progressbarOppositeClass);
+		}
+
+		if (params.clickable) {
+			swiper.on('paginationItemClick', function onClick(_s, itemIndex) {
+				let index = itemIndex * swiper.params.slidesPerGroup;
+				if (swiper.params.loop) index += swiper.loopedSlides;
+				swiper.slideTo(index);
+			});
+		}
+
+		Object.assign(swiper.pagination, {
+			$el,
+			el: $el,
+		});
+
+		if (!swiper.enabled) {
+			swiper.$wrapperEl.addPaginationClass(params.lockClass);
+		}
+	}
+
+	function destroy() {
+		const params = swiper.params.pagination;
+		if (isPaginationDisabled()) return;
+		const $el = swiper.pagination.$el;
+		if (params.clickable) {
+			swiper.off('paginationItemClick', classesToSelector(params.bulletClass));
+		}
+	}
+
+	on('init update', () => {
+		if (swiper.native.paginationContent) {
+			swiper.native.updateData({
+				paginationContent: []
+			})
+		}
+		// swiper.native.paginationContent = [];
+		init();
+		render();
+		update();
+	});
+	on('activeIndexChange', () => {
+		if (swiper.params.loop) {
+			update();
+		} else if (typeof swiper.snapIndex === 'undefined') {
+			update();
+		}
+	});
+	on('snapIndexChange', () => {
+		if (!swiper.params.loop) {
+			update();
+		}
+	});
+	on('slidesLengthChange', () => {
+		if (swiper.params.loop) {
+			render();
+			update();
+		}
+	});
+	on('snapGridLengthChange', () => {
+		if (!swiper.params.loop) {
+			render();
+			update();
+		}
+	});
+	on('destroy', () => {
+		destroy();
+	});
+	on('enable disable', () => {
+		const {
+			$el
+		} = swiper.pagination;
+		if ($el) {
+			swiper.$wrapperEl[swiper.enabled ? 'removePaginationClass' : 'addPaginationClass'](swiper.params
+				.pagination.lockClass);
+		}
+	});
+	on('lock unlock', () => {
+		update();
+	});
+	on('click', (_s, e) => {
+		const targetEl = e.target;
+		const {
+			$el
+		} = swiper.pagination;
+		if (
+			swiper.params.pagination.el &&
+			swiper.params.pagination.hideOnClick &&
+			$el.length > 0 &&
+			!$(targetEl).hasClass(swiper.params.pagination.bulletClass)
+		) {
+			if (
+				swiper.navigation &&
+				((swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) ||
+					(swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl))
+			)
+				return;
+			const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass);
+			if (isHidden === true) {
+				emit('paginationShow');
+			} else {
+				emit('paginationHide');
+			}
+			$el.toggleClass(swiper.params.pagination.hiddenClass);
+		}
+	});
+
+	Object.assign(swiper.pagination, {
+		render,
+		update,
+		init,
+		destroy,
+	});
+}

+ 149 - 0
uni_modules/zebra-swiper/modules/pagination/pagination.scss

@@ -0,0 +1,149 @@
+.swiper-pagination {
+  position: absolute;
+  text-align: center;
+  transition: 300ms opacity;
+  transform: translate3d(0, 0, 0);
+  z-index: 10;
+  font-size: 24rpx;
+  &.swiper-pagination-hidden {
+    opacity: 0;
+  }
+}
+/* Common Styles */
+.swiper-pagination-fraction,
+.swiper-pagination-custom,
+.swiper-horizontal > .swiper-pagination-bullets,
+.swiper-pagination-bullets.swiper-pagination-horizontal {
+  bottom: 10px;
+  left: 0;
+  width: 100%;
+}
+/* Bullets */
+.swiper-pagination-bullets-dynamic {
+  overflow: hidden;
+  font-size: 0;
+  .swiper-pagination-bullet {
+    transform: scale(0.33);
+    position: relative;
+  }
+  .swiper-pagination-bullet-active {
+    transform: scale(1);
+  }
+  .swiper-pagination-bullet-active-main {
+    transform: scale(1);
+  }
+  .swiper-pagination-bullet-active-prev {
+    transform: scale(0.66);
+  }
+  .swiper-pagination-bullet-active-prev-prev {
+    transform: scale(0.33);
+  }
+  .swiper-pagination-bullet-active-next {
+    transform: scale(0.66);
+  }
+  .swiper-pagination-bullet-active-next-next {
+    transform: scale(0.33);
+  }
+}
+.swiper-pagination-bullet {
+  width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 8px));
+  height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
+  display: inline-block;
+  border-radius: 50%;
+  background: var(--swiper-pagination-bullet-inactive-color, #000);
+  opacity: var(--swiper-pagination-bullet-inactive-opacity, 0.2);
+  @at-root button#{&} {
+    border: none;
+    margin: 0;
+    padding: 0;
+    box-shadow: none;
+    appearance: none;
+  }
+  .swiper-pagination-clickable & {
+    cursor: pointer;
+  }
+
+  &:only-child {
+    display: none !important;
+  }
+}
+.swiper-pagination-bullet-active {
+  opacity: var(--swiper-pagination-bullet-opacity, 1);
+  background: var(--swiper-pagination-color, #007aff);
+}
+
+.swiper-vertical > .swiper-pagination-bullets,
+.swiper-pagination-vertical.swiper-pagination-bullets {
+  right: 10px;
+  top: 50%;
+  transform: translate3d(0px, -50%, 0);
+  .swiper-pagination-bullet {
+    margin: var(--swiper-pagination-bullet-vertical-gap, 6px) 0;
+    display: block;
+  }
+  &.swiper-pagination-bullets-dynamic {
+    top: 50%;
+    transform: translateY(-50%);
+    width: 8px;
+    .swiper-pagination-bullet {
+      display: inline-block;
+      transition: 200ms transform, 200ms top;
+    }
+  }
+}
+.swiper-horizontal > .swiper-pagination-bullets,
+.swiper-pagination-horizontal.swiper-pagination-bullets {
+  .swiper-pagination-bullet {
+    margin: 0 var(--swiper-pagination-bullet-horizontal-gap, 4px);
+  }
+  &.swiper-pagination-bullets-dynamic {
+    left: 50%;
+    transform: translateX(-50%);
+    white-space: nowrap;
+    .swiper-pagination-bullet {
+      transition: 200ms transform, 200ms left;
+    }
+  }
+}
+.swiper-horizontal.swiper-rtl > .swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+  transition: 200ms transform, 200ms right;
+}
+/* Progress */
+.swiper-pagination-progressbar {
+  background: rgba(0, 0, 0, 0.25);
+  position: absolute;
+  .swiper-pagination-progressbar-fill {
+    background: var(--swiper-pagination-color, #007aff);
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    transform: scale(0);
+    transform-origin: left top;
+  }
+  .swiper-rtl & .swiper-pagination-progressbar-fill {
+    transform-origin: right top;
+  }
+  .swiper-horizontal > &,
+  &.swiper-pagination-horizontal,
+  .swiper-vertical > &.swiper-pagination-progressbar-opposite,
+  &.swiper-pagination-vertical.swiper-pagination-progressbar-opposite {
+    width: 100%;
+    height: 4px;
+    left: 0;
+    top: 0;
+  }
+  .swiper-vertical > &,
+  &.swiper-pagination-vertical,
+  .swiper-horizontal > &.swiper-pagination-progressbar-opposite,
+  &.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite {
+    width: 4px;
+    height: 100%;
+    left: 0;
+    top: 0;
+  }
+}
+.swiper-pagination-lock {
+  display: none;
+}

+ 390 - 0
uni_modules/zebra-swiper/modules/scrollbar/scrollbar.js

@@ -0,0 +1,390 @@
+import {
+	nextTick
+} from '../../shared/utils.js';
+
+export default function Scrollbar({
+	swiper,
+	extendParams,
+	on,
+	emit
+}) {
+
+	let isTouched = false;
+	let timeout = null;
+	let dragTimeout = null;
+	let dragStartPos;
+	let dragSize;
+	let trackSize;
+	let divider;
+
+	extendParams({
+		scrollbar: {
+			el: null,
+			dragSize: 'auto',
+			hide: false,
+			draggable: false,
+			snapOnRelease: true,
+			lockClass: 'swiper-scrollbar-lock',
+			dragClass: 'swiper-scrollbar-drag',
+		},
+	});
+
+	swiper.scrollbar = {
+		el: null,
+		dragEl: null,
+		$el: null,
+		$dragEl: null,
+	};
+
+	function setTranslate() {
+		if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
+		const {
+			scrollbar,
+			rtlTranslate: rtl,
+			progress
+		} = swiper;
+		const params = swiper.params.scrollbar;
+
+		let newSize = dragSize;
+		let newPos = (trackSize - dragSize) * progress;
+		if (rtl) {
+			newPos = -newPos;
+			if (newPos > 0) {
+				newSize = dragSize - newPos;
+				newPos = 0;
+			} else if (-newPos + dragSize > trackSize) {
+				newSize = trackSize + newPos;
+			}
+		} else if (newPos < 0) {
+			newSize = dragSize + newPos;
+			newPos = 0;
+		} else if (newPos + dragSize > trackSize) {
+			newSize = trackSize - newPos;
+		}
+		if (swiper.isHorizontal()) {
+			swiper.$wrapperEl.scrollbarItemTransform(`translate3d(${newPos}px, 0, 0)`);
+			swiper.$wrapperEl.scrollbarItemCss({
+				width: `${newSize}px`
+			})
+		} else {
+			swiper.$wrapperEl.scrollbarItemTransform(`translate3d(0px, ${newPos}px, 0)`);
+			swiper.$wrapperEl.scrollbarItemCss({
+				height: `${newSize}px`
+			})
+		}
+		if (params.hide) {
+			clearTimeout(timeout);
+			swiper.$wrapperEl.scrollbarCss({
+				opacity: 1
+			})
+			timeout = setTimeout(() => {
+				swiper.$wrapperEl.scrollbarCss({
+					opacity: 0
+				})
+				swiper.$wrapperEl.scrollbarTransition(400)
+			}, 1000);
+		}
+	}
+
+	function setTransition(duration) {
+		if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
+		swiper.$wrapperEl.scrollbarItemTransition(duration);
+	}
+
+	async function updateSize() {
+		if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
+
+		const {
+			scrollbar
+		} = swiper;
+		const {
+			$el,
+			methods
+		} = scrollbar;
+
+		swiper.$wrapperEl.scrollbarItemCss({
+			width: '',
+			height: ''
+		})
+		let rectInfo = await swiper.native.getRectScrollbar();
+
+		methods.offset = function() {
+			return rectInfo;
+		}
+		trackSize = swiper.isHorizontal() ? rectInfo.width : rectInfo.height;
+
+		divider =
+			swiper.size /
+			(swiper.virtualSize +
+				swiper.params.slidesOffsetBefore -
+				(swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
+		if (swiper.params.scrollbar.dragSize === 'auto') {
+			dragSize = trackSize * divider;
+		} else {
+			dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
+		}
+
+		if (swiper.isHorizontal()) {
+			swiper.$wrapperEl.scrollbarItemCss({
+				width: `${dragSize}px`
+			})
+		} else {
+			swiper.$wrapperEl.scrollbarItemCss({
+				height: `${dragSize}px`
+			})
+		}
+
+		if (divider >= 1) {
+			swiper.$wrapperEl.scrollbarCss({
+				display: 'none'
+			})
+		} else {
+			swiper.$wrapperEl.scrollbarCss({
+				display: ''
+			})
+		}
+		if (swiper.params.scrollbar.hide) {
+			swiper.$wrapperEl.scrollbarCss({
+				opacity: 0
+			})
+		}
+
+		if (swiper.params.watchOverflow && swiper.enabled) {
+			swiper.$wrapperEl[swiper.isLocked ? 'addScrollbarClass' : 'removeScrollbarClass'](
+				swiper.params.scrollbar.lockClass,
+			);
+		}
+	}
+
+	function getPointerPosition(e) {
+		if (swiper.isHorizontal()) {
+			return e.type === 'touchstart' || e.type === 'touchmove' || 'touchStart' || e.type === 'touchMove' ?
+				e.touches[0].clientX :
+				e.clientX;
+		}
+		return e.type === 'touchstart' || e.type === 'touchmove' ?
+			e.touches[0].clientY :
+			e.clientY;
+	}
+
+	function setDragPosition(e) {
+		const {
+			scrollbar,
+			rtlTranslate: rtl
+		} = swiper;
+		const {
+			$el,
+			methods
+		} = scrollbar;
+
+		let positionRatio;
+		positionRatio =
+			(getPointerPosition(e) -
+				methods.offset()[swiper.isHorizontal() ? 'left' : 'top'] -
+				(dragStartPos !== null ? dragStartPos : dragSize / 2)) /
+			(trackSize - dragSize);
+		positionRatio = Math.max(Math.min(positionRatio, 1), 0);
+		if (rtl) {
+			positionRatio = 1 - positionRatio;
+		}
+
+		const position =
+			swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
+
+		swiper.updateProgress(position);
+		swiper.setTranslate(position);
+		swiper.updateActiveIndex();
+		swiper.updateSlidesClasses();
+	}
+
+	function onDragStart(_s, e) {
+		const params = swiper.params.scrollbar;
+		const {
+			scrollbar,
+			$wrapperEl
+		} = swiper;
+		isTouched = true;
+		dragStartPos =
+			// e.target ===
+			//  $dragEl[0] || e.target === $dragEl ?
+			// getPointerPosition(e) -
+			// e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] :
+			null;
+		// e.preventDefault();
+		// e.stopPropagation();
+
+		$wrapperEl.transition(100);
+		swiper.$wrapperEl.scrollbarItemTransition(100)
+		// $dragEl.transition(100);
+		setDragPosition(e);
+
+		clearTimeout(dragTimeout);
+		swiper.$wrapperEl.scrollbarTransition(0)
+		if (params.hide) {
+			swiper.$wrapperEl.scrollbarCss({
+				opacity: 1
+			})
+		}
+		if (swiper.params.cssMode) {
+			swiper.$wrapperEl.css({
+				'scroll-snap-type': 'none'
+			});
+		}
+		emit('scrollbarDragStart', e);
+	}
+
+	function onDragMove(_s, e) {
+		const {
+			scrollbar,
+			$wrapperEl
+		} = swiper;
+
+		if (!isTouched) return;
+		setDragPosition(e);
+		$wrapperEl.transition(0);
+		swiper.$wrapperEl.scrollbarTransition(0)
+		swiper.$wrapperEl.scrollbarItemTransition(0)
+		emit('scrollbarDragMove', e);
+	}
+
+	function onDragEnd(_s, e) {
+		const params = swiper.params.scrollbar;
+		const {
+			scrollbar,
+			$wrapperEl
+		} = swiper;
+		const {
+			$el
+		} = scrollbar;
+
+		if (!isTouched) return;
+		isTouched = false;
+		if (swiper.params.cssMode) {
+			swiper.$wrapperEl.css({
+				'scroll-snap-type': ''
+			});
+			$wrapperEl.transition('');
+		}
+		if (params.hide) {
+			clearTimeout(dragTimeout);
+			dragTimeout = nextTick(() => {
+				swiper.$wrapperEl.scrollbarCss({
+					opacity: 0
+				})
+				swiper.$wrapperEl.scrollbarTransition(400)
+			}, 1000);
+		}
+		emit('scrollbarDragEnd', e);
+		if (params.snapOnRelease) {
+			swiper.slideToClosest();
+		}
+	}
+
+	function events(method) {
+		const {
+			scrollbar,
+			touchEventsTouch,
+			touchEventsDesktop,
+			params,
+			support
+		} = swiper;
+		const $el = scrollbar.$el;
+		const target = $el;
+		const activeListener =
+			support.passiveListener && params.passiveListeners ? {
+				passive: false,
+				capture: false
+			} :
+			false;
+		const passiveListener =
+			support.passiveListener && params.passiveListeners ? {
+				passive: true,
+				capture: false
+			} :
+			false;
+		if (!target) return;
+		const eventMethod = method === 'on' ? 'on' : 'off';
+		if (!support.touch) {
+			swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
+			swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
+			swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
+		} else {
+			swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
+			swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
+			swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
+		}
+	}
+
+	function enableDraggable() {
+		if (!swiper.params.scrollbar.el) return;
+		events('on');
+	}
+
+	function disableDraggable() {
+		if (!swiper.params.scrollbar.el) return;
+		events('off');
+	}
+
+	function init() {
+		const {
+			scrollbar,
+		} = swiper;
+		const params = swiper.params.scrollbar;
+		if (!params.el) return;
+		// swiper.native.updateData({
+		// 	scrollbarShow: true
+		// })
+		let $el = params.el;
+
+		Object.assign(scrollbar, {
+			$el,
+			el: $el,
+			methods: {}
+		});
+
+		if (params.draggable) {
+			enableDraggable();
+		}
+
+		swiper.$wrapperEl[swiper.enabled ? 'removeScrollbarClass' : 'addScrollbarClass'](swiper.params.scrollbar
+			.lockClass);
+		return true;
+	}
+
+	function destroy() {
+		disableDraggable();
+	}
+
+	on('init', async () => {
+		await init();
+		updateSize();
+		setTranslate();
+	});
+	on('update resize observerUpdate lock unlock', () => {
+		updateSize();
+	});
+	on('setTranslate', () => {
+		setTranslate();
+	});
+	on('setTransition', (_s, duration) => {
+		setTransition(duration);
+	});
+	on('enable disable', () => {
+		const {
+			$el
+		} = swiper.scrollbar;
+		if ($el) {
+			$el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
+		}
+	});
+	on('destroy', () => {
+		destroy();
+	});
+
+	Object.assign(swiper.scrollbar, {
+		updateSize,
+		setTranslate,
+		init,
+		destroy,
+	});
+}

+ 38 - 0
uni_modules/zebra-swiper/modules/scrollbar/scrollbar.scss

@@ -0,0 +1,38 @@
+/* Scrollbar */
+.swiper-scrollbar {
+  border-radius: 10px;
+  position: relative;
+  -ms-touch-action: none;
+  background: rgba(0, 0, 0, 0.1);
+  .swiper-horizontal > & {
+    position: absolute;
+    left: 1%;
+    bottom: 3px;
+    z-index: 50;
+    height: 5px;
+    width: 98%;
+  }
+  .swiper-vertical > & {
+    position: absolute;
+    right: 3px;
+    top: 1%;
+    z-index: 50;
+    width: 5px;
+    height: 98%;
+  }
+}
+.swiper-scrollbar-drag {
+  height: 100%;
+  width: 100%;
+  position: relative;
+  background: rgba(0, 0, 0, 0.5);
+  border-radius: 10px;
+  left: 0;
+  top: 0;
+}
+.swiper-scrollbar-cursor-drag {
+  cursor: move;
+}
+.swiper-scrollbar-lock {
+  display: none;
+}

+ 240 - 0
uni_modules/zebra-swiper/modules/thumbs/thumbs.js

@@ -0,0 +1,240 @@
+import {
+	isObject
+} from '../../shared/utils.js';
+// import $ from '../../shared/dom.js';
+
+export default function Thumb({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		thumbs: {
+			swiper: null,
+			multipleActiveThumbs: true,
+			autoScrollOffset: 0,
+			slideThumbActiveClass: 'swiper-slide-thumb-active',
+			thumbsContainerClass: 'swiper-thumbs',
+		},
+	});
+
+	let initialized = false;
+	let swiperCreated = false;
+
+	swiper.thumbs = {
+		swiper: null,
+	};
+
+	function onThumbClick() {
+		const thumbsSwiper = swiper.thumbs.swiper;
+		if (!thumbsSwiper) return;
+		const clickedIndex = thumbsSwiper.clickedIndex;
+		const clickedSlide = thumbsSwiper.clickedSlide;
+		if (clickedSlide && clickedSlide.hasClass(swiper.params.thumbs.slideThumbActiveClass))
+			return;
+		if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
+		let slideToIndex;
+		if (thumbsSwiper.params.loop) {
+			slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);
+		} else {
+			slideToIndex = clickedIndex;
+		}
+		if (swiper.params.loop) {
+			let currentIndex = swiper.activeIndex;
+			if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {
+				swiper.loopFix();
+				// eslint-disable-next-line
+				swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
+				currentIndex = swiper.activeIndex;
+			}
+			const prevIndex = swiper.slides
+				.eq(currentIndex)
+				.prevAll(`[data-swiper-slide-index="${slideToIndex}"]`)
+				.eq(0)
+				.index();
+			const nextIndex = swiper.slides
+				.eq(currentIndex)
+				.nextAll(`[data-swiper-slide-index="${slideToIndex}"]`)
+				.eq(0)
+				.index();
+			if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;
+			else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;
+			else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;
+			else slideToIndex = prevIndex;
+		}
+		swiper.slideTo(slideToIndex);
+	}
+
+	function init() {
+		const {
+			thumbs: thumbsParams
+		} = swiper.params;
+		if (initialized) return false;
+		initialized = true;
+		const SwiperClass = swiper.constructor;
+		if (thumbsParams.swiper instanceof SwiperClass) {
+			swiper.thumbs.swiper = thumbsParams.swiper;
+			Object.assign(swiper.thumbs.swiper.originalParams, {
+				watchSlidesProgress: true,
+				slideToClickedSlide: false,
+			});
+			Object.assign(swiper.thumbs.swiper.params, {
+				watchSlidesProgress: true,
+				slideToClickedSlide: false,
+			});
+		} else if (isObject(thumbsParams.swiper)) {
+			const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
+			Object.assign(thumbsSwiperParams, {
+				watchSlidesProgress: true,
+				slideToClickedSlide: false,
+			});
+			swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
+			swiperCreated = true;
+		}
+		swiper.thumbs.swiper.$el && swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);
+		swiper.thumbs.swiper.on('slideClick', onThumbClick);
+		return true;
+	}
+
+	function update(initial) {
+		const thumbsSwiper = swiper.thumbs.swiper;
+		if (!thumbsSwiper) return;
+
+		const slidesPerView =
+			thumbsSwiper.params.slidesPerView === 'auto' ?
+			thumbsSwiper.slidesPerViewDynamic() :
+			thumbsSwiper.params.slidesPerView;
+
+		const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
+		const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
+		if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
+			let currentThumbsIndex = thumbsSwiper.activeIndex;
+			let newThumbsIndex;
+			let direction;
+			if (thumbsSwiper.params.loop) {
+				if (
+					thumbsSwiper.slides
+					.eq(currentThumbsIndex)
+					.hasClass(thumbsSwiper.params.slideDuplicateClass)
+				) {
+					thumbsSwiper.loopFix();
+					// eslint-disable-next-line
+					thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;
+					currentThumbsIndex = thumbsSwiper.activeIndex;
+				}
+				// Find actual thumbs index to slide to
+				const prevThumbsIndex = thumbsSwiper.slides
+					.eq(currentThumbsIndex)
+					.prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
+					.eq(0)
+					.index();
+				const nextThumbsIndex = thumbsSwiper.slides
+					.eq(currentThumbsIndex)
+					.nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
+					.eq(0)
+					.index();
+				if (typeof prevThumbsIndex === 'undefined') {
+					newThumbsIndex = nextThumbsIndex;
+				} else if (typeof nextThumbsIndex === 'undefined') {
+					newThumbsIndex = prevThumbsIndex;
+				} else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {
+					newThumbsIndex =
+						thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;
+				} else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {
+					newThumbsIndex = nextThumbsIndex;
+				} else {
+					newThumbsIndex = prevThumbsIndex;
+				}
+				direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
+			} else {
+				newThumbsIndex = swiper.realIndex;
+				direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
+			}
+			if (useOffset) {
+				newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
+			}
+			if (
+				thumbsSwiper.visibleSlidesIndexes &&
+				thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0
+			) {
+				if (thumbsSwiper.params.centeredSlides) {
+					if (newThumbsIndex > currentThumbsIndex) {
+						newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
+					} else {
+						newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
+					}
+				} else if (
+					newThumbsIndex > currentThumbsIndex &&
+					thumbsSwiper.params.slidesPerGroup === 1
+				) {
+					// newThumbsIndex = newThumbsIndex - slidesPerView + 1;
+				}
+
+				thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
+			}
+		}
+
+		// Activate thumbs
+		let thumbsToActivate = 1;
+		const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
+
+		if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
+			thumbsToActivate = swiper.params.slidesPerView;
+		}
+
+		if (!swiper.params.thumbs.multipleActiveThumbs) {
+			thumbsToActivate = 1;
+		}
+
+		thumbsToActivate = Math.floor(thumbsToActivate);
+		// thumbsSwiper.slides.removeClass(thumbActiveClass);
+		thumbsSwiper.slides.forEach((item) => {
+			item.addClass(swiper.params.slideThumbsClass);
+			item.removeClass(thumbActiveClass);
+		})
+		if (
+			thumbsSwiper.params.loop ||
+			(thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled)
+		) {
+			for (let i = 0; i < thumbsToActivate; i += 1) {
+				thumbsSwiper.$wrapperEl
+					.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`)
+					.addClass(thumbActiveClass);
+			}
+		} else {
+			for (let i = 0; i < thumbsToActivate; i += 1) {
+				thumbsSwiper.slides[swiper.realIndex + i].addClass(thumbActiveClass);
+			}
+		}
+	}
+
+	on('beforeInit', () => {
+		const {
+			thumbs
+		} = swiper.params;
+		if (!thumbs || !thumbs.swiper) return;
+		init();
+		update(true);
+	});
+	on('slideChange update resize observerUpdate', () => {
+		if (!swiper.thumbs.swiper) return;
+		update();
+	});
+	on('setTransition', (_s, duration) => {
+		const thumbsSwiper = swiper.thumbs.swiper;
+		if (!thumbsSwiper) return;
+		thumbsSwiper.setTransition(duration);
+	});
+	on('beforeDestroy', () => {
+		const thumbsSwiper = swiper.thumbs.swiper;
+		if (!thumbsSwiper) return;
+		if (swiperCreated && thumbsSwiper) {
+			thumbsSwiper.destroy();
+		}
+	});
+
+	Object.assign(swiper.thumbs, {
+		init,
+		update,
+	});
+}

+ 10 - 0
uni_modules/zebra-swiper/modules/thumbs/thumbs.scss

@@ -0,0 +1,10 @@
+.swiper-thumbs {
+
+}
+.swiper-slide-thumb {
+	 opacity: 0.4;
+}
+.swiper-slide-thumb-active {
+    // Styles for active thumb slide
+	 opacity: 1;
+}

+ 319 - 0
uni_modules/zebra-swiper/modules/virtual/virtual.js

@@ -0,0 +1,319 @@
+export default function Virtual({
+	swiper,
+	extendParams,
+	on
+}) {
+	extendParams({
+		virtual: {
+			enabled: false,
+			slides: [],
+			cache: true,
+			renderSlide: null,
+			renderExternal: null,
+			renderExternalUpdate: true,
+			addSlidesBefore: 0,
+			addSlidesAfter: 0,
+		},
+	});
+
+	let cssModeTimeout;
+
+	swiper.virtual = {
+		cache: {},
+		from: undefined,
+		to: undefined,
+		slides: [],
+		offset: 0,
+		slidesGrid: [],
+	};
+
+	function renderSlide(slide, index) {
+		const params = swiper.params.virtual;
+		if (params.cache && swiper.virtual.cache[index]) {
+			return swiper.virtual.cache[index];
+		}
+		// const $slideEl = params.renderSlide ?
+		// 	$(params.renderSlide.call(swiper, slide, index)) :
+		// 	$(
+		// 		`<div class="${swiper.params.slideClass}" data-swiper-slide-index="${index}">${slide}</div>`,
+		// 	);
+		// if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);
+		// if (params.cache) swiper.virtual.cache[index] = $slideEl;
+		// return $slideEl;
+	}
+
+	function onRendered() {
+		swiper.updateSlides();
+		swiper.updateProgress();
+		swiper.updateSlidesClasses();
+		if (swiper.lazy && swiper.params.lazy.enabled) {
+			swiper.lazy.load();
+		}
+	}
+
+	async function update(force) {
+		const {
+			slidesPerView,
+			slidesPerGroup,
+			centeredSlides
+		} = swiper.params;
+		const {
+			addSlidesBefore,
+			addSlidesAfter
+		} = swiper.params.virtual;
+		const {
+			from: previousFrom,
+			to: previousTo,
+			slides,
+			slidesGrid: previousSlidesGrid,
+			offset: previousOffset,
+		} = swiper.virtual;
+		if (!swiper.params.cssMode) {
+			swiper.updateActiveIndex();
+		}
+
+		const activeIndex = swiper.activeIndex || 0;
+
+		let offsetProp;
+		if (swiper.rtlTranslate) offsetProp = 'right';
+		else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
+
+		let slidesAfter;
+		let slidesBefore;
+		if (centeredSlides) {
+			slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
+			slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
+		} else {
+			slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
+			slidesBefore = slidesPerGroup + addSlidesBefore;
+		}
+		const from = Math.max((activeIndex || 0) - slidesBefore, 0);
+		const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);
+		const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
+		Object.assign(swiper.virtual, {
+			from,
+			to,
+			offset,
+			slidesGrid: swiper.slidesGrid,
+		});
+
+		function onRendered() {
+			swiper.updateSlides();
+			swiper.updateProgress();
+			swiper.updateSlidesClasses();
+			if (swiper.lazy && swiper.params.lazy.enabled) {
+				swiper.lazy.load();
+			}
+		}
+		if (previousFrom === from && previousTo === to && !force) {
+			if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
+				swiper.slides.css(offsetProp, `${offset}px`);
+			}
+			swiper.updateProgress();
+			return;
+		}
+		if (swiper.params.virtual.renderExternal) {
+			swiper.params.virtual.renderExternal.call(swiper, {
+				offset,
+				from,
+				to,
+				slides: (function getSlides() {
+					const slidesToRender = [];
+					if (swiper.params.virtual.type == 'keep') {
+						for (let i = 0; i < from; i += 1) {
+							slidesToRender.push("");
+						}
+					}
+					for (let i = from; i <= to; i += 1) {
+						slidesToRender.push(slides[i]);
+					}
+					return slidesToRender;
+				})(),
+			});
+			if (swiper.params.virtual.renderExternalUpdate) {
+				onRendered();
+			}
+			return;
+		}
+		const prependIndexes = [];
+		const appendIndexes = [];
+		if (force) {
+			swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();
+		} else {
+			for (let i = previousFrom; i <= previousTo; i += 1) {
+				if (i < from || i > to) {
+					swiper.virtualList.splice(swiper.virtualList.findIndex((item) => {
+						return item == slides[i]
+					}), 1)
+
+					swiper.virtualIndexList.splice(swiper.virtualIndexList.findIndex((item) => {
+						return item == i
+					}), 1)
+					// swiper.slides[i].virtualShow = false;
+				}
+			}
+		}
+		for (let i = 0; i < slides.length; i += 1) {
+			if (i >= from && i <= to) {
+				if (typeof previousTo === 'undefined' || force) {
+					appendIndexes.push(i);
+				} else {
+					if (i > previousTo) appendIndexes.push(i);
+					if (i < previousFrom) prependIndexes.push(i);
+				}
+			}
+		}
+		// let list = [];
+		appendIndexes.forEach((index) => {
+
+
+			// if (swiper.slides[index]) {
+			// 	swiper.slides[index].virtualShow = true;
+			// } else {
+			swiper.virtualList.push(slides[index]);
+			swiper.virtualIndexList.push(index)
+			// }
+
+			// renderSlide(slides[index], index)
+			// renderSlide(slides[index], index)
+			// swiper.$wrapperEl.append(renderSlide(slides[index], index));
+		});
+		prependIndexes
+			.sort((a, b) => b - a)
+			.forEach((index) => {
+				// swiper.slides[index].virtualShow = true;
+				swiper.virtualList.unshift(slides[index]);
+				swiper.virtualIndexList.unshift(index)
+
+				// swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
+			});
+		swiper.native.emit("input", [swiper.virtualList])
+		onRendered();
+	}
+
+	function appendSlide(slides) {
+		if (typeof slides === 'object' && 'length' in slides) {
+			for (let i = 0; i < slides.length; i += 1) {
+				if (slides[i]) swiper.virtual.slides.push(slides[i]);
+			}
+		} else {
+			swiper.virtual.slides.push(slides);
+		}
+		update(true);
+	}
+
+	function prependSlide(slides) {
+		const activeIndex = swiper.activeIndex;
+		let newActiveIndex = activeIndex + 1;
+		let numberOfNewSlides = 1;
+
+		if (Array.isArray(slides)) {
+			for (let i = 0; i < slides.length; i += 1) {
+				if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
+			}
+			newActiveIndex = activeIndex + slides.length;
+			numberOfNewSlides = slides.length;
+		} else {
+			swiper.virtual.slides.unshift(slides);
+		}
+		if (swiper.params.virtual.cache) {
+			const cache = swiper.virtual.cache;
+			const newCache = {};
+			Object.keys(cache).forEach((cachedIndex) => {
+				const $cachedEl = cache[cachedIndex];
+				const cachedElIndex = $cachedEl.attr('data-swiper-slide-index');
+				if (cachedElIndex) {
+					$cachedEl.attr(
+						'data-swiper-slide-index',
+						parseInt(cachedElIndex, 10) + numberOfNewSlides,
+					);
+				}
+				newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;
+			});
+			swiper.virtual.cache = newCache;
+		}
+		update(true);
+		swiper.slideTo(newActiveIndex, 0);
+	}
+
+	function removeSlide(slidesIndexes) {
+		if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
+		let activeIndex = swiper.activeIndex;
+		if (Array.isArray(slidesIndexes)) {
+			for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
+				swiper.virtual.slides.splice(slidesIndexes[i], 1);
+				if (swiper.params.virtual.cache) {
+					delete swiper.virtual.cache[slidesIndexes[i]];
+				}
+				if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
+				activeIndex = Math.max(activeIndex, 0);
+			}
+		} else {
+			swiper.virtual.slides.splice(slidesIndexes, 1);
+			if (swiper.params.virtual.cache) {
+				delete swiper.virtual.cache[slidesIndexes];
+			}
+			if (slidesIndexes < activeIndex) activeIndex -= 1;
+			activeIndex = Math.max(activeIndex, 0);
+		}
+		update(true);
+		swiper.slideTo(activeIndex, 0);
+	}
+
+	function removeAllSlides() {
+		swiper.virtual.slides = [];
+		if (swiper.params.virtual.cache) {
+			swiper.virtual.cache = {};
+		}
+		update(true);
+		swiper.slideTo(0, 0);
+	}
+
+	on('beforeInit', () => {
+		if (!swiper.params.virtual.enabled) return;
+		swiper.virtual.slides = swiper.params.virtual.slides;
+		swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
+
+		swiper.params.watchSlidesProgress = true;
+		swiper.originalParams.watchSlidesProgress = true;
+		if (!swiper.params.initialSlide) {
+			update();
+		}
+	});
+	// on('beforeUpdate', () => {
+	// 	if (!swiper.params.virtual.enabled) return;
+	// 	let offsetProp;
+	// 	if (swiper.rtlTranslate) offsetProp = 'right';
+	// 	else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
+	// 	swiper.slides.forEach((item, index) => {
+	// 		item.dataSwiperSlideIndex = swiper.virtualIndexList[index];
+	// 		item.css({
+	// 			[offsetProp]: `${swiper.virtual.offset}px`
+	// 		})
+	// 	})
+	// })
+	on('setTranslate', async () => {
+		if (!swiper.params.virtual.enabled) return;
+		if (swiper.params.cssMode && !swiper._immediateVirtual) {
+			clearTimeout(cssModeTimeout);
+			cssModeTimeout = setTimeout(() => {
+				update();
+			}, 100);
+		} else {
+			console.log("update==========")
+			clearTimeout(cssModeTimeout);
+			cssModeTimeout = setTimeout(() => {
+				update();
+			}, 100);
+			// update();
+		}
+	});
+
+	Object.assign(swiper.virtual, {
+		appendSlide,
+		prependSlide,
+		removeSlide,
+		removeAllSlides,
+		update,
+	});
+}

+ 17 - 0
uni_modules/zebra-swiper/modules/virtual/virtual.scss

@@ -0,0 +1,17 @@
+.swiper-virtual.swiper-css-mode {
+  .swiper-wrapper::after {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0;
+    pointer-events: none;
+  }
+  &.swiper-horizontal .swiper-wrapper::after {
+    height: 1px;
+    width: var(--swiper-virtual-size);
+  }
+  &.swiper-vertical .swiper-wrapper::after {
+    width: 1px;
+    height: var(--swiper-virtual-size);
+  }
+}

+ 20 - 0
uni_modules/zebra-swiper/modules/will-change/will-change.js

@@ -0,0 +1,20 @@
+export default function WillChange({
+	swiper,
+	extendParams,
+	on
+}) {
+	on('setTransition', (s, duration) => {
+		if (!swiper.params.willChange) return;
+		if (swiper.params.effect == "slide" || swiper.params.effect == "cube" || swiper.params.effect ==
+			"coverflow" || swiper.params.effect == "panorama") {
+			swiper.$wrapperEl.willChange("transform");
+		}
+	});
+	on('transitionEnd', (s, duration) => {
+		if (!swiper.params.willChange) return;
+		swiper.$wrapperEl.willChange("auto");
+		swiper.slides.forEach((item) => {
+			item.$itemEl.willChange("auto");
+		})
+	});
+}

+ 96 - 0
uni_modules/zebra-swiper/package.json

@@ -0,0 +1,96 @@
+{
+	"name": "@zebra-ui/swiper",
+	"id": "zebra-swiper",
+	"displayName": "zebra-swiper 3D轮播,全面对标swiperjs并实现全端兼容。",
+	"version": "2.2.6",
+	"description": "适配多端的高自定义轮播组件,多种3D效果。全面对标swiperjs。",
+	"main": "index.js",
+	"keywords": [
+        "zebra",
+        "swiper",
+        "轮播",
+        "3D",
+        "banner"
+    ],
+	"repository": "https://github.com/zebra-ui/zebra-uniapp-swiper",
+	"bugs": {
+		"url": "https://github.com/zebra-ui/zebra-uniapp-swiper/issues"
+	},
+	"homepage": "https://github.com/zebra-ui/zebra-uniapp-swiper#readme",
+	"author": "zebra-ui",
+	"license": "ISC",
+	"publishConfig": {
+		"access": "public"
+	},
+	"engines": {
+		"HBuilderX": "^3.1.0"
+	},
+	"dcloudext": {
+		"sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": ""
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "插件不采集任何数据",
+			"permissions": "无"
+		},
+		"npmurl": "https://www.npmjs.com/package/@zebra-ui/swiper",
+		"type": "component-vue"
+	},
+	"uni_modules": {
+		"dependencies": [],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "n"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y",
+					"钉钉": "u",
+					"快手": "y",
+					"飞书": "y",
+					"京东": "u"
+				},
+				"快应用": {
+					"华为": "y",
+					"联盟": "y"
+				}
+			}
+		}
+	}
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно