Browse Source

工单详情图片展示

miaofuhao 7 years ago
parent
commit
d56b0e5d9c
4 changed files with 920 additions and 34 deletions
  1. 215 34
      WebChat/html/gongDanDetail.html
  2. 1 0
      WebChat/html/myTouSu.html
  3. 382 0
      WebChat/js/mui.previewimage.js
  4. 322 0
      WebChat/js/mui.zoom.js

+ 215 - 34
WebChat/html/gongDanDetail.html

@@ -55,6 +55,201 @@
55 55
 			.detail_list div{
56 56
 				margin-top: 5px;
57 57
 			}
58
+			p img {
59
+				max-width: 100%;
60
+				height: auto;
61
+			}
62
+			
63
+			.img-box {
64
+				float: left;
65
+				width: 20%;
66
+				height:60px;
67
+				margin: 2%;
68
+				text-align: center;
69
+			}
70
+			.img-box img{
71
+				width: 100%;
72
+				height: 100%;
73
+			}
74
+			
75
+			.image-list {
76
+				display: none;
77
+				overflow: hidden;
78
+			}
79
+			.mui-preview-image.mui-fullscreen {
80
+				position: fixed;
81
+				z-index: 20;
82
+				background-color: #000;
83
+			}
84
+			.mui-preview-header,
85
+			.mui-preview-footer {
86
+				position: absolute;
87
+				width: 100%;
88
+				left: 0;
89
+				z-index: 10;
90
+			}
91
+			.mui-preview-header {
92
+				height: 44px;
93
+				top: 0;
94
+			}
95
+			.mui-preview-footer {
96
+				height: 50px;
97
+				bottom: 0px;
98
+			}
99
+			.mui-preview-header .mui-preview-indicator {
100
+				display: block;
101
+				line-height: 25px;
102
+				color: #fff;
103
+				text-align: center;
104
+				margin: 15px auto 4;
105
+				width: 70px;
106
+				background-color: rgba(0, 0, 0, 0.4);
107
+				border-radius: 12px;
108
+				font-size: 16px;
109
+			}
110
+			.mui-preview-image {
111
+				display: none;
112
+				-webkit-animation-duration: 0.5s;
113
+				animation-duration: 0.5s;
114
+				-webkit-animation-fill-mode: both;
115
+				animation-fill-mode: both;
116
+			}
117
+			.mui-preview-image.mui-preview-in {
118
+				-webkit-animation-name: fadeIn;
119
+				animation-name: fadeIn;
120
+			}
121
+			.mui-preview-image.mui-preview-out {
122
+				background: none;
123
+				-webkit-animation-name: fadeOut;
124
+				animation-name: fadeOut;
125
+			}
126
+			.mui-preview-image.mui-preview-out .mui-preview-header,
127
+			.mui-preview-image.mui-preview-out .mui-preview-footer {
128
+				display: none;
129
+			}
130
+			.mui-zoom-scroller {
131
+				position: absolute;
132
+				display: -webkit-box;
133
+				display: -webkit-flex;
134
+				display: flex;
135
+				-webkit-box-align: center;
136
+				-webkit-align-items: center;
137
+				align-items: center;
138
+				-webkit-box-pack: center;
139
+				-webkit-justify-content: center;
140
+				justify-content: center;
141
+				left: 0;
142
+				right: 0;
143
+				bottom: 0;
144
+				top: 0;
145
+				width: 100%;
146
+				height: 100%;
147
+				margin: 0;
148
+				-webkit-backface-visibility: hidden;
149
+			}
150
+			.mui-zoom {
151
+				-webkit-transform-style: preserve-3d;
152
+				transform-style: preserve-3d;
153
+			}
154
+			.mui-slider .mui-slider-group .mui-slider-item img {
155
+				width: auto;
156
+				height: auto;
157
+				max-width: 100%;
158
+				max-height: 100%;
159
+			}
160
+			.mui-android-4-1 .mui-slider .mui-slider-group .mui-slider-item img {
161
+				width: 100%;
162
+			}
163
+			.mui-android-4-1 .mui-slider.mui-preview-image .mui-slider-group .mui-slider-item {
164
+				display: inline-table;
165
+			}
166
+			.mui-android-4-1 .mui-slider.mui-preview-image .mui-zoom-scroller img {
167
+				display: table-cell;
168
+				vertical-align: middle;
169
+			}
170
+			.mui-preview-loading {
171
+				position: absolute;
172
+				width: 100%;
173
+				height: 100%;
174
+				top: 0;
175
+				left: 0;
176
+				display: none;
177
+			}
178
+			.mui-preview-loading.mui-active {
179
+				display: block;
180
+			}
181
+			.mui-preview-loading .mui-spinner-white {
182
+				position: absolute;
183
+				top: 50%;
184
+				left: 50%;
185
+				margin-left: -25px;
186
+				margin-top: -25px;
187
+				height: 50px;
188
+				width: 50px;
189
+			}
190
+			.mui-preview-image img.mui-transitioning {
191
+				-webkit-transition: -webkit-transform 0.5s ease, opacity 0.5s ease;
192
+				transition: transform 0.5s ease, opacity 0.5s ease;
193
+			}
194
+			@-webkit-keyframes fadeIn {
195
+				0% {
196
+					opacity: 0;
197
+				}
198
+				100% {
199
+					opacity: 1;
200
+				}
201
+			}
202
+			@keyframes fadeIn {
203
+				0% {
204
+					opacity: 0;
205
+				}
206
+				100% {
207
+					opacity: 1;
208
+				}
209
+			}
210
+			@-webkit-keyframes fadeOut {
211
+				0% {
212
+					opacity: 1;
213
+				}
214
+				100% {
215
+					opacity: 0;
216
+				}
217
+			}
218
+			@keyframes fadeOut {
219
+				0% {
220
+					opacity: 1;
221
+				}
222
+				100% {
223
+					opacity: 0;
224
+				}
225
+			}
226
+			p img {
227
+				max-width: 100%;
228
+				height: auto;
229
+			}
230
+			.BTS ul{
231
+				overflow: hidden;
232
+			}
233
+			.BTS ul li{
234
+				float: left;
235
+				
236
+			}
237
+			.BTS ul li a{
238
+				
239
+			}
240
+			.btn_agree{
241
+				text-align: center;
242
+				width: 80%;
243
+				font-size: 14px !important;
244
+				margin: 10px 10%;
245
+				height: 30px;
246
+				line-height: 4px !important;
247
+				border: 1px solid #007aff;
248
+				color: #FFFFFF;
249
+				-moz-border-radius: 5px; /* Firefox */ 
250
+				-webkit-border-radius: 5px; /* Safari 和 Chrome */
251
+				border-radius: 5px; /* Opera 10.5+, 以及使用了IE-CSS3的IE浏览器 */
252
+			}
58 253
 		</style>
59 254
 	</head>
60 255
 
@@ -72,7 +267,7 @@
72 267
 					<p class='order_content'></p>
73 268
 					<p class='order_HandleContent'></p>
74 269
 				</li>
75
-				<li class="mui-table-view-cell detail_list">
270
+				<div class="mui-table-view-cell detail_list">
76 271
 					<div class="clearFix">
77 272
 						<p class="mui-pull-left"><i class="iconfont icon-dizhi icon_right"></i>事件地址:</p>
78 273
 						<p class="mui-pull-right address"></p>
@@ -93,6 +288,10 @@
93 288
 						<p class="mui-pull-left"><i class="iconfont icon-daichuli icon_right"></i>提交时间:</p>
94 289
 						<p class="mui-pull-right order_time"></p>
95 290
 					</div>
291
+					<!--图片展示-->
292
+					<div class="mui-table-view">
293
+						<div id='image-list' class="row image-list"></div>
294
+					</div>
96 295
 					<h4 class="gdgz">工单跟踪信息</h4>
97 296
 				</li>
98 297
 				<li class="mui-table-view-cell">
@@ -107,39 +306,6 @@
107 306
 								
108 307
 							</div>
109 308
 						</li>-->
110
-						<!--<li class="layui-timeline-item">
111
-							<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
112
-							<div class="layui-timeline-content layui-text">
113
-								<h3 class="layui-timeline-title">2017-08-20 12:00:00 大傻子 完成此工单</h3>
114
-								<p>操作人:大傻子</p>
115
-								<p>操作人电话:123456789120</p>
116
-								<p>备注信息:备注不要太多 麻烦 懂的么</p>
117
-							</div>
118
-						</li>-->
119
-						<!--<li class="layui-timeline-item">
120
-							<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
121
-							<div class="layui-timeline-content layui-text">
122
-								<h3 class="layui-timeline-title">2017-08-20 12:00:00 大傻子 完成此工单</h3>
123
-								<p>操作人:大傻子</p>
124
-								<p>操作人电话:123456789120</p>
125
-								<p>备注信息:备注不要太多 麻烦 懂的么</p>
126
-							</div>
127
-						</li>-->
128
-						<!--<li class="layui-timeline-item">
129
-							<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
130
-							<div class="layui-timeline-content layui-text">
131
-								<h3 class="layui-timeline-title">2017-08-20 12:00:00 大傻子 完成此工单</h3>
132
-								<p>操作人:大傻子</p>
133
-								<p>操作人电话:123456789120</p>
134
-								<p>备注信息:备注不要太多 麻烦 懂的么</p>
135
-							</div>
136
-						</li>-->
137
-						 <!--<li class="layui-timeline-item">
138
-						    <i class="layui-icon layui-timeline-axis">&#xe63f;</i>
139
-						    <div class="layui-timeline-content layui-text">
140
-						      <div class="layui-timeline-title">过去</div>
141
-						    </div>
142
-						   </li>-->
143 309
 					</ul>
144 310
 
145 311
 				</li>
@@ -151,11 +317,14 @@
151 317
 		<script src="../js/zepto.js"></script>
152 318
         <script src="../Script/Common/huayi.config.js"></script>
153 319
         <script src="../Script/Common/huayi.http.js"></script>
320
+        <script src="../js/mui.zoom.js"></script>
321
+		<script src="../js/mui.previewimage.js"></script>
154 322
 		<script type="text/javascript">
155 323
 			mui.init()
156 324
 			var openid = helper.cookies.get("openid");
157 325
 			var id=helper.request.queryString("id");
158 326
 			console.log(id);
327
+			mui.previewImage();
159 328
 			$.ajax({
160 329
 				type:"get",
161 330
 				url:huayi.config.callcenter_url + 'WxLogin/GetWorkOrder',
@@ -207,6 +376,18 @@
207 376
 							'</div>'+
208 377
 						'</li>').appendTo('.time_line')
209 378
 					})
379
+					//图片展示
380
+					if(conDetail.File) {
381
+						$(conDetail.File).each(function(i, n) {
382
+							if(n.F_FileType == '.jpg'&&n.F_FileType == '.png') {
383
+								$('<div class="img-box"><img src="' + n.F_FileUrl + '" alt="" class="image-item" data-preview-src="" data-preview-group="1" /><div>').appendTo("#image-list");
384
+								$(".image-list").show();
385
+							} else if(n.F_FileType == '.docx') {
386
+								mui.toast('猜猜我是谁')
387
+							}
388
+
389
+						})
390
+					}
210 391
 					
211 392
 				}
212 393
 			});

+ 1 - 0
WebChat/html/myTouSu.html

@@ -379,6 +379,7 @@
379 379
                         //		  			$("#userResult").val('');
380 380
                         $('#detail_address').val('');
381 381
                         $('input[name="secret"][value="0"]').prop("checked", "checked");
382
+                        window.location.reload();
382 383
                     }
383 384
                 }
384 385
             });

+ 382 - 0
WebChat/js/mui.previewimage.js

@@ -0,0 +1,382 @@
1
+(function($, window) {
2
+
3
+	var template = '<div id="{{id}}" class="mui-slider mui-preview-image mui-fullscreen"><div class="mui-preview-header">{{header}}</div><div class="mui-slider-group"></div><div class="mui-preview-footer mui-hidden">{{footer}}</div><div class="mui-preview-loading"><span class="mui-spinner mui-spinner-white"></span></div></div>';
4
+	var itemTemplate = '<div class="mui-slider-item mui-zoom-wrapper {{className}}"><div class="mui-zoom-scroller"><img src="{{src}}" data-preview-lazyload="{{lazyload}}" style="{{style}}" class="mui-zoom"></div></div>';
5
+	var defaultGroupName = '__DEFAULT';
6
+	var div = document.createElement('div');
7
+	var imgId = 0;
8
+	var PreviewImage = function(options) {
9
+		this.options = $.extend(true, {
10
+			id: '__MUI_PREVIEWIMAGE',
11
+			zoom: true,
12
+			header: '<span class="mui-preview-indicator"></span>',
13
+			footer: ''
14
+		}, options || {});
15
+		this.init();
16
+		this.initEvent();
17
+	};
18
+	var proto = PreviewImage.prototype;
19
+	proto.init = function() {
20
+		var options = this.options;
21
+		var el = document.getElementById(this.options.id);
22
+		if (!el) {
23
+			div.innerHTML = template.replace(/\{\{id\}\}/g, this.options.id).replace('{{header}}', options.header).replace('{{footer}}', options.footer);
24
+			document.body.appendChild(div.firstElementChild);
25
+			el = document.getElementById(this.options.id);
26
+		}
27
+
28
+		this.element = el;
29
+		this.scroller = this.element.querySelector($.classSelector('.slider-group'));
30
+		this.indicator = this.element.querySelector($.classSelector('.preview-indicator'));
31
+		this.loader = this.element.querySelector($.classSelector('.preview-loading'));
32
+		if (options.footer) {
33
+			this.element.querySelector($.classSelector('.preview-footer')).classList.remove($.className('hidden'));
34
+		}
35
+		this.addImages();
36
+	};
37
+	proto.initEvent = function() {
38
+		var self = this;
39
+		$(document.body).on('tap', 'img[data-preview-src]', function() {
40
+			self.open(this);
41
+			return false;
42
+		});
43
+		var laterClose = null;
44
+		var laterCloseEvent = function() {
45
+			!laterClose && (laterClose = $.later(function() {
46
+				self.loader.removeEventListener('tap', laterCloseEvent);
47
+				self.scroller.removeEventListener('tap', laterCloseEvent);
48
+				self.close();
49
+			}, 300));
50
+		};
51
+		this.scroller.addEventListener('doubletap', function() {
52
+			if (laterClose) {
53
+				laterClose.cancel();
54
+				laterClose = null;
55
+			}
56
+		});
57
+		this.element.addEventListener('webkitAnimationEnd', function() {
58
+			if (self.element.classList.contains($.className('preview-out'))) { //close
59
+				self.element.style.display = 'none';
60
+				self.element.classList.remove($.className('preview-out'));
61
+				self.element.classList.remove($.className('preview-in'));
62
+				laterClose = null;
63
+			} else { //open
64
+				self.loader.addEventListener('tap', laterCloseEvent);
65
+				self.scroller.addEventListener('tap', laterCloseEvent);
66
+			}
67
+		});
68
+		this.element.addEventListener('slide', function(e) {
69
+			if (self.options.zoom) {
70
+				var lastZoomerEl = self.element.querySelector('.mui-zoom-wrapper:nth-child(' + (self.lastIndex + 1) + ')');
71
+				if (lastZoomerEl) {
72
+					$(lastZoomerEl).zoom().setZoom(1);
73
+				}
74
+			}
75
+			var slideNumber = e.detail.slideNumber;
76
+			self.lastIndex = slideNumber;
77
+			self.indicator && (self.indicator.innerText = (slideNumber + 1) + '/' + self.currentGroup.length);
78
+			self._loadItem(slideNumber);
79
+
80
+		});
81
+	};
82
+	proto.addImages = function(group, index) {
83
+		this.groups = {};
84
+		var imgs = [];
85
+		if (group) {
86
+			if (group === defaultGroupName) {
87
+				imgs = document.querySelectorAll("img[data-preview-src]:not([data-preview-group])");
88
+			} else {
89
+				imgs = document.querySelectorAll("img[data-preview-src][data-preview-group='" + group + "']");
90
+			}
91
+		} else {
92
+			imgs = document.querySelectorAll("img[data-preview-src]");
93
+		}
94
+		if (imgs.length) {
95
+			for (var i = 0, len = imgs.length; i < len; i++) {
96
+				this.addImage(imgs[i]);
97
+			}
98
+		}
99
+	};
100
+	proto.addImage = function(img) {
101
+		var group = img.getAttribute('data-preview-group');
102
+		group = group || defaultGroupName;
103
+		if (!this.groups[group]) {
104
+			this.groups[group] = [];
105
+		}
106
+		var src = img.getAttribute('src');
107
+		if (img.__mui_img_data && img.__mui_img_data.src === src) { //已缓存且图片未变化
108
+			this.groups[group].push(img.__mui_img_data);
109
+		} else {
110
+			var lazyload = img.getAttribute('data-preview-src');
111
+			if (!lazyload) {
112
+				lazyload = src;
113
+			}
114
+			var imgObj = {
115
+				src: src,
116
+				lazyload: src === lazyload ? '' : lazyload,
117
+				loaded: src === lazyload ? true : false,
118
+				sWidth: 0,
119
+				sHeight: 0,
120
+				sTop: 0,
121
+				sLeft: 0,
122
+				sScale: 1,
123
+				el: img
124
+			};
125
+			this.groups[group].push(imgObj);
126
+			img.__mui_img_data = imgObj;
127
+		}
128
+	};
129
+
130
+
131
+	proto.empty = function() {
132
+		this.scroller.innerHTML = '';
133
+	};
134
+	proto._initImgData = function(itemData, imgEl) {
135
+		if (!itemData.sWidth) {
136
+			var img = itemData.el;
137
+			itemData.sWidth = img.offsetWidth;
138
+			itemData.sHeight = img.offsetHeight;
139
+			var offset = $.offset(img);
140
+			itemData.sTop = offset.top;
141
+			itemData.sLeft = offset.left;
142
+			itemData.sScale = Math.max(itemData.sWidth / window.innerWidth, itemData.sHeight / window.innerHeight);
143
+		}
144
+		imgEl.style.webkitTransform = 'translate3d(0,0,0) scale(' + itemData.sScale + ')';
145
+	};
146
+
147
+	proto._getScale = function(from, to) {
148
+		var scaleX = from.width / to.width;
149
+		var scaleY = from.height / to.height;
150
+		var scale = 1;
151
+		if (scaleX <= scaleY) {
152
+			scale = from.height / (to.height * scaleX);
153
+		} else {
154
+			scale = from.width / (to.width * scaleY);
155
+		}
156
+		return scale;
157
+	};
158
+	proto._imgTransitionEnd = function(e) {
159
+		var img = e.target;
160
+		img.classList.remove($.className('transitioning'));
161
+		img.removeEventListener('webkitTransitionEnd', this._imgTransitionEnd.bind(this));
162
+	};
163
+	proto._loadItem = function(index, isOpening) { //TODO 暂时仅支持img
164
+		var itemEl = this.scroller.querySelector($.classSelector('.slider-item:nth-child(' + (index + 1) + ')'));
165
+		var itemData = this.currentGroup[index];
166
+		var imgEl = itemEl.querySelector('img');
167
+		this._initImgData(itemData, imgEl);
168
+		if (isOpening) {
169
+			var posi = this._getPosition(itemData);
170
+			imgEl.style.webkitTransitionDuration = '0ms';
171
+			imgEl.style.webkitTransform = 'translate3d(' + posi.x + 'px,' + posi.y + 'px,0) scale(' + itemData.sScale + ')';
172
+			imgEl.offsetHeight;
173
+		}
174
+		if (!itemData.loaded && imgEl.getAttribute('data-preview-lazyload')) {
175
+			var self = this;
176
+			self.loader.classList.add($.className('active'));
177
+			//移动位置动画
178
+			imgEl.style.webkitTransitionDuration = '0.5s';
179
+			imgEl.addEventListener('webkitTransitionEnd', self._imgTransitionEnd.bind(self));
180
+			imgEl.style.webkitTransform = 'translate3d(0,0,0) scale(' + itemData.sScale + ')';
181
+			this.loadImage(imgEl, function() {
182
+				itemData.loaded = true;
183
+				imgEl.src = itemData.lazyload;
184
+				self._initZoom(itemEl, this.width, this.height);
185
+				imgEl.classList.add($.className('transitioning'));
186
+				imgEl.addEventListener('webkitTransitionEnd', self._imgTransitionEnd.bind(self));
187
+				imgEl.setAttribute('style', '');
188
+				imgEl.offsetHeight;
189
+				self.loader.classList.remove($.className('active'));
190
+			});
191
+		} else {
192
+			itemData.lazyload && (imgEl.src = itemData.lazyload);
193
+			this._initZoom(itemEl, imgEl.width, imgEl.height);
194
+			imgEl.classList.add($.className('transitioning'));
195
+			imgEl.addEventListener('webkitTransitionEnd', this._imgTransitionEnd.bind(this));
196
+			imgEl.setAttribute('style', '');
197
+			imgEl.offsetHeight;
198
+		}
199
+		this._preloadItem(index + 1);
200
+		this._preloadItem(index - 1);
201
+	};
202
+	proto._preloadItem = function(index) {
203
+		var itemEl = this.scroller.querySelector($.classSelector('.slider-item:nth-child(' + (index + 1) + ')'));
204
+		if (itemEl) {
205
+			var itemData = this.currentGroup[index];
206
+			if (!itemData.sWidth) {
207
+				var imgEl = itemEl.querySelector('img');
208
+				this._initImgData(itemData, imgEl);
209
+			}
210
+		}
211
+	};
212
+	proto._initZoom = function(zoomWrapperEl, zoomerWidth, zoomerHeight) {
213
+		if (!this.options.zoom) {
214
+			return;
215
+		}
216
+		if (zoomWrapperEl.getAttribute('data-zoomer')) {
217
+			return;
218
+		}
219
+		var zoomEl = zoomWrapperEl.querySelector($.classSelector('.zoom'));
220
+		if (zoomEl.tagName === 'IMG') {
221
+			var self = this;
222
+			var maxZoom = self._getScale({
223
+				width: zoomWrapperEl.offsetWidth,
224
+				height: zoomWrapperEl.offsetHeight
225
+			}, {
226
+				width: zoomerWidth,
227
+				height: zoomerHeight
228
+			});
229
+			$(zoomWrapperEl).zoom({
230
+				maxZoom: Math.max(maxZoom, 1)
231
+			});
232
+		} else {
233
+			$(zoomWrapperEl).zoom();
234
+		}
235
+	};
236
+	proto.loadImage = function(imgEl, callback) {
237
+		var onReady = function() {
238
+			callback && callback.call(this);
239
+		};
240
+		var img = new Image();
241
+		img.onload = onReady;
242
+		img.onerror = onReady;
243
+		img.src = imgEl.getAttribute('data-preview-lazyload');
244
+	};
245
+	proto.getRangeByIndex = function(index, length) {
246
+		return {
247
+			from: 0,
248
+			to: length - 1
249
+		};
250
+		//		var from = Math.max(index - 1, 0);
251
+		//		var to = Math.min(index + 1, length);
252
+		//		if (index === length - 1) {
253
+		//			from = Math.max(length - 3, 0);
254
+		//			to = length - 1;
255
+		//		}
256
+		//		if (index === 0) {
257
+		//			from = 0;
258
+		//			to = Math.min(2, length - 1);
259
+		//		}
260
+		//		return {
261
+		//			from: from,
262
+		//			to: to
263
+		//		};
264
+	};
265
+
266
+	proto._getPosition = function(itemData) {
267
+		var sLeft = itemData.sLeft - window.pageXOffset;
268
+		var sTop = itemData.sTop - window.pageYOffset;
269
+		var left = (window.innerWidth - itemData.sWidth) / 2;
270
+		var top = (window.innerHeight - itemData.sHeight) / 2;
271
+		return {
272
+			left: sLeft,
273
+			top: sTop,
274
+			x: sLeft - left,
275
+			y: sTop - top
276
+		};
277
+	};
278
+	proto.refresh = function(index, groupArray) {
279
+		this.currentGroup = groupArray;
280
+		//重新生成slider
281
+		var length = groupArray.length;
282
+		var itemHtml = [];
283
+		var currentRange = this.getRangeByIndex(index, length);
284
+		var from = currentRange.from;
285
+		var to = currentRange.to + 1;
286
+		var currentIndex = index;
287
+		var className = '';
288
+		var itemStr = '';
289
+		var wWidth = window.innerWidth;
290
+		var wHeight = window.innerHeight;
291
+		for (var i = 0; from < to; from++, i++) {
292
+			var itemData = groupArray[from];
293
+			var style = '';
294
+			if (itemData.sWidth) {
295
+				style = '-webkit-transform:translate3d(0,0,0) scale(' + itemData.sScale + ');transform:translate3d(0,0,0) scale(' + itemData.sScale + ')';
296
+			}
297
+			itemStr = itemTemplate.replace('{{src}}', itemData.src).replace('{{lazyload}}', itemData.lazyload).replace('{{style}}', style);
298
+			if (from === index) {
299
+				currentIndex = i;
300
+				className = $.className('active');
301
+			} else {
302
+				className = '';
303
+			}
304
+			itemHtml.push(itemStr.replace('{{className}}', className));
305
+		}
306
+		this.scroller.innerHTML = itemHtml.join('');
307
+		this.element.style.display = 'block';
308
+		this.element.classList.add($.className('preview-in'));
309
+		this.lastIndex = currentIndex;
310
+		this.element.offsetHeight;
311
+		$(this.element).slider().gotoItem(currentIndex, 0);
312
+		this.indicator && (this.indicator.innerText = (currentIndex + 1) + '/' + this.currentGroup.length);
313
+		this._loadItem(currentIndex, true);
314
+	};
315
+	proto.openByGroup = function(index, group) {
316
+		index = Math.min(Math.max(0, index), this.groups[group].length - 1);
317
+		this.refresh(index, this.groups[group]);
318
+	};
319
+	proto.open = function(index, group) {
320
+		if (this.isShown()) {
321
+			return;
322
+		}
323
+		if (typeof index === "number") {
324
+			group = group || defaultGroupName;
325
+			this.addImages(group, index); //刷新当前group
326
+			this.openByGroup(index, group);
327
+		} else {
328
+			group = index.getAttribute('data-preview-group');
329
+			group = group || defaultGroupName;
330
+			this.addImages(group, index); //刷新当前group
331
+			this.openByGroup(this.groups[group].indexOf(index.__mui_img_data), group);
332
+		}
333
+	};
334
+	proto.close = function(index, group) {
335
+		if (!this.isShown()) {
336
+			return;
337
+		}
338
+		this.element.classList.remove($.className('preview-in'));
339
+		this.element.classList.add($.className('preview-out'));
340
+		var itemEl = this.scroller.querySelector($.classSelector('.slider-item:nth-child(' + (this.lastIndex + 1) + ')'));
341
+		var imgEl = itemEl.querySelector('img');
342
+		if (imgEl) {
343
+			imgEl.classList.add($.className('transitioning'));
344
+			var itemData = this.currentGroup[this.lastIndex];
345
+			var posi = this._getPosition(itemData);
346
+			var sLeft = posi.left;
347
+			var sTop = posi.top;
348
+			if (sTop > window.innerHeight || sLeft > window.innerWidth || sTop < 0 || sLeft < 0) { //out viewport
349
+				imgEl.style.opacity = 0;
350
+				imgEl.style.webkitTransitionDuration = '0.5s';
351
+				imgEl.style.webkitTransform = 'scale(' + itemData.sScale + ')';
352
+			} else {
353
+				if (this.options.zoom) {
354
+					$(imgEl.parentNode.parentNode).zoom().toggleZoom(0);
355
+				}
356
+				imgEl.style.webkitTransitionDuration = '0.5s';
357
+				imgEl.style.webkitTransform = 'translate3d(' + posi.x + 'px,' + posi.y + 'px,0) scale(' + itemData.sScale + ')';
358
+			}
359
+		}
360
+		var zoomers = this.element.querySelectorAll($.classSelector('.zoom-wrapper'));
361
+		for (var i = 0, len = zoomers.length; i < len; i++) {
362
+			$(zoomers[i]).zoom().destroy();
363
+		}
364
+		$(this.element).slider().destroy();
365
+//		this.empty();
366
+	};
367
+	proto.isShown = function() {
368
+		return this.element.classList.contains($.className('preview-in'));
369
+	};
370
+
371
+	var previewImageApi = null;
372
+	$.previewImage = function(options) {
373
+		if (!previewImageApi) {
374
+			previewImageApi = new PreviewImage(options);
375
+		}
376
+		return previewImageApi;
377
+	};
378
+	$.getPreviewImage = function() {
379
+		return previewImageApi;
380
+	}
381
+
382
+})(mui, window);

+ 322 - 0
WebChat/js/mui.zoom.js

@@ -0,0 +1,322 @@
1
+(function($, window) {
2
+	var CLASS_ZOOM = $.className('zoom');
3
+	var CLASS_ZOOM_SCROLLER = $.className('zoom-scroller');
4
+
5
+	var SELECTOR_ZOOM = '.' + CLASS_ZOOM;
6
+	var SELECTOR_ZOOM_SCROLLER = '.' + CLASS_ZOOM_SCROLLER;
7
+
8
+	var EVENT_PINCH_START = 'pinchstart';
9
+	var EVENT_PINCH = 'pinch';
10
+	var EVENT_PINCH_END = 'pinchend';
11
+	if ('ongesturestart' in window) {
12
+		EVENT_PINCH_START = 'gesturestart';
13
+		EVENT_PINCH = 'gesturechange';
14
+		EVENT_PINCH_END = 'gestureend';
15
+	}
16
+	$.Zoom = function(element, options) {
17
+		var zoom = this;
18
+
19
+		zoom.options = $.extend($.Zoom.defaults, options);
20
+
21
+		zoom.wrapper = zoom.element = element;
22
+		zoom.scroller = element.querySelector(SELECTOR_ZOOM_SCROLLER);
23
+		zoom.scrollerStyle = zoom.scroller && zoom.scroller.style;
24
+
25
+		zoom.zoomer = element.querySelector(SELECTOR_ZOOM);
26
+		zoom.zoomerStyle = zoom.zoomer && zoom.zoomer.style;
27
+
28
+		zoom.init = function() {
29
+			//自动启用
30
+			$.options.gestureConfig.pinch = true;
31
+			$.options.gestureConfig.doubletap = true;
32
+			zoom.initEvents();
33
+		};
34
+
35
+		zoom.initEvents = function(detach) {
36
+			var action = detach ? 'removeEventListener' : 'addEventListener';
37
+			var target = zoom.scroller;
38
+
39
+			target[action](EVENT_PINCH_START, zoom.onPinchstart);
40
+			target[action](EVENT_PINCH, zoom.onPinch);
41
+			target[action](EVENT_PINCH_END, zoom.onPinchend);
42
+
43
+			target[action]($.EVENT_START, zoom.onTouchstart);
44
+			target[action]($.EVENT_MOVE, zoom.onTouchMove);
45
+			target[action]($.EVENT_CANCEL, zoom.onTouchEnd);
46
+			target[action]($.EVENT_END, zoom.onTouchEnd);
47
+
48
+			target[action]('drag', zoom.dragEvent);
49
+			target[action]('doubletap', zoom.doubleTapEvent);
50
+		};
51
+		zoom.dragEvent = function(e) {
52
+			if (imageIsMoved || isGesturing) {
53
+				e.stopPropagation();
54
+			}
55
+		};
56
+		zoom.doubleTapEvent = function(e) {
57
+			zoom.toggleZoom(e.detail.center);
58
+		};
59
+		zoom.transition = function(style, time) {
60
+			time = time || 0;
61
+			style['webkitTransitionDuration'] = time + 'ms';
62
+			return zoom;
63
+		};
64
+		zoom.translate = function(style, x, y) {
65
+			x = x || 0;
66
+			y = y || 0;
67
+			style['webkitTransform'] = 'translate3d(' + x + 'px,' + y + 'px,0px)';
68
+			return zoom;
69
+		};
70
+		zoom.scale = function(style, scale) {
71
+			scale = scale || 1;
72
+			style['webkitTransform'] = 'translate3d(0,0,0) scale(' + scale + ')';
73
+			return zoom;
74
+		};
75
+		zoom.scrollerTransition = function(time) {
76
+			return zoom.transition(zoom.scrollerStyle, time);
77
+		};
78
+		zoom.scrollerTransform = function(x, y) {
79
+			return zoom.translate(zoom.scrollerStyle, x, y);
80
+		};
81
+		zoom.zoomerTransition = function(time) {
82
+			return zoom.transition(zoom.zoomerStyle, time);
83
+		};
84
+		zoom.zoomerTransform = function(scale) {
85
+			return zoom.scale(zoom.zoomerStyle, scale);
86
+		};
87
+
88
+		// Gestures
89
+		var scale = 1,
90
+			currentScale = 1,
91
+			isScaling = false,
92
+			isGesturing = false;
93
+		zoom.onPinchstart = function(e) {
94
+			isGesturing = true;
95
+		};
96
+		zoom.onPinch = function(e) {
97
+			if (!isScaling) {
98
+				zoom.zoomerTransition(0);
99
+				isScaling = true;
100
+			}
101
+			scale = (e.detail ? e.detail.scale : e.scale) * currentScale;
102
+			if (scale > zoom.options.maxZoom) {
103
+				scale = zoom.options.maxZoom - 1 + Math.pow((scale - zoom.options.maxZoom + 1), 0.5);
104
+			}
105
+			if (scale < zoom.options.minZoom) {
106
+				scale = zoom.options.minZoom + 1 - Math.pow((zoom.options.minZoom - scale + 1), 0.5);
107
+			}
108
+			zoom.zoomerTransform(scale);
109
+		};
110
+		zoom.onPinchend = function(e) {
111
+			scale = Math.max(Math.min(scale, zoom.options.maxZoom), zoom.options.minZoom);
112
+			zoom.zoomerTransition(zoom.options.speed).zoomerTransform(scale);
113
+			currentScale = scale;
114
+			isScaling = false;
115
+		};
116
+		zoom.setZoom = function(newScale) {
117
+			scale = currentScale = newScale;
118
+			zoom.scrollerTransition(zoom.options.speed).scrollerTransform(0, 0);
119
+			zoom.zoomerTransition(zoom.options.speed).zoomerTransform(scale);
120
+		};
121
+		zoom.toggleZoom = function(position, speed) {
122
+			if (typeof position === 'number') {
123
+				speed = position;
124
+				position = undefined;
125
+			}
126
+			speed = typeof speed === 'undefined' ? zoom.options.speed : speed;
127
+			if (scale && scale !== 1) {
128
+				scale = currentScale = 1;
129
+				zoom.scrollerTransition(speed).scrollerTransform(0, 0);
130
+			} else {
131
+				scale = currentScale = zoom.options.maxZoom;
132
+				if (position) {
133
+					var offset = $.offset(zoom.zoomer);
134
+					var top = offset.top;
135
+					var left = offset.left;
136
+					var offsetX = (position.x - left) * scale;
137
+					var offsetY = (position.y - top) * scale;
138
+					this._cal();
139
+					if (offsetX >= imageMaxX && offsetX <= (imageMaxX + wrapperWidth)) { //center
140
+						offsetX = imageMaxX - offsetX + wrapperWidth / 2;
141
+					} else if (offsetX < imageMaxX) { //left
142
+						offsetX = imageMaxX - offsetX + wrapperWidth / 2;
143
+					} else if (offsetX > (imageMaxX + wrapperWidth)) { //right
144
+						offsetX = imageMaxX + wrapperWidth - offsetX - wrapperWidth / 2;
145
+					}
146
+					if (offsetY >= imageMaxY && offsetY <= (imageMaxY + wrapperHeight)) { //middle
147
+						offsetY = imageMaxY - offsetY + wrapperHeight / 2;
148
+					} else if (offsetY < imageMaxY) { //top
149
+						offsetY = imageMaxY - offsetY + wrapperHeight / 2;
150
+					} else if (offsetY > (imageMaxY + wrapperHeight)) { //bottom
151
+						offsetY = imageMaxY + wrapperHeight - offsetY - wrapperHeight / 2;
152
+					}
153
+					offsetX = Math.min(Math.max(offsetX, imageMinX), imageMaxX);
154
+					offsetY = Math.min(Math.max(offsetY, imageMinY), imageMaxY);
155
+					zoom.scrollerTransition(speed).scrollerTransform(offsetX, offsetY);
156
+				} else {
157
+					zoom.scrollerTransition(speed).scrollerTransform(0, 0);
158
+				}
159
+			}
160
+			zoom.zoomerTransition(speed).zoomerTransform(scale);
161
+		};
162
+
163
+		zoom._cal = function() {
164
+			wrapperWidth = zoom.wrapper.offsetWidth;
165
+			wrapperHeight = zoom.wrapper.offsetHeight;
166
+			imageWidth = zoom.zoomer.offsetWidth;
167
+			imageHeight = zoom.zoomer.offsetHeight;
168
+			var scaledWidth = imageWidth * scale;
169
+			var scaledHeight = imageHeight * scale;
170
+			imageMinX = Math.min((wrapperWidth / 2 - scaledWidth / 2), 0);
171
+			imageMaxX = -imageMinX;
172
+			imageMinY = Math.min((wrapperHeight / 2 - scaledHeight / 2), 0);
173
+			imageMaxY = -imageMinY;
174
+		};
175
+
176
+		var wrapperWidth, wrapperHeight, imageIsTouched, imageIsMoved, imageCurrentX, imageCurrentY, imageMinX, imageMinY, imageMaxX, imageMaxY, imageWidth, imageHeight, imageTouchesStart = {},
177
+			imageTouchesCurrent = {},
178
+			imageStartX, imageStartY, velocityPrevPositionX, velocityPrevTime, velocityX, velocityPrevPositionY, velocityY;
179
+
180
+		zoom.onTouchstart = function(e) {
181
+			e.preventDefault();
182
+			imageIsTouched = true;
183
+			imageTouchesStart.x = e.type === $.EVENT_START ? e.targetTouches[0].pageX : e.pageX;
184
+			imageTouchesStart.y = e.type === $.EVENT_START ? e.targetTouches[0].pageY : e.pageY;
185
+		};
186
+		zoom.onTouchMove = function(e) {
187
+			e.preventDefault();
188
+			if (!imageIsTouched) return;
189
+			if (!imageIsMoved) {
190
+				wrapperWidth = zoom.wrapper.offsetWidth;
191
+				wrapperHeight = zoom.wrapper.offsetHeight;
192
+				imageWidth = zoom.zoomer.offsetWidth;
193
+				imageHeight = zoom.zoomer.offsetHeight;
194
+				var translate = $.parseTranslateMatrix($.getStyles(zoom.scroller, 'webkitTransform'));
195
+				imageStartX = translate.x || 0;
196
+				imageStartY = translate.y || 0;
197
+				zoom.scrollerTransition(0);
198
+			}
199
+			var scaledWidth = imageWidth * scale;
200
+			var scaledHeight = imageHeight * scale;
201
+
202
+			if (scaledWidth < wrapperWidth && scaledHeight < wrapperHeight) return;
203
+
204
+			imageMinX = Math.min((wrapperWidth / 2 - scaledWidth / 2), 0);
205
+			imageMaxX = -imageMinX;
206
+			imageMinY = Math.min((wrapperHeight / 2 - scaledHeight / 2), 0);
207
+			imageMaxY = -imageMinY;
208
+
209
+			imageTouchesCurrent.x = e.type === $.EVENT_MOVE ? e.targetTouches[0].pageX : e.pageX;
210
+			imageTouchesCurrent.y = e.type === $.EVENT_MOVE ? e.targetTouches[0].pageY : e.pageY;
211
+
212
+			if (!imageIsMoved && !isScaling) {
213
+				//				if (Math.abs(imageTouchesCurrent.y - imageTouchesStart.y) < Math.abs(imageTouchesCurrent.x - imageTouchesStart.x)) {
214
+				//TODO 此处需要优化,当遇到长图,需要上下滚动时,下列判断会导致滚动不流畅
215
+				if (
216
+					(Math.floor(imageMinX) === Math.floor(imageStartX) && imageTouchesCurrent.x < imageTouchesStart.x) ||
217
+					(Math.floor(imageMaxX) === Math.floor(imageStartX) && imageTouchesCurrent.x > imageTouchesStart.x)
218
+				) {
219
+					imageIsTouched = false;
220
+					return;
221
+				}
222
+				//				}
223
+			}
224
+			imageIsMoved = true;
225
+			imageCurrentX = imageTouchesCurrent.x - imageTouchesStart.x + imageStartX;
226
+			imageCurrentY = imageTouchesCurrent.y - imageTouchesStart.y + imageStartY;
227
+
228
+			if (imageCurrentX < imageMinX) {
229
+				imageCurrentX = imageMinX + 1 - Math.pow((imageMinX - imageCurrentX + 1), 0.8);
230
+			}
231
+			if (imageCurrentX > imageMaxX) {
232
+				imageCurrentX = imageMaxX - 1 + Math.pow((imageCurrentX - imageMaxX + 1), 0.8);
233
+			}
234
+
235
+			if (imageCurrentY < imageMinY) {
236
+				imageCurrentY = imageMinY + 1 - Math.pow((imageMinY - imageCurrentY + 1), 0.8);
237
+			}
238
+			if (imageCurrentY > imageMaxY) {
239
+				imageCurrentY = imageMaxY - 1 + Math.pow((imageCurrentY - imageMaxY + 1), 0.8);
240
+			}
241
+
242
+			//Velocity
243
+			if (!velocityPrevPositionX) velocityPrevPositionX = imageTouchesCurrent.x;
244
+			if (!velocityPrevPositionY) velocityPrevPositionY = imageTouchesCurrent.y;
245
+			if (!velocityPrevTime) velocityPrevTime = $.now();
246
+			velocityX = (imageTouchesCurrent.x - velocityPrevPositionX) / ($.now() - velocityPrevTime) / 2;
247
+			velocityY = (imageTouchesCurrent.y - velocityPrevPositionY) / ($.now() - velocityPrevTime) / 2;
248
+			if (Math.abs(imageTouchesCurrent.x - velocityPrevPositionX) < 2) velocityX = 0;
249
+			if (Math.abs(imageTouchesCurrent.y - velocityPrevPositionY) < 2) velocityY = 0;
250
+			velocityPrevPositionX = imageTouchesCurrent.x;
251
+			velocityPrevPositionY = imageTouchesCurrent.y;
252
+			velocityPrevTime = $.now();
253
+
254
+			zoom.scrollerTransform(imageCurrentX, imageCurrentY);
255
+		};
256
+		zoom.onTouchEnd = function(e) {
257
+			if (!e.touches.length) {
258
+				isGesturing = false;
259
+			}
260
+			if (!imageIsTouched || !imageIsMoved) {
261
+				imageIsTouched = false;
262
+				imageIsMoved = false;
263
+				return;
264
+			}
265
+			imageIsTouched = false;
266
+			imageIsMoved = false;
267
+			var momentumDurationX = 300;
268
+			var momentumDurationY = 300;
269
+			var momentumDistanceX = velocityX * momentumDurationX;
270
+			var newPositionX = imageCurrentX + momentumDistanceX;
271
+			var momentumDistanceY = velocityY * momentumDurationY;
272
+			var newPositionY = imageCurrentY + momentumDistanceY;
273
+
274
+			if (velocityX !== 0) momentumDurationX = Math.abs((newPositionX - imageCurrentX) / velocityX);
275
+			if (velocityY !== 0) momentumDurationY = Math.abs((newPositionY - imageCurrentY) / velocityY);
276
+			var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
277
+
278
+			imageCurrentX = newPositionX;
279
+			imageCurrentY = newPositionY;
280
+
281
+			var scaledWidth = imageWidth * scale;
282
+			var scaledHeight = imageHeight * scale;
283
+			imageMinX = Math.min((wrapperWidth / 2 - scaledWidth / 2), 0);
284
+			imageMaxX = -imageMinX;
285
+			imageMinY = Math.min((wrapperHeight / 2 - scaledHeight / 2), 0);
286
+			imageMaxY = -imageMinY;
287
+			imageCurrentX = Math.max(Math.min(imageCurrentX, imageMaxX), imageMinX);
288
+			imageCurrentY = Math.max(Math.min(imageCurrentY, imageMaxY), imageMinY);
289
+
290
+			zoom.scrollerTransition(momentumDuration).scrollerTransform(imageCurrentX, imageCurrentY);
291
+		};
292
+		zoom.destroy = function() {
293
+			zoom.initEvents(true); //detach
294
+			delete $.data[zoom.wrapper.getAttribute('data-zoomer')];
295
+			zoom.wrapper.setAttribute('data-zoomer', '');
296
+		}
297
+		zoom.init();
298
+		return zoom;
299
+	};
300
+	$.Zoom.defaults = {
301
+		speed: 300,
302
+		maxZoom: 3,
303
+		minZoom: 1,
304
+	};
305
+	$.fn.zoom = function(options) {
306
+		var zoomApis = [];
307
+		this.each(function() {
308
+			var zoomApi = null;
309
+			var self = this;
310
+			var id = self.getAttribute('data-zoomer');
311
+			if (!id) {
312
+				id = ++$.uuid;
313
+				$.data[id] = zoomApi = new $.Zoom(self, options);
314
+				self.setAttribute('data-zoomer', id);
315
+			} else {
316
+				zoomApi = $.data[id];
317
+			}
318
+			zoomApis.push(zoomApi);
319
+		});
320
+		return zoomApis.length === 1 ? zoomApis[0] : zoomApis;
321
+	};
322
+})(mui, window);