├── pages
├── index
│ ├── index.json
│ ├── index.wxss
│ ├── index.wxml
│ └── index.js
└── preview-media-desc
│ ├── swiper-limited-load
│ ├── index.wxss
│ ├── index.json
│ ├── index.wxml
│ └── index.js
│ ├── item
│ ├── item-index.json
│ ├── item-index.wxss
│ ├── item-index.wxml
│ └── item-index.js
│ ├── index.json
│ ├── index.wxss
│ ├── index.wxml
│ └── index.js
├── img
└── test.gif
├── sitemap.json
├── .gitignore
├── app.wxss
├── app.json
├── app.js
├── README.md
└── project.config.json
/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {}
3 | }
--------------------------------------------------------------------------------
/img/test.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pengboboer/preview-media-desc/HEAD/img/test.gif
--------------------------------------------------------------------------------
/pages/preview-media-desc/swiper-limited-load/index.wxss:
--------------------------------------------------------------------------------
1 | /* components/swiper-limited-load/index.wxss */
--------------------------------------------------------------------------------
/pages/preview-media-desc/item/item-index.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {}
4 | }
--------------------------------------------------------------------------------
/pages/preview-media-desc/swiper-limited-load/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "componentGenerics": {
4 | "item-view": true
5 | },
6 | "usingComponents": {}
7 | }
--------------------------------------------------------------------------------
/sitemap.json:
--------------------------------------------------------------------------------
1 | {
2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3 | "rules": [{
4 | "action": "allow",
5 | "page": "*"
6 | }]
7 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows
2 | [Dd]esktop.ini
3 | Thumbs.db
4 | $RECYCLE.BIN/
5 |
6 | # macOS
7 | .DS_Store
8 | .fseventsd
9 | .Spotlight-V100
10 | .TemporaryItems
11 | .Trashes
12 |
13 | # Node.js
14 | node_modules/
15 |
--------------------------------------------------------------------------------
/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/index.wxss */
2 | .main{
3 | height: 100%;
4 | width: 100%;
5 | display: flex;
6 | flex-direction: column;
7 | align-items: center;
8 | }
9 |
10 | .btn{
11 | margin-top: 100rpx;
12 | }
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 | .container {
3 | height: 100%;
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | justify-content: space-between;
8 | padding: 200rpx 0;
9 | box-sizing: border-box;
10 | }
11 |
--------------------------------------------------------------------------------
/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pages/preview-media-desc/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "swiper-limited-load": "./swiper-limited-load/index",
4 | "item-view": "./item/item-index"
5 | },
6 | "navigationStyle": "custom",
7 | "navigationBarTextStyle": "white"
8 | }
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index/index",
4 | "pages/preview-media-desc/index"
5 | ],
6 | "window": {
7 | "backgroundTextStyle": "light",
8 | "navigationBarBackgroundColor": "#fff",
9 | "navigationBarTitleText": "Weixin",
10 | "navigationBarTextStyle": "black"
11 | },
12 | "style": "v2",
13 | "sitemapLocation": "sitemap.json"
14 | }
--------------------------------------------------------------------------------
/pages/preview-media-desc/index.wxss:
--------------------------------------------------------------------------------
1 | /* pages/preview-image-video/index.wxss */
2 |
3 | .index-title{
4 | width: 100%;
5 | display: flex;
6 | flex-direction: row;
7 | justify-content: center;
8 | align-items: center;
9 | margin-top: 100rpx;
10 | color: #ffffff;
11 | font-size: 30rpx;
12 | position: fixed;
13 | top: 0;
14 | z-index: 10;
15 | }
16 |
17 | .swiper{
18 | background-color: #000000;
19 | }
--------------------------------------------------------------------------------
/pages/preview-media-desc/swiper-limited-load/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 | // 展示本地存储能力
5 | var logs = wx.getStorageSync('logs') || []
6 | logs.unshift(Date.now())
7 | wx.setStorageSync('logs', logs)
8 |
9 | // 登录
10 | wx.login({
11 | success: res => {
12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId
13 | }
14 | })
15 | // 获取用户信息
16 | wx.getSetting({
17 | success: res => {
18 | if (res.authSetting['scope.userInfo']) {
19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
20 | wx.getUserInfo({
21 | success: res => {
22 | // 可以将 res 发送给后台解码出 unionId
23 | this.globalData.userInfo = res.userInfo
24 |
25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26 | // 所以此处加入 callback 以防止这种情况
27 | if (this.userInfoReadyCallback) {
28 | this.userInfoReadyCallback(res)
29 | }
30 | }
31 | })
32 | }
33 | }
34 | })
35 | },
36 | globalData: {
37 | userInfo: null
38 | }
39 | })
--------------------------------------------------------------------------------
/pages/preview-media-desc/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | module.exports = {
4 | getIndex: function (currentIndex, list) {
5 | if (currentIndex == -1) {
6 | return 1
7 | }
8 |
9 | if (currentIndex == -2) {
10 | return list.length
11 | }
12 |
13 | return currentIndex + 1
14 | }
15 | }
16 |
17 |
18 | {{func.getIndex(currentIndex, list)}}/{{list.length}}
19 |
20 |
39 |
40 |
--------------------------------------------------------------------------------
/pages/preview-media-desc/item/item-index.wxss:
--------------------------------------------------------------------------------
1 | /* pages/preview-image-video/item/item-index.wxss */
2 |
3 | .box{
4 | width: 100%;
5 | height: 100%;
6 | display: flex;
7 | flex-direction: row;
8 | justify-content: center;
9 | align-items: center;
10 | background-color: #000000;
11 | overflow: scroll;
12 | }
13 |
14 | .img-box{
15 | display: flex;
16 | flex-direction: row;
17 | align-items: center;
18 | }
19 |
20 | .img{
21 | width: 100%;
22 | }
23 |
24 | .desc{
25 | width: 100%;
26 | font-size: 30rpx;
27 | color: #ffffff;
28 | position: fixed;
29 | bottom: 0;
30 | padding: 30rpx;
31 | box-sizing: border-box;
32 | background-color: rgba(0,0,0,0.5);
33 | display: -webkit-box;
34 | overflow: hidden;
35 | text-overflow: ellipsis;
36 | word-break: break-all;
37 | white-space: pre-line;
38 | -webkit-box-orient: vertical;
39 | -webkit-line-clamp: 6;
40 | }
41 |
42 | movable-view {
43 | display: flex;
44 | align-items: center;
45 | justify-content: center;
46 | height: 100%;
47 | width: 100%;
48 | color: #fff;
49 | }
50 |
51 | movable-area {
52 | height: 100%;
53 | width: 750rpx;
54 | overflow: hidden;
55 | }
56 |
57 | .video{
58 | width: 100%;
59 | height: 0rpx;
60 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # preview-image-video
2 | ## 微信小程序preview-media带有图片描述
3 |
4 | ### 示例动图
5 | 
6 | ##### 跟微信小程序的wx.prevImage或者wx.prevVideo的基本类似,大体功能类似,体验上稍微有一点点差距吧,但是好在可以显示图片描述
7 | 这里实现了如下功能和细节:
8 | * 支持左右滑动
9 | * 图片双指缩放
10 | * 单击图片返回
11 | * 双击放大缩小
12 | * 图片视频混排
13 | * 显示图片描述
14 |
15 | # 使用方法
16 | * 将pages中的preview-media-desc复制到您的项目中
17 | * 在app.json中注册该page
18 | * 具体可以参照项目目录index中的用法
19 |
20 | ```
21 | app.globalData.previewInfo = {
22 | list: [
23 | {
24 | picUrl: "",
25 | video: "",
26 | desc: ""
27 | }
28 | ],
29 | current: 0
30 | }
31 |
32 | wx.navigateTo({
33 | url: '../../pages/preview-media-desc/index',
34 | })
35 | ```
36 | # 特别说明:
37 | * 如果你需要使用视频,那么将会涉及到一个视频的宽高比例问题,这里我使用wx.getImageInfo()来获取视频封面的宽高比,从而知道video容器的高度。使用wx.getImageInfo()来获取网络图片的宽高必须配置download域名,否则最好你的接口能直接返回video的宽高信息,然后通过屏幕宽度计算出video容器的高度,这样显示的视频就会是按比例铺满整个手机的宽度。
38 | * 在preview-media-desc/item/item-index中可找到对应的代码
39 |
40 |
41 | [csdn原文:微信小程序可添加图片描述的wx.previewMedia](https://blog.csdn.net/pengbo6665631/article/details/108768510)
42 | [小程序交流专区:大图预览下添加图片描述](https://developers.weixin.qq.com/community/develop/article/doc/00080c2ed6006805050bd275155c13)
43 | ### 如果对你有帮助,动动小手给个star,谢谢。
44 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件",
3 | "packOptions": {
4 | "ignore": []
5 | },
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": true,
9 | "postcss": true,
10 | "preloadBackgroundData": false,
11 | "minified": true,
12 | "newFeature": true,
13 | "coverView": true,
14 | "autoAudits": false,
15 | "showShadowRootInWxmlPanel": true,
16 | "scopeDataCheck": false,
17 | "checkInvalidKey": true,
18 | "checkSiteMap": true,
19 | "uploadWithSourceMap": true,
20 | "babelSetting": {
21 | "ignore": [],
22 | "disablePlugins": [],
23 | "outputPath": ""
24 | },
25 | "useCompilerModule": true,
26 | "userConfirmedUseCompilerModuleSwitch": false
27 | },
28 | "compileType": "miniprogram",
29 | "libVersion": "2.13.0",
30 | "appid": "wxf6bd41fffc7e1fc8",
31 | "projectname": "preview-image-video",
32 | "debugOptions": {
33 | "hidedInDevtools": []
34 | },
35 | "isGameTourist": false,
36 | "simulatorType": "wechat",
37 | "simulatorPluginLibVersion": {},
38 | "condition": {
39 | "search": {
40 | "current": -1,
41 | "list": []
42 | },
43 | "conversation": {
44 | "current": -1,
45 | "list": []
46 | },
47 | "game": {
48 | "currentL": -1,
49 | "list": []
50 | },
51 | "miniprogram": {
52 | "current": -1,
53 | "list": []
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/pages/preview-media-desc/item/item-index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
40 | {{item.desc}}
41 |
--------------------------------------------------------------------------------
/pages/preview-media-desc/item/item-index.js:
--------------------------------------------------------------------------------
1 | // pages/preview-image-video/item/item-index.js
2 | Component({
3 |
4 | observers: {
5 | 'currentIndex': function(index) {
6 | let that = this
7 | // 这块代码的目的是为了获取视频的比例,这里是通过视频封面图片来获取的
8 | // 如果你们后台有直接返回了宽高比例,这里可以直接计算真是的video容器的高度
9 | let item = that.data.item
10 | if (index == item.index) {
11 | if (item.videoUrl != null && item.videoUrl != "") {
12 | // 如果项目配置了download域名,则可直接用此代码
13 | // 否则看你的接口是否会返回视频的宽高,然后来计算video容器的宽高
14 | // wx.getImageInfo({
15 | // src: item.picUrl,
16 | // success: function(res){
17 | // console.log(res)
18 | // let scale = res.height / res.width
19 | // let videoHeight = wx.getSystemInfoSync().windowWidth * scale
20 | // that.setData({
21 | // videoHeight: videoHeight
22 | // })
23 | // },
24 | // fail: function(res){
25 | // console.log(res)
26 | // },
27 | // })
28 |
29 |
30 | // 这里暂时给视频比例弄成个4:3吧, 高:宽 1000: 750
31 | // 你们在使用时要根据情况设置宽高比
32 | that.setData({
33 | videoHeight: 1000 / 750 * wx.getSystemInfoSync().windowWidth
34 | })
35 |
36 | }
37 | }
38 | }
39 | },
40 | /**
41 | * 组件的属性列表
42 | */
43 | properties: {
44 | item: {
45 | type: Object,
46 | value: null
47 | },
48 | scaleItem: {
49 | type: Number,
50 | value: 1.0
51 | },
52 | swiperHeight: {
53 | type: Number,
54 | value: 0
55 | },
56 | currentIndex: {
57 | type: Number,
58 | value: 0
59 | }
60 | },
61 |
62 | /**
63 | * 组件的初始数据
64 | */
65 | data: {
66 |
67 | },
68 |
69 | /**
70 | * 组件的方法列表
71 | */
72 | methods: {
73 | touchStart (e) {
74 | this.triggerEvent("touchStart")
75 | },
76 |
77 | touchMove (e) {
78 | this.triggerEvent("touchMove")
79 | },
80 |
81 | touchEnd (e) {
82 | this.triggerEvent("touchEnd")
83 | },
84 |
85 | onClickBox (e) {
86 | this.triggerEvent("onClickBox", e.timeStamp)
87 | },
88 |
89 | movableChange (e) {
90 | this.triggerEvent("movableChange",e.detail.source)
91 | },
92 |
93 | onScale (e) {
94 | this.triggerEvent("onScale", e.detail.scale)
95 | }
96 | }
97 | })
98 |
--------------------------------------------------------------------------------
/pages/index/index.js:
--------------------------------------------------------------------------------
1 | // pages/index/index.js
2 | const app = getApp()
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 |
10 | },
11 |
12 | onClickBtn (e) {
13 | let index = e.currentTarget.dataset.index
14 | if (index == 0) {
15 | this.prevImage()
16 | }
17 |
18 | if (index == 1) {
19 | this.prevMedia()
20 | }
21 | },
22 |
23 | prevImage() {
24 | app.globalData.previewInfo = {
25 | list: [
26 | {
27 | picUrl: "https://pic.008box.com/picture/20200918104001_2348.jpg",
28 | desc: "这是一个微博长图"
29 | },
30 | {
31 | picUrl: "https://pic.008box.com/test/20200923152850_1409.jpg",
32 | desc: "这里是图片描述哦,这里是图片描述哦,这里是图片描述哦,这里是图片描述哦"
33 | },
34 | {
35 | picUrl: "https://pic.008box.com/test/20200923152850_5256.jpg",
36 | desc: "这里是图片描述哦,这里是图片描述哦,这里是图片描述哦,这里是图片描述哦"
37 | },
38 | {
39 | picUrl: "https://pic.008box.com/test/20200923152850_1958.jpg",
40 | desc: ""
41 | }
42 | ],
43 | current: 3
44 | }
45 |
46 | wx.navigateTo({
47 | url: '../../pages/preview-media-desc/index',
48 | })
49 | },
50 |
51 | prevMedia() {
52 | app.globalData.previewInfo = {
53 | list: [
54 | {
55 | picUrl: " https://pic.008box.com/test/20200923152453_9874.jpeg",
56 | videoUrl: "https://pic.008box.com/test/20200923152451_0443.mp4",
57 | desc: "刘皇叔蹦迪......"
58 | },
59 | {
60 | picUrl: "https://pic.008box.com/test/20200923164811_2537.jpeg",
61 | videoUrl: "https://pic.008box.com/test/20200923164808_5195.mp4",
62 | desc: "你是我惊鸿一瞥的春光,也是我永恒追逐的星辰大海。"
63 | },
64 | {
65 | picUrl: "https://pic.008box.com/test/20200923152850_3681.jpg",
66 | desc: "我以为你是那一场春雨,谁知你是大雨之前的电闪雷鸣。"
67 | },
68 | {
69 | picUrl: "https://pic.008box.com/test/20200923150733_4419.jpeg",
70 | videoUrl:"https://pic.008box.com/test/20200923150731_6834.mp4",
71 | desc: "这是一个蜘蛛侠视频"
72 | }
73 | ],
74 | current: 0
75 | }
76 |
77 | wx.navigateTo({
78 | url: '../../pages/preview-media-desc/index',
79 | })
80 | },
81 |
82 | /**
83 | * 生命周期函数--监听页面加载
84 | */
85 | onLoad: function (options) {
86 |
87 | },
88 |
89 | /**
90 | * 生命周期函数--监听页面初次渲染完成
91 | */
92 | onReady: function () {
93 |
94 | },
95 |
96 | /**
97 | * 生命周期函数--监听页面显示
98 | */
99 | onShow: function () {
100 |
101 | },
102 |
103 | /**
104 | * 生命周期函数--监听页面隐藏
105 | */
106 | onHide: function () {
107 |
108 | },
109 |
110 | /**
111 | * 生命周期函数--监听页面卸载
112 | */
113 | onUnload: function () {
114 |
115 | },
116 |
117 | /**
118 | * 页面相关事件处理函数--监听用户下拉动作
119 | */
120 | onPullDownRefresh: function () {
121 |
122 | },
123 |
124 | /**
125 | * 页面上拉触底事件的处理函数
126 | */
127 | onReachBottom: function () {
128 |
129 | },
130 |
131 | /**
132 | * 用户点击右上角分享
133 | */
134 | onShareAppMessage: function () {
135 |
136 | }
137 | })
--------------------------------------------------------------------------------
/pages/preview-media-desc/index.js:
--------------------------------------------------------------------------------
1 | // pages/preview-image-video/index.js
2 | const app = getApp()
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | list: [],
10 | scaleList: [],
11 | scaleTempList: [],
12 | current: 0,
13 | currentIndex: 0,
14 | swiperDuration: "0",
15 |
16 | lastTapTime: 0, // 最后一次单击事件点击发生时间
17 | singleClickFunc: null,
18 | isFingerMoved: false,
19 | },
20 |
21 | swiperChange (e) {
22 | let current = e.detail.current
23 | this.setData({
24 | currentIndex: current
25 | })
26 | },
27 |
28 | touchStart (e) {
29 | this.data.isFingerMoved = false
30 | },
31 |
32 | touchMove (e) {
33 | this.data.isFingerMoved = true
34 | },
35 |
36 | touchEnd (e) {
37 | let that = this
38 | let currentIndex = that.data.currentIndex
39 | let scaleTemp = that.data.scaleTempList[currentIndex]
40 | let scaleChange = "scaleList[" + currentIndex + "]"
41 | // 仿微信自带prevImage 缩放到最小后恢复原样, 超过3倍后显示3倍
42 | if (scaleTemp < 1 || scaleTemp > 3) {
43 | that.setData({
44 | [scaleChange]: scaleTemp < 1 ? 1 : 3
45 | })
46 | }
47 | },
48 |
49 | onClickBox (e) {
50 | console.log(e)
51 | let that = this
52 | let curTime = e.detail
53 | let lastTime = that.data.lastTapTime
54 | let currentIndex = that.data.currentIndex
55 | let scaleTemp = that.data.scaleTempList[currentIndex]
56 | // 双击
57 | if (curTime - lastTime < 300) {
58 | clearTimeout(that.data.singleClickFunc)
59 | let scaleChange = "scaleList[" + currentIndex + "]"
60 | that.setData({
61 | [scaleChange]: scaleTemp == 1 ? 3 : 1
62 | })
63 | } else {
64 | if (scaleTemp < 1.1 && !that.data.isFingerMoved) {
65 | that.data.singleClickFunc = setTimeout(function(){
66 | wx.navigateBack({
67 | delta: 1
68 | })
69 | }, 350)
70 | }
71 | }
72 | that.data.lastTapTime = curTime
73 | },
74 |
75 | movableChange (e) {
76 | console.log(e)
77 | let that = this
78 | let currentIndex = that.data.currentIndex
79 | // 这个好像是微信的bug,经常触发不了out-of-bounds,也是头疼
80 | if (e.detail == "out-of-bounds") {
81 | if(currentIndex == 0 || currentIndex == that.data.list.length - 1) {
82 | return
83 | }
84 | // 左边界
85 | if (e.detail.x == 0) {
86 | that.setData({
87 | current: that.data.currentIndex - 1
88 | })
89 | // 右边界
90 | } else {
91 | that.setData({
92 | current: that.data.currentIndex + 1
93 | })
94 | }
95 | }
96 | },
97 |
98 | onScale (e) {
99 | let scaleTemp = "scaleTempList[" + this.data.currentIndex + "]"
100 | this.setData({
101 | [scaleTemp]: e.detail
102 | })
103 | },
104 |
105 | /**
106 | * 生命周期函数--监听页面加载
107 | */
108 | onLoad: function (options) {
109 | let that = this
110 | that.setData({
111 | swiperHeight: wx.getSystemInfoSync().windowHeight,
112 | })
113 |
114 | let info = app.globalData.previewInfo
115 | app.globalData.previewInfo = null
116 |
117 | let scaleList = []
118 | let list = info.list.map(function(item, index){
119 | item.index = index
120 | scaleList.push(1.0)
121 | return item
122 | })
123 |
124 | that.setData({
125 | list: list,
126 | scaleList: scaleList,
127 | scaleTempList: scaleList
128 | })
129 |
130 | that.setData({
131 | current: info.current
132 | })
133 | that.setData({
134 | swiperDuration: '250'
135 | })
136 | },
137 |
138 | /**
139 | * 生命周期函数--监听页面初次渲染完成
140 | */
141 | onReady: function () {
142 |
143 | },
144 |
145 | /**
146 | * 生命周期函数--监听页面显示
147 | */
148 | onShow: function () {
149 |
150 | },
151 |
152 | /**
153 | * 生命周期函数--监听页面隐藏
154 | */
155 | onHide: function () {
156 |
157 | },
158 |
159 | /**
160 | * 生命周期函数--监听页面卸载
161 | */
162 | onUnload: function () {
163 |
164 | },
165 |
166 | /**
167 | * 页面相关事件处理函数--监听用户下拉动作
168 | */
169 | onPullDownRefresh: function () {
170 |
171 | },
172 |
173 | /**
174 | * 页面上拉触底事件的处理函数
175 | */
176 | onReachBottom: function () {
177 |
178 | },
179 |
180 | /**
181 | * 用户点击右上角分享
182 | */
183 | onShareAppMessage: function () {
184 |
185 | }
186 | })
--------------------------------------------------------------------------------
/pages/preview-media-desc/swiper-limited-load/index.js:
--------------------------------------------------------------------------------
1 | // components/swiper-limited-load/index.js
2 | const START = 0
3 | const END = 2
4 | const SWIPER_LENGTH = 3
5 |
6 | Component({
7 | observers: {
8 | 'current': function(index) {
9 | let that = this
10 | let current = index % SWIPER_LENGTH
11 | let {swiperIndex, swiperList} = that.data
12 | if (swiperList.length == 0) {
13 | return
14 | }
15 | // 如果change后还是之前的那一个item,直接return
16 | if (current == swiperIndex && swiperList[swiperIndex].index == index) {
17 | return
18 | }
19 | that.init(index)
20 | // 如果change之后还是当前的current,比如之前是1、点击后是4 之前是2、点击后是5之类
21 | // 那么不会走swiperChange的change方法,需要我们手动去给它加一个current,然后传出去
22 | if (current == swiperIndex) {
23 | that.triggerEvent("change", {source: "",current: index})
24 | }
25 | },
26 |
27 | 'list': function(list) {
28 | this.init(this.data.swiperIndex)
29 | }
30 | },
31 | /**
32 | * 组件的属性列表
33 | */
34 | properties: {
35 | swiperHeight: {
36 | type: Number,
37 | value: 0
38 | },
39 | list: {
40 | type: Array,
41 | value: []
42 | },
43 | scaleList: {
44 | type: Array,
45 | value: []
46 | },
47 | scaleTempList: {
48 | type: Array,
49 | value: []
50 | },
51 | current: {
52 | type: Number,
53 | value: 0
54 | },
55 | swiperDuration: {
56 | type: String,
57 | value: "250"
58 | },
59 | currentSelectIndex: {
60 | type: Number,
61 | value: 0
62 | }
63 | },
64 |
65 | /**
66 | * 组件的初始数据
67 | */
68 | data: {
69 | // 滑动到的位置
70 | swiperIndex: 0,
71 | // 此值控制swiper的位置
72 | swiperCurrent: 0,
73 | // 值为0禁止切换动画
74 | swiperDuration: "250",
75 | // 当前swiper渲染的items
76 | swiperList: [],
77 |
78 | list: [],
79 | },
80 |
81 | /**
82 | * 组件的方法列表
83 | */
84 | methods: {
85 |
86 | touchStart (e) {
87 | this.triggerEvent("touchStart")
88 | },
89 |
90 | touchMove (e) {
91 | this.triggerEvent("touchMove")
92 | },
93 |
94 | touchEnd (e) {
95 | this.triggerEvent("touchEnd")
96 | },
97 |
98 | onClickBox (e) {
99 | this.triggerEvent("onClickBox", e.detail)
100 | },
101 |
102 | movableChange (e) {
103 | this.triggerEvent("movableChange", e.detail)
104 | },
105 |
106 | onScale (e) {
107 | this.triggerEvent("onScale", e.detail)
108 | },
109 |
110 | init (defaulaIndex) {
111 | let that = this
112 | let list = that.data.list
113 | if (list == null || list.length == 0) {
114 | return
115 | }
116 | // 默认显示的index
117 | let current = defaulaIndex % SWIPER_LENGTH
118 | that.setData({
119 | swiperList: that.getInitSwiperList(list, defaulaIndex),
120 | swiperIndex: current,
121 | swiperCurrent: current,
122 | })
123 |
124 | },
125 |
126 |
127 | swiperChange: function (e) {
128 | let that = this
129 |
130 | let current = e.detail.current
131 | let lastIndex = that.data.swiperIndex
132 | let currentItem = that.data.swiperList[current]
133 | console.log("我看", lastIndex)
134 | console.log(that.data.swiperList)
135 | console.log(that.data.list)
136 |
137 | let info = {}
138 | info.source = e.detail.source
139 | // 如果是滑到了左边界,弹回去
140 | if (currentItem.isFirstPlaceholder) {
141 | info.current = -1
142 | that.triggerEvent("change", info)
143 | that.setData({
144 | swiperCurrent: lastIndex
145 | })
146 | return
147 | }
148 | // 如果滑到了右边界,弹回去
149 | if (currentItem.isLastPlaceholder) {
150 | info.current = -2
151 | that.triggerEvent("change", info)
152 | that.setData({
153 | swiperCurrent: lastIndex
154 | })
155 | console.log("到右边界了", info)
156 | return
157 | }
158 |
159 | // 正向滑动,到下一个的时候
160 | // 是正向衔接
161 | let isLoopPositive = current == START && lastIndex == END
162 | if (current - lastIndex == 1 || isLoopPositive) {
163 | let swiperChangeItem = "swiperList[" + that.getNextSwiperChangeIndex(current) + "]"
164 | that.setData({
165 | [swiperChangeItem]: that.getNextSwiperNeedItem(currentItem, that.data.list)
166 | })
167 | }
168 |
169 | // 反向滑动,到上一个的时候
170 | // 是反向衔接
171 | var isLoopNegative = current == END && lastIndex == START
172 | if (lastIndex - current == 1 || isLoopNegative) {
173 | let swiperChangeItem = "swiperList[" + that.getLastSwiperChangeIndex(current) + "]"
174 | that.setData({
175 | [swiperChangeItem]: that.getLastSwiperNeedItem(currentItem, that.data.list)
176 | })
177 | }
178 |
179 | info.current = currentItem.index
180 | that.triggerEvent("change", info)
181 |
182 | // 记录滑过来的位置,此值对于下一次滑动的计算很重要
183 | that.data.swiperIndex = current
184 | },
185 |
186 |
187 |
188 |
189 | /**
190 | * 获取初始化的swiperList
191 | */
192 | getInitSwiperList : function (list, defaultIndex) {
193 | let that = this
194 | let swiperList = []
195 | for (let i = 0; i < 3; i++) {
196 | swiperList.push({})
197 | }
198 | let current = defaultIndex % 3
199 | let currentItem = list[defaultIndex]
200 | swiperList[current] = currentItem
201 | swiperList[that.getLastSwiperChangeIndex(current)] = that.getLastSwiperNeedItem(currentItem, list)
202 | swiperList[that.getNextSwiperChangeIndex(current)] = that.getNextSwiperNeedItem(currentItem, list)
203 | // console.log(swiperList)
204 | return swiperList;
205 | },
206 | /**
207 | * 获取swiperList中current上一个的index
208 | */
209 | getLastSwiperChangeIndex : function (current) {
210 | return current > START ? current - 1 : END
211 | },
212 | /**
213 | * 获取swiperLit中current下一个的index
214 | */
215 | getNextSwiperChangeIndex : function (current) {
216 | return current < END ? current + 1 : START
217 | },
218 | /**
219 | * 获取上一个要替换的list中的item
220 | */
221 | getLastSwiperNeedItem : function (currentItem, list) {
222 | let listNeedIndex = currentItem.index - 1
223 | let item = listNeedIndex == -1 ? { isFirstPlaceholder: true } : list[listNeedIndex]
224 | return item
225 | },
226 | /**
227 | * 获取下一个要替换的list中的item
228 | */
229 | getNextSwiperNeedItem : function (currentItem, list) {
230 | let listNeedIndex = currentItem.index + 1
231 | let item = listNeedIndex == list.length ? { isLastPlaceholder: true } : list[listNeedIndex]
232 | return item
233 | }
234 |
235 | }
236 | })
237 |
--------------------------------------------------------------------------------