uview-plus 3.1.50 → 3.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +10 -10
  2. package/changelog.md +18 -1
  3. package/components/u-action-sheet/props.js +10 -11
  4. package/components/u-album/props.js +11 -12
  5. package/components/u-alert/props.js +8 -9
  6. package/components/u-avatar/props.js +14 -15
  7. package/components/u-avatar-group/props.js +9 -10
  8. package/components/u-back-top/props.js +10 -11
  9. package/components/u-back-top/u-back-top.vue +1 -1
  10. package/components/u-badge/props.js +14 -15
  11. package/components/u-badge/u-badge.vue +1 -1
  12. package/components/u-button/props.js +28 -29
  13. package/components/u-button/u-button.vue +6 -6
  14. package/components/u-button/vue.scss +8 -7
  15. package/components/u-calendar/month.vue +1 -1
  16. package/components/u-calendar/props.js +27 -28
  17. package/components/u-car-keyboard/props.js +0 -1
  18. package/components/u-car-keyboard/u-car-keyboard.vue +1 -1
  19. package/components/u-cell/props.js +17 -18
  20. package/components/u-cell/u-cell.vue +14 -4
  21. package/components/u-cell-group/props.js +2 -3
  22. package/components/u-cell-group/u-cell-group.vue +1 -1
  23. package/components/u-checkbox/props.js +13 -14
  24. package/components/u-checkbox/u-checkbox.vue +1 -1
  25. package/components/u-checkbox-group/props.js +16 -17
  26. package/components/u-circle-progress/props.js +1 -2
  27. package/components/u-code/props.js +6 -7
  28. package/components/u-code/u-code.vue +5 -0
  29. package/components/u-code-input/props.js +16 -17
  30. package/components/u-col/props.js +5 -6
  31. package/components/u-collapse/props.js +3 -4
  32. package/components/u-collapse-item/props.js +11 -12
  33. package/components/u-column-notice/props.js +10 -11
  34. package/components/u-copy/u-copy.vue +70 -0
  35. package/components/u-count-down/props.js +4 -5
  36. package/components/u-count-down/u-count-down.vue +6 -1
  37. package/components/u-count-to/props.js +11 -12
  38. package/components/u-datetime-picker/props.js +37 -25
  39. package/components/u-datetime-picker/u-datetime-picker.vue +58 -3
  40. package/components/u-divider/props.js +8 -9
  41. package/components/u-dropdown/props.js +0 -1
  42. package/components/u-dropdown-item/props.js +0 -1
  43. package/components/u-empty/props.js +11 -12
  44. package/components/u-form/props.js +8 -9
  45. package/components/u-form/u-form.vue +1 -1
  46. package/components/u-form-item/props.js +13 -9
  47. package/components/u-form-item/u-form-item.vue +1 -0
  48. package/components/u-gap/props.js +4 -5
  49. package/components/u-gap/u-gap.vue +5 -4
  50. package/components/u-grid/props.js +3 -4
  51. package/components/u-grid-item/props.js +2 -3
  52. package/components/u-grid-item/u-grid-item.vue +5 -0
  53. package/components/u-icon/props.js +17 -18
  54. package/components/u-icon/u-icon.vue +9 -6
  55. package/components/u-image/props.js +16 -17
  56. package/components/u-image/u-image.vue +1 -1
  57. package/components/u-index-anchor/props.js +5 -6
  58. package/components/u-index-anchor/u-index-anchor.vue +1 -1
  59. package/components/u-index-item/props.js +0 -1
  60. package/components/u-index-item/u-index-item.vue +1 -1
  61. package/components/u-index-list/props.js +5 -6
  62. package/components/u-index-list/u-index-list.vue +3 -2
  63. package/components/u-input/props.js +35 -36
  64. package/components/u-input/u-input.vue +10 -4
  65. package/components/u-keyboard/props.js +16 -17
  66. package/components/u-line/props.js +6 -7
  67. package/components/u-line-progress/props.js +5 -6
  68. package/components/u-link/props.js +7 -8
  69. package/components/u-list/props.js +14 -15
  70. package/components/u-list-item/props.js +1 -2
  71. package/components/u-loading-icon/props.js +11 -12
  72. package/components/u-loading-page/props.js +9 -10
  73. package/components/u-loadmore/props.js +18 -19
  74. package/components/u-modal/props.js +16 -17
  75. package/components/u-navbar/props.js +16 -17
  76. package/components/u-no-network/props.js +3 -4
  77. package/components/u-notice-bar/props.js +13 -14
  78. package/components/u-notify/props.js +9 -10
  79. package/components/u-notify/u-notify.vue +5 -0
  80. package/components/u-number-box/props.js +22 -23
  81. package/components/u-number-box/u-number-box.vue +21 -1
  82. package/components/u-number-keyboard/props.js +3 -4
  83. package/components/u-overlay/props.js +4 -5
  84. package/components/u-parse/props.js +8 -9
  85. package/components/u-parse/u-parse.vue +6 -1
  86. package/components/u-picker/props.js +16 -17
  87. package/components/u-picker-column/props.js +0 -1
  88. package/components/u-popup/props.js +15 -16
  89. package/components/u-qrcode/qrcode.js +1206 -0
  90. package/components/u-qrcode/u-qrcode.vue +199 -0
  91. package/components/u-radio/props.js +13 -14
  92. package/components/u-radio-group/props.js +17 -18
  93. package/components/u-rate/props.js +14 -15
  94. package/components/u-read-more/props.js +8 -9
  95. package/components/u-row/props.js +3 -4
  96. package/components/u-row-notice/props.js +7 -8
  97. package/components/u-row-notice/u-row-notice.vue +5 -0
  98. package/components/u-safe-bottom/props.js +0 -1
  99. package/components/u-scroll-list/props.js +6 -7
  100. package/components/u-search/props.js +24 -25
  101. package/components/u-skeleton/props.js +11 -12
  102. package/components/u-slider/props.js +11 -12
  103. package/components/u-status-bar/props.js +1 -2
  104. package/components/u-status-bar/u-status-bar.vue +1 -1
  105. package/components/u-steps/props.js +7 -8
  106. package/components/u-steps/u-steps.vue +1 -1
  107. package/components/u-steps-item/props.js +4 -5
  108. package/components/u-steps-item/u-steps-item.vue +1 -1
  109. package/components/u-sticky/props.js +6 -7
  110. package/components/u-sticky/u-sticky.vue +5 -0
  111. package/components/u-subsection/props.js +9 -10
  112. package/components/u-subsection/u-subsection.vue +2 -2
  113. package/components/u-swipe-action/props.js +1 -2
  114. package/components/u-swipe-action-item/nvue.js +5 -0
  115. package/components/u-swipe-action-item/props.js +6 -7
  116. package/components/u-swiper/props.js +24 -25
  117. package/components/u-swiper-indicator/props.js +5 -6
  118. package/components/u-switch/props.js +11 -12
  119. package/components/u-tabbar/props.js +8 -9
  120. package/components/u-tabbar-item/props.js +6 -7
  121. package/components/u-table/props.js +0 -1
  122. package/components/u-tabs/props.js +12 -13
  123. package/components/u-tabs-item/props.js +0 -1
  124. package/components/u-tag/props.js +15 -16
  125. package/components/u-td/props.js +0 -1
  126. package/components/u-text/props.js +21 -22
  127. package/components/u-textarea/props.js +23 -24
  128. package/components/u-toast/u-toast.vue +5 -0
  129. package/components/u-toolbar/props.js +6 -7
  130. package/components/u-tooltip/props.js +11 -12
  131. package/components/u-tooltip/u-tooltip.vue +0 -28
  132. package/components/u-tr/props.js +0 -1
  133. package/components/u-transition/props.js +4 -5
  134. package/components/u-transition/transition.js +8 -9
  135. package/components/u-transition/u-transition.vue +1 -1
  136. package/components/u-upload/props.js +22 -23
  137. package/components/u-upload/u-upload.vue +1 -1
  138. package/index.js +6 -6
  139. package/libs/config/props/actionSheet.js +1 -1
  140. package/libs/config/props/album.js +1 -1
  141. package/libs/config/props/avatarGroup.js +1 -1
  142. package/libs/config/props/backtop.js +2 -2
  143. package/libs/config/props/badge.js +1 -1
  144. package/libs/config/props/calendar.js +3 -3
  145. package/libs/config/props/checkboxGroup.js +1 -1
  146. package/libs/config/props/datetimePicker.js +1 -1
  147. package/libs/config/props/form.js +3 -3
  148. package/libs/config/props/formItem.js +1 -0
  149. package/libs/config/props/indexList.js +1 -1
  150. package/libs/config/props/noticeBar.js +1 -1
  151. package/libs/config/props/picker.js +2 -2
  152. package/libs/config/props/popup.js +1 -1
  153. package/libs/config/props/search.js +2 -2
  154. package/libs/config/props/slider.js +1 -1
  155. package/libs/config/props/swiper.js +1 -1
  156. package/libs/config/props/tabs.js +7 -7
  157. package/libs/config/props/text.js +2 -2
  158. package/libs/config/props/toast.js +1 -1
  159. package/libs/config/props/tooltip.js +1 -1
  160. package/libs/config/props/upload.js +3 -3
  161. package/libs/css/components.scss +11 -1
  162. package/libs/css/flex.scss +103 -101
  163. package/libs/function/colorGradient.js +8 -8
  164. package/libs/function/debounce.js +2 -2
  165. package/libs/function/digit.js +5 -5
  166. package/libs/function/index.js +29 -29
  167. package/libs/function/test.js +28 -28
  168. package/libs/function/throttle.js +2 -2
  169. package/package.json +4 -3
@@ -0,0 +1,1206 @@
1
+ let QRCode = {};
2
+ (function () {
3
+ /**
4
+ * 获取单个字符的utf8编码
5
+ * unicode BMP平面约65535个字符
6
+ * @param {num} code
7
+ * return {array}
8
+ */
9
+ function unicodeFormat8(code) {
10
+ // 1 byte
11
+ var c0, c1, c2;
12
+ if (code < 128) {
13
+ return [code];
14
+ // 2 bytes
15
+ } else if (code < 2048) {
16
+ c0 = 192 + (code >> 6);
17
+ c1 = 128 + (code & 63);
18
+ return [c0, c1];
19
+ // 3 bytes
20
+ } else {
21
+ c0 = 224 + (code >> 12);
22
+ c1 = 128 + (code >> 6 & 63);
23
+ c2 = 128 + (code & 63);
24
+ return [c0, c1, c2];
25
+ }
26
+ }
27
+ /**
28
+ * 获取字符串的utf8编码字节串
29
+ * @param {string} string
30
+ * @return {array}
31
+ */
32
+ function getUTF8Bytes(string) {
33
+ var utf8codes = [];
34
+ for (var i = 0; i < string.length; i++) {
35
+ var code = string.charCodeAt(i);
36
+ var utf8 = unicodeFormat8(code);
37
+ for (var j = 0; j < utf8.length; j++) {
38
+ utf8codes.push(utf8[j]);
39
+ }
40
+ }
41
+ return utf8codes;
42
+ }
43
+ /**
44
+ * 二维码算法实现
45
+ * @param {string} data 要编码的信息字符串
46
+ * @param {num} errorCorrectLevel 纠错等级
47
+ */
48
+ function QRCodeAlg(data, errorCorrectLevel) {
49
+ this.typeNumber = -1; //版本
50
+ this.errorCorrectLevel = errorCorrectLevel;
51
+ this.modules = null; //二维矩阵,存放最终结果
52
+ this.moduleCount = 0; //矩阵大小
53
+ this.dataCache = null; //数据缓存
54
+ this.rsBlocks = null; //版本数据信息
55
+ this.totalDataCount = -1; //可使用的数据量
56
+ this.data = data;
57
+ this.utf8bytes = getUTF8Bytes(data);
58
+ this.make();
59
+ }
60
+ QRCodeAlg.prototype = {
61
+ constructor: QRCodeAlg,
62
+ /**
63
+ * 获取二维码矩阵大小
64
+ * @return {num} 矩阵大小
65
+ */
66
+ getModuleCount: function () {
67
+ return this.moduleCount;
68
+ },
69
+ /**
70
+ * 编码
71
+ */
72
+ make: function () {
73
+ this.getRightType();
74
+ this.dataCache = this.createData();
75
+ this.createQrcode();
76
+ },
77
+ /**
78
+ * 设置二位矩阵功能图形
79
+ * @param {bool} test 表示是否在寻找最好掩膜阶段
80
+ * @param {num} maskPattern 掩膜的版本
81
+ */
82
+ makeImpl: function (maskPattern) {
83
+ this.moduleCount = this.typeNumber * 4 + 17;
84
+ this.modules = new Array(this.moduleCount);
85
+ for (var row = 0; row < this.moduleCount; row++) {
86
+ this.modules[row] = new Array(this.moduleCount);
87
+ }
88
+ this.setupPositionProbePattern(0, 0);
89
+ this.setupPositionProbePattern(this.moduleCount - 7, 0);
90
+ this.setupPositionProbePattern(0, this.moduleCount - 7);
91
+ this.setupPositionAdjustPattern();
92
+ this.setupTimingPattern();
93
+ this.setupTypeInfo(true, maskPattern);
94
+ if (this.typeNumber >= 7) {
95
+ this.setupTypeNumber(true);
96
+ }
97
+ this.mapData(this.dataCache, maskPattern);
98
+ },
99
+ /**
100
+ * 设置二维码的位置探测图形
101
+ * @param {num} row 探测图形的中心横坐标
102
+ * @param {num} col 探测图形的中心纵坐标
103
+ */
104
+ setupPositionProbePattern: function (row, col) {
105
+ for (var r = -1; r <= 7; r++) {
106
+ if (row + r <= -1 || this.moduleCount <= row + r) continue;
107
+ for (var c = -1; c <= 7; c++) {
108
+ if (col + c <= -1 || this.moduleCount <= col + c) continue;
109
+ if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
110
+ this.modules[row + r][col + c] = true;
111
+ } else {
112
+ this.modules[row + r][col + c] = false;
113
+ }
114
+ }
115
+ }
116
+ },
117
+ /**
118
+ * 创建二维码
119
+ * @return {[type]} [description]
120
+ */
121
+ createQrcode: function () {
122
+ var minLostPoint = 0;
123
+ var pattern = 0;
124
+ var bestModules = null;
125
+ for (var i = 0; i < 8; i++) {
126
+ this.makeImpl(i);
127
+ var lostPoint = QRUtil.getLostPoint(this);
128
+ if (i == 0 || minLostPoint > lostPoint) {
129
+ minLostPoint = lostPoint;
130
+ pattern = i;
131
+ bestModules = this.modules;
132
+ }
133
+ }
134
+ this.modules = bestModules;
135
+ this.setupTypeInfo(false, pattern);
136
+ if (this.typeNumber >= 7) {
137
+ this.setupTypeNumber(false);
138
+ }
139
+ },
140
+ /**
141
+ * 设置定位图形
142
+ * @return {[type]} [description]
143
+ */
144
+ setupTimingPattern: function () {
145
+ for (var r = 8; r < this.moduleCount - 8; r++) {
146
+ if (this.modules[r][6] != null) {
147
+ continue;
148
+ }
149
+ this.modules[r][6] = (r % 2 == 0);
150
+ if (this.modules[6][r] != null) {
151
+ continue;
152
+ }
153
+ this.modules[6][r] = (r % 2 == 0);
154
+ }
155
+ },
156
+ /**
157
+ * 设置矫正图形
158
+ * @return {[type]} [description]
159
+ */
160
+ setupPositionAdjustPattern: function () {
161
+ var pos = QRUtil.getPatternPosition(this.typeNumber);
162
+ for (var i = 0; i < pos.length; i++) {
163
+ for (var j = 0; j < pos.length; j++) {
164
+ var row = pos[i];
165
+ var col = pos[j];
166
+ if (this.modules[row][col] != null) {
167
+ continue;
168
+ }
169
+ for (var r = -2; r <= 2; r++) {
170
+ for (var c = -2; c <= 2; c++) {
171
+ if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
172
+ this.modules[row + r][col + c] = true;
173
+ } else {
174
+ this.modules[row + r][col + c] = false;
175
+ }
176
+ }
177
+ }
178
+ }
179
+ }
180
+ },
181
+ /**
182
+ * 设置版本信息(7以上版本才有)
183
+ * @param {bool} test 是否处于判断最佳掩膜阶段
184
+ * @return {[type]} [description]
185
+ */
186
+ setupTypeNumber: function (test) {
187
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
188
+ for (var i = 0; i < 18; i++) {
189
+ var mod = (!test && ((bits >> i) & 1) == 1);
190
+ this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
191
+ this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
192
+ }
193
+ },
194
+ /**
195
+ * 设置格式信息(纠错等级和掩膜版本)
196
+ * @param {bool} test
197
+ * @param {num} maskPattern 掩膜版本
198
+ * @return {}
199
+ */
200
+ setupTypeInfo: function (test, maskPattern) {
201
+ var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern;
202
+ var bits = QRUtil.getBCHTypeInfo(data);
203
+ // vertical
204
+ for (var i = 0; i < 15; i++) {
205
+ var mod = (!test && ((bits >> i) & 1) == 1);
206
+ if (i < 6) {
207
+ this.modules[i][8] = mod;
208
+ } else if (i < 8) {
209
+ this.modules[i + 1][8] = mod;
210
+ } else {
211
+ this.modules[this.moduleCount - 15 + i][8] = mod;
212
+ }
213
+ // horizontal
214
+ var mod = (!test && ((bits >> i) & 1) == 1);
215
+ if (i < 8) {
216
+ this.modules[8][this.moduleCount - i - 1] = mod;
217
+ } else if (i < 9) {
218
+ this.modules[8][15 - i - 1 + 1] = mod;
219
+ } else {
220
+ this.modules[8][15 - i - 1] = mod;
221
+ }
222
+ }
223
+ // fixed module
224
+ this.modules[this.moduleCount - 8][8] = (!test);
225
+ },
226
+ /**
227
+ * 数据编码
228
+ * @return {[type]} [description]
229
+ */
230
+ createData: function () {
231
+ var buffer = new QRBitBuffer();
232
+ var lengthBits = this.typeNumber > 9 ? 16 : 8;
233
+ buffer.put(4, 4); //添加模式
234
+ buffer.put(this.utf8bytes.length, lengthBits);
235
+ for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
236
+ buffer.put(this.utf8bytes[i], 8);
237
+ }
238
+ if (buffer.length + 4 <= this.totalDataCount * 8) {
239
+ buffer.put(0, 4);
240
+ }
241
+ // padding
242
+ while (buffer.length % 8 != 0) {
243
+ buffer.putBit(false);
244
+ }
245
+ // padding
246
+ while (true) {
247
+ if (buffer.length >= this.totalDataCount * 8) {
248
+ break;
249
+ }
250
+ buffer.put(QRCodeAlg.PAD0, 8);
251
+ if (buffer.length >= this.totalDataCount * 8) {
252
+ break;
253
+ }
254
+ buffer.put(QRCodeAlg.PAD1, 8);
255
+ }
256
+ return this.createBytes(buffer);
257
+ },
258
+ /**
259
+ * 纠错码编码
260
+ * @param {buffer} buffer 数据编码
261
+ * @return {[type]}
262
+ */
263
+ createBytes: function (buffer) {
264
+ var offset = 0;
265
+ var maxDcCount = 0;
266
+ var maxEcCount = 0;
267
+ var length = this.rsBlock.length / 3;
268
+ var rsBlocks = new Array();
269
+ for (var i = 0; i < length; i++) {
270
+ var count = this.rsBlock[i * 3 + 0];
271
+ var totalCount = this.rsBlock[i * 3 + 1];
272
+ var dataCount = this.rsBlock[i * 3 + 2];
273
+ for (var j = 0; j < count; j++) {
274
+ rsBlocks.push([dataCount, totalCount]);
275
+ }
276
+ }
277
+ var dcdata = new Array(rsBlocks.length);
278
+ var ecdata = new Array(rsBlocks.length);
279
+ for (var r = 0; r < rsBlocks.length; r++) {
280
+ var dcCount = rsBlocks[r][0];
281
+ var ecCount = rsBlocks[r][1] - dcCount;
282
+ maxDcCount = Math.max(maxDcCount, dcCount);
283
+ maxEcCount = Math.max(maxEcCount, ecCount);
284
+ dcdata[r] = new Array(dcCount);
285
+ for (var i = 0; i < dcdata[r].length; i++) {
286
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset];
287
+ }
288
+ offset += dcCount;
289
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
290
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
291
+ var modPoly = rawPoly.mod(rsPoly);
292
+ ecdata[r] = new Array(rsPoly.getLength() - 1);
293
+ for (var i = 0; i < ecdata[r].length; i++) {
294
+ var modIndex = i + modPoly.getLength() - ecdata[r].length;
295
+ ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
296
+ }
297
+ }
298
+ var data = new Array(this.totalDataCount);
299
+ var index = 0;
300
+ for (var i = 0; i < maxDcCount; i++) {
301
+ for (var r = 0; r < rsBlocks.length; r++) {
302
+ if (i < dcdata[r].length) {
303
+ data[index++] = dcdata[r][i];
304
+ }
305
+ }
306
+ }
307
+ for (var i = 0; i < maxEcCount; i++) {
308
+ for (var r = 0; r < rsBlocks.length; r++) {
309
+ if (i < ecdata[r].length) {
310
+ data[index++] = ecdata[r][i];
311
+ }
312
+ }
313
+ }
314
+ return data;
315
+
316
+ },
317
+ /**
318
+ * 布置模块,构建最终信息
319
+ * @param {} data
320
+ * @param {} maskPattern
321
+ * @return {}
322
+ */
323
+ mapData: function (data, maskPattern) {
324
+ var inc = -1;
325
+ var row = this.moduleCount - 1;
326
+ var bitIndex = 7;
327
+ var byteIndex = 0;
328
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
329
+ if (col == 6) col--;
330
+ while (true) {
331
+ for (var c = 0; c < 2; c++) {
332
+ if (this.modules[row][col - c] == null) {
333
+ var dark = false;
334
+ if (byteIndex < data.length) {
335
+ dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
336
+ }
337
+ var mask = QRUtil.getMask(maskPattern, row, col - c);
338
+ if (mask) {
339
+ dark = !dark;
340
+ }
341
+ this.modules[row][col - c] = dark;
342
+ bitIndex--;
343
+ if (bitIndex == -1) {
344
+ byteIndex++;
345
+ bitIndex = 7;
346
+ }
347
+ }
348
+ }
349
+ row += inc;
350
+ if (row < 0 || this.moduleCount <= row) {
351
+ row -= inc;
352
+ inc = -inc;
353
+ break;
354
+ }
355
+ }
356
+ }
357
+ }
358
+ };
359
+ /**
360
+ * 填充字段
361
+ */
362
+ QRCodeAlg.PAD0 = 0xEC;
363
+ QRCodeAlg.PAD1 = 0x11;
364
+ //---------------------------------------------------------------------
365
+ // 纠错等级对应的编码
366
+ //---------------------------------------------------------------------
367
+ var QRErrorCorrectLevel = [1, 0, 3, 2];
368
+ //---------------------------------------------------------------------
369
+ // 掩膜版本
370
+ //---------------------------------------------------------------------
371
+ var QRMaskPattern = {
372
+ PATTERN000: 0,
373
+ PATTERN001: 1,
374
+ PATTERN010: 2,
375
+ PATTERN011: 3,
376
+ PATTERN100: 4,
377
+ PATTERN101: 5,
378
+ PATTERN110: 6,
379
+ PATTERN111: 7
380
+ };
381
+ //---------------------------------------------------------------------
382
+ // 工具类
383
+ //---------------------------------------------------------------------
384
+ var QRUtil = {
385
+ /*
386
+ 每个版本矫正图形的位置
387
+ */
388
+ PATTERN_POSITION_TABLE: [
389
+ [],
390
+ [6, 18],
391
+ [6, 22],
392
+ [6, 26],
393
+ [6, 30],
394
+ [6, 34],
395
+ [6, 22, 38],
396
+ [6, 24, 42],
397
+ [6, 26, 46],
398
+ [6, 28, 50],
399
+ [6, 30, 54],
400
+ [6, 32, 58],
401
+ [6, 34, 62],
402
+ [6, 26, 46, 66],
403
+ [6, 26, 48, 70],
404
+ [6, 26, 50, 74],
405
+ [6, 30, 54, 78],
406
+ [6, 30, 56, 82],
407
+ [6, 30, 58, 86],
408
+ [6, 34, 62, 90],
409
+ [6, 28, 50, 72, 94],
410
+ [6, 26, 50, 74, 98],
411
+ [6, 30, 54, 78, 102],
412
+ [6, 28, 54, 80, 106],
413
+ [6, 32, 58, 84, 110],
414
+ [6, 30, 58, 86, 114],
415
+ [6, 34, 62, 90, 118],
416
+ [6, 26, 50, 74, 98, 122],
417
+ [6, 30, 54, 78, 102, 126],
418
+ [6, 26, 52, 78, 104, 130],
419
+ [6, 30, 56, 82, 108, 134],
420
+ [6, 34, 60, 86, 112, 138],
421
+ [6, 30, 58, 86, 114, 142],
422
+ [6, 34, 62, 90, 118, 146],
423
+ [6, 30, 54, 78, 102, 126, 150],
424
+ [6, 24, 50, 76, 102, 128, 154],
425
+ [6, 28, 54, 80, 106, 132, 158],
426
+ [6, 32, 58, 84, 110, 136, 162],
427
+ [6, 26, 54, 82, 110, 138, 166],
428
+ [6, 30, 58, 86, 114, 142, 170]
429
+ ],
430
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
431
+ G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
432
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
433
+ /*
434
+ BCH编码格式信息
435
+ */
436
+ getBCHTypeInfo: function (data) {
437
+ var d = data << 10;
438
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
439
+ d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
440
+ }
441
+ return ((data << 10) | d) ^ QRUtil.G15_MASK;
442
+ },
443
+ /*
444
+ BCH编码版本信息
445
+ */
446
+ getBCHTypeNumber: function (data) {
447
+ var d = data << 12;
448
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
449
+ d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
450
+ }
451
+ return (data << 12) | d;
452
+ },
453
+ /*
454
+ 获取BCH位信息
455
+ */
456
+ getBCHDigit: function (data) {
457
+ var digit = 0;
458
+ while (data != 0) {
459
+ digit++;
460
+ data >>>= 1;
461
+ }
462
+ return digit;
463
+ },
464
+ /*
465
+ 获取版本对应的矫正图形位置
466
+ */
467
+ getPatternPosition: function (typeNumber) {
468
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
469
+ },
470
+ /*
471
+ 掩膜算法
472
+ */
473
+ getMask: function (maskPattern, i, j) {
474
+ switch (maskPattern) {
475
+ case QRMaskPattern.PATTERN000:
476
+ return (i + j) % 2 == 0;
477
+ case QRMaskPattern.PATTERN001:
478
+ return i % 2 == 0;
479
+ case QRMaskPattern.PATTERN010:
480
+ return j % 3 == 0;
481
+ case QRMaskPattern.PATTERN011:
482
+ return (i + j) % 3 == 0;
483
+ case QRMaskPattern.PATTERN100:
484
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
485
+ case QRMaskPattern.PATTERN101:
486
+ return (i * j) % 2 + (i * j) % 3 == 0;
487
+ case QRMaskPattern.PATTERN110:
488
+ return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
489
+ case QRMaskPattern.PATTERN111:
490
+ return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
491
+ default:
492
+ throw new Error("bad maskPattern:" + maskPattern);
493
+ }
494
+ },
495
+ /*
496
+ 获取RS的纠错多项式
497
+ */
498
+ getErrorCorrectPolynomial: function (errorCorrectLength) {
499
+ var a = new QRPolynomial([1], 0);
500
+ for (var i = 0; i < errorCorrectLength; i++) {
501
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
502
+ }
503
+ return a;
504
+ },
505
+ /*
506
+ 获取评价
507
+ */
508
+ getLostPoint: function (qrCode) {
509
+ var moduleCount = qrCode.getModuleCount(),
510
+ lostPoint = 0,
511
+ darkCount = 0;
512
+ for (var row = 0; row < moduleCount; row++) {
513
+ var sameCount = 0;
514
+ var head = qrCode.modules[row][0];
515
+ for (var col = 0; col < moduleCount; col++) {
516
+ var current = qrCode.modules[row][col];
517
+ //level 3 评价
518
+ if (col < moduleCount - 6) {
519
+ if (current && !qrCode.modules[row][col + 1] && qrCode.modules[row][col + 2] && qrCode.modules[row][col + 3] && qrCode.modules[row][col + 4] && !qrCode.modules[row][col + 5] && qrCode.modules[row][col + 6]) {
520
+ if (col < moduleCount - 10) {
521
+ if (qrCode.modules[row][col + 7] && qrCode.modules[row][col + 8] && qrCode.modules[row][col + 9] && qrCode.modules[row][col + 10]) {
522
+ lostPoint += 40;
523
+ }
524
+ } else if (col > 3) {
525
+ if (qrCode.modules[row][col - 1] && qrCode.modules[row][col - 2] && qrCode.modules[row][col - 3] && qrCode.modules[row][col - 4]) {
526
+ lostPoint += 40;
527
+ }
528
+ }
529
+ }
530
+ }
531
+ //level 2 评价
532
+ if ((row < moduleCount - 1) && (col < moduleCount - 1)) {
533
+ var count = 0;
534
+ if (current) count++;
535
+ if (qrCode.modules[row + 1][col]) count++;
536
+ if (qrCode.modules[row][col + 1]) count++;
537
+ if (qrCode.modules[row + 1][col + 1]) count++;
538
+ if (count == 0 || count == 4) {
539
+ lostPoint += 3;
540
+ }
541
+ }
542
+ //level 1 评价
543
+ if (head ^ current) {
544
+ sameCount++;
545
+ } else {
546
+ head = current;
547
+ if (sameCount >= 5) {
548
+ lostPoint += (3 + sameCount - 5);
549
+ }
550
+ sameCount = 1;
551
+ }
552
+ //level 4 评价
553
+ if (current) {
554
+ darkCount++;
555
+ }
556
+ }
557
+ }
558
+ for (var col = 0; col < moduleCount; col++) {
559
+ var sameCount = 0;
560
+ var head = qrCode.modules[0][col];
561
+ for (var row = 0; row < moduleCount; row++) {
562
+ var current = qrCode.modules[row][col];
563
+ //level 3 评价
564
+ if (row < moduleCount - 6) {
565
+ if (current && !qrCode.modules[row + 1][col] && qrCode.modules[row + 2][col] && qrCode.modules[row + 3][col] && qrCode.modules[row + 4][col] && !qrCode.modules[row + 5][col] && qrCode.modules[row + 6][col]) {
566
+ if (row < moduleCount - 10) {
567
+ if (qrCode.modules[row + 7][col] && qrCode.modules[row + 8][col] && qrCode.modules[row + 9][col] && qrCode.modules[row + 10][col]) {
568
+ lostPoint += 40;
569
+ }
570
+ } else if (row > 3) {
571
+ if (qrCode.modules[row - 1][col] && qrCode.modules[row - 2][col] && qrCode.modules[row - 3][col] && qrCode.modules[row - 4][col]) {
572
+ lostPoint += 40;
573
+ }
574
+ }
575
+ }
576
+ }
577
+ //level 1 评价
578
+ if (head ^ current) {
579
+ sameCount++;
580
+ } else {
581
+ head = current;
582
+ if (sameCount >= 5) {
583
+ lostPoint += (3 + sameCount - 5);
584
+ }
585
+ sameCount = 1;
586
+ }
587
+ }
588
+ }
589
+ // LEVEL4
590
+ var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
591
+ lostPoint += ratio * 10;
592
+ return lostPoint;
593
+ }
594
+
595
+ };
596
+ //---------------------------------------------------------------------
597
+ // QRMath使用的数学工具
598
+ //---------------------------------------------------------------------
599
+ var QRMath = {
600
+ /*
601
+ 将n转化为a^m
602
+ */
603
+ glog: function (n) {
604
+ if (n < 1) {
605
+ throw new Error("glog(" + n + ")");
606
+ }
607
+ return QRMath.LOG_TABLE[n];
608
+ },
609
+ /*
610
+ 将a^m转化为n
611
+ */
612
+ gexp: function (n) {
613
+ while (n < 0) {
614
+ n += 255;
615
+ }
616
+ while (n >= 256) {
617
+ n -= 255;
618
+ }
619
+ return QRMath.EXP_TABLE[n];
620
+ },
621
+ EXP_TABLE: new Array(256),
622
+ LOG_TABLE: new Array(256)
623
+
624
+ };
625
+ for (var i = 0; i < 8; i++) {
626
+ QRMath.EXP_TABLE[i] = 1 << i;
627
+ }
628
+ for (var i = 8; i < 256; i++) {
629
+ QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8];
630
+ }
631
+ for (var i = 0; i < 255; i++) {
632
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
633
+ }
634
+ //---------------------------------------------------------------------
635
+ // QRPolynomial 多项式
636
+ //---------------------------------------------------------------------
637
+ /**
638
+ * 多项式类
639
+ * @param {Array} num 系数
640
+ * @param {num} shift a^shift
641
+ */
642
+ function QRPolynomial(num, shift) {
643
+ if (num.length == undefined) {
644
+ throw new Error(num.length + "/" + shift);
645
+ }
646
+ var offset = 0;
647
+ while (offset < num.length && num[offset] == 0) {
648
+ offset++;
649
+ }
650
+ this.num = new Array(num.length - offset + shift);
651
+ for (var i = 0; i < num.length - offset; i++) {
652
+ this.num[i] = num[i + offset];
653
+ }
654
+ }
655
+ QRPolynomial.prototype = {
656
+ get: function (index) {
657
+ return this.num[index];
658
+ },
659
+ getLength: function () {
660
+ return this.num.length;
661
+ },
662
+ /**
663
+ * 多项式乘法
664
+ * @param {QRPolynomial} e 被乘多项式
665
+ * @return {[type]} [description]
666
+ */
667
+ multiply: function (e) {
668
+ var num = new Array(this.getLength() + e.getLength() - 1);
669
+ for (var i = 0; i < this.getLength(); i++) {
670
+ for (var j = 0; j < e.getLength(); j++) {
671
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
672
+ }
673
+ }
674
+ return new QRPolynomial(num, 0);
675
+ },
676
+ /**
677
+ * 多项式模运算
678
+ * @param {QRPolynomial} e 模多项式
679
+ * @return {}
680
+ */
681
+ mod: function (e) {
682
+ var tl = this.getLength(),
683
+ el = e.getLength();
684
+ if (tl - el < 0) {
685
+ return this;
686
+ }
687
+ var num = new Array(tl);
688
+ for (var i = 0; i < tl; i++) {
689
+ num[i] = this.get(i);
690
+ }
691
+ while (num.length >= el) {
692
+ var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0));
693
+
694
+ for (var i = 0; i < e.getLength(); i++) {
695
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
696
+ }
697
+ while (num[0] == 0) {
698
+ num.shift();
699
+ }
700
+ }
701
+ return new QRPolynomial(num, 0);
702
+ }
703
+ };
704
+
705
+ //---------------------------------------------------------------------
706
+ // RS_BLOCK_TABLE
707
+ //---------------------------------------------------------------------
708
+ /*
709
+ 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
710
+ */
711
+ var RS_BLOCK_TABLE = [
712
+ // L
713
+ // M
714
+ // Q
715
+ // H
716
+ // 1
717
+ [1, 26, 19],
718
+ [1, 26, 16],
719
+ [1, 26, 13],
720
+ [1, 26, 9],
721
+
722
+ // 2
723
+ [1, 44, 34],
724
+ [1, 44, 28],
725
+ [1, 44, 22],
726
+ [1, 44, 16],
727
+
728
+ // 3
729
+ [1, 70, 55],
730
+ [1, 70, 44],
731
+ [2, 35, 17],
732
+ [2, 35, 13],
733
+
734
+ // 4
735
+ [1, 100, 80],
736
+ [2, 50, 32],
737
+ [2, 50, 24],
738
+ [4, 25, 9],
739
+
740
+ // 5
741
+ [1, 134, 108],
742
+ [2, 67, 43],
743
+ [2, 33, 15, 2, 34, 16],
744
+ [2, 33, 11, 2, 34, 12],
745
+
746
+ // 6
747
+ [2, 86, 68],
748
+ [4, 43, 27],
749
+ [4, 43, 19],
750
+ [4, 43, 15],
751
+
752
+ // 7
753
+ [2, 98, 78],
754
+ [4, 49, 31],
755
+ [2, 32, 14, 4, 33, 15],
756
+ [4, 39, 13, 1, 40, 14],
757
+
758
+ // 8
759
+ [2, 121, 97],
760
+ [2, 60, 38, 2, 61, 39],
761
+ [4, 40, 18, 2, 41, 19],
762
+ [4, 40, 14, 2, 41, 15],
763
+
764
+ // 9
765
+ [2, 146, 116],
766
+ [3, 58, 36, 2, 59, 37],
767
+ [4, 36, 16, 4, 37, 17],
768
+ [4, 36, 12, 4, 37, 13],
769
+
770
+ // 10
771
+ [2, 86, 68, 2, 87, 69],
772
+ [4, 69, 43, 1, 70, 44],
773
+ [6, 43, 19, 2, 44, 20],
774
+ [6, 43, 15, 2, 44, 16],
775
+
776
+ // 11
777
+ [4, 101, 81],
778
+ [1, 80, 50, 4, 81, 51],
779
+ [4, 50, 22, 4, 51, 23],
780
+ [3, 36, 12, 8, 37, 13],
781
+
782
+ // 12
783
+ [2, 116, 92, 2, 117, 93],
784
+ [6, 58, 36, 2, 59, 37],
785
+ [4, 46, 20, 6, 47, 21],
786
+ [7, 42, 14, 4, 43, 15],
787
+
788
+ // 13
789
+ [4, 133, 107],
790
+ [8, 59, 37, 1, 60, 38],
791
+ [8, 44, 20, 4, 45, 21],
792
+ [12, 33, 11, 4, 34, 12],
793
+
794
+ // 14
795
+ [3, 145, 115, 1, 146, 116],
796
+ [4, 64, 40, 5, 65, 41],
797
+ [11, 36, 16, 5, 37, 17],
798
+ [11, 36, 12, 5, 37, 13],
799
+
800
+ // 15
801
+ [5, 109, 87, 1, 110, 88],
802
+ [5, 65, 41, 5, 66, 42],
803
+ [5, 54, 24, 7, 55, 25],
804
+ [11, 36, 12],
805
+
806
+ // 16
807
+ [5, 122, 98, 1, 123, 99],
808
+ [7, 73, 45, 3, 74, 46],
809
+ [15, 43, 19, 2, 44, 20],
810
+ [3, 45, 15, 13, 46, 16],
811
+
812
+ // 17
813
+ [1, 135, 107, 5, 136, 108],
814
+ [10, 74, 46, 1, 75, 47],
815
+ [1, 50, 22, 15, 51, 23],
816
+ [2, 42, 14, 17, 43, 15],
817
+
818
+ // 18
819
+ [5, 150, 120, 1, 151, 121],
820
+ [9, 69, 43, 4, 70, 44],
821
+ [17, 50, 22, 1, 51, 23],
822
+ [2, 42, 14, 19, 43, 15],
823
+
824
+ // 19
825
+ [3, 141, 113, 4, 142, 114],
826
+ [3, 70, 44, 11, 71, 45],
827
+ [17, 47, 21, 4, 48, 22],
828
+ [9, 39, 13, 16, 40, 14],
829
+
830
+ // 20
831
+ [3, 135, 107, 5, 136, 108],
832
+ [3, 67, 41, 13, 68, 42],
833
+ [15, 54, 24, 5, 55, 25],
834
+ [15, 43, 15, 10, 44, 16],
835
+
836
+ // 21
837
+ [4, 144, 116, 4, 145, 117],
838
+ [17, 68, 42],
839
+ [17, 50, 22, 6, 51, 23],
840
+ [19, 46, 16, 6, 47, 17],
841
+
842
+ // 22
843
+ [2, 139, 111, 7, 140, 112],
844
+ [17, 74, 46],
845
+ [7, 54, 24, 16, 55, 25],
846
+ [34, 37, 13],
847
+
848
+ // 23
849
+ [4, 151, 121, 5, 152, 122],
850
+ [4, 75, 47, 14, 76, 48],
851
+ [11, 54, 24, 14, 55, 25],
852
+ [16, 45, 15, 14, 46, 16],
853
+
854
+ // 24
855
+ [6, 147, 117, 4, 148, 118],
856
+ [6, 73, 45, 14, 74, 46],
857
+ [11, 54, 24, 16, 55, 25],
858
+ [30, 46, 16, 2, 47, 17],
859
+
860
+ // 25
861
+ [8, 132, 106, 4, 133, 107],
862
+ [8, 75, 47, 13, 76, 48],
863
+ [7, 54, 24, 22, 55, 25],
864
+ [22, 45, 15, 13, 46, 16],
865
+
866
+ // 26
867
+ [10, 142, 114, 2, 143, 115],
868
+ [19, 74, 46, 4, 75, 47],
869
+ [28, 50, 22, 6, 51, 23],
870
+ [33, 46, 16, 4, 47, 17],
871
+
872
+ // 27
873
+ [8, 152, 122, 4, 153, 123],
874
+ [22, 73, 45, 3, 74, 46],
875
+ [8, 53, 23, 26, 54, 24],
876
+ [12, 45, 15, 28, 46, 16],
877
+
878
+ // 28
879
+ [3, 147, 117, 10, 148, 118],
880
+ [3, 73, 45, 23, 74, 46],
881
+ [4, 54, 24, 31, 55, 25],
882
+ [11, 45, 15, 31, 46, 16],
883
+
884
+ // 29
885
+ [7, 146, 116, 7, 147, 117],
886
+ [21, 73, 45, 7, 74, 46],
887
+ [1, 53, 23, 37, 54, 24],
888
+ [19, 45, 15, 26, 46, 16],
889
+
890
+ // 30
891
+ [5, 145, 115, 10, 146, 116],
892
+ [19, 75, 47, 10, 76, 48],
893
+ [15, 54, 24, 25, 55, 25],
894
+ [23, 45, 15, 25, 46, 16],
895
+
896
+ // 31
897
+ [13, 145, 115, 3, 146, 116],
898
+ [2, 74, 46, 29, 75, 47],
899
+ [42, 54, 24, 1, 55, 25],
900
+ [23, 45, 15, 28, 46, 16],
901
+
902
+ // 32
903
+ [17, 145, 115],
904
+ [10, 74, 46, 23, 75, 47],
905
+ [10, 54, 24, 35, 55, 25],
906
+ [19, 45, 15, 35, 46, 16],
907
+
908
+ // 33
909
+ [17, 145, 115, 1, 146, 116],
910
+ [14, 74, 46, 21, 75, 47],
911
+ [29, 54, 24, 19, 55, 25],
912
+ [11, 45, 15, 46, 46, 16],
913
+
914
+ // 34
915
+ [13, 145, 115, 6, 146, 116],
916
+ [14, 74, 46, 23, 75, 47],
917
+ [44, 54, 24, 7, 55, 25],
918
+ [59, 46, 16, 1, 47, 17],
919
+
920
+ // 35
921
+ [12, 151, 121, 7, 152, 122],
922
+ [12, 75, 47, 26, 76, 48],
923
+ [39, 54, 24, 14, 55, 25],
924
+ [22, 45, 15, 41, 46, 16],
925
+
926
+ // 36
927
+ [6, 151, 121, 14, 152, 122],
928
+ [6, 75, 47, 34, 76, 48],
929
+ [46, 54, 24, 10, 55, 25],
930
+ [2, 45, 15, 64, 46, 16],
931
+
932
+ // 37
933
+ [17, 152, 122, 4, 153, 123],
934
+ [29, 74, 46, 14, 75, 47],
935
+ [49, 54, 24, 10, 55, 25],
936
+ [24, 45, 15, 46, 46, 16],
937
+
938
+ // 38
939
+ [4, 152, 122, 18, 153, 123],
940
+ [13, 74, 46, 32, 75, 47],
941
+ [48, 54, 24, 14, 55, 25],
942
+ [42, 45, 15, 32, 46, 16],
943
+
944
+ // 39
945
+ [20, 147, 117, 4, 148, 118],
946
+ [40, 75, 47, 7, 76, 48],
947
+ [43, 54, 24, 22, 55, 25],
948
+ [10, 45, 15, 67, 46, 16],
949
+
950
+ // 40
951
+ [19, 148, 118, 6, 149, 119],
952
+ [18, 75, 47, 31, 76, 48],
953
+ [34, 54, 24, 34, 55, 25],
954
+ [20, 45, 15, 61, 46, 16]
955
+ ];
956
+
957
+ /**
958
+ * 根据数据获取对应版本
959
+ * @return {[type]} [description]
960
+ */
961
+ QRCodeAlg.prototype.getRightType = function () {
962
+ for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
963
+ var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel];
964
+ if (rsBlock == undefined) {
965
+ throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + this.errorCorrectLevel);
966
+ }
967
+ var length = rsBlock.length / 3;
968
+ var totalDataCount = 0;
969
+ for (var i = 0; i < length; i++) {
970
+ var count = rsBlock[i * 3 + 0];
971
+ var dataCount = rsBlock[i * 3 + 2];
972
+ totalDataCount += dataCount * count;
973
+ }
974
+ var lengthBytes = typeNumber > 9 ? 2 : 1;
975
+ if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
976
+ this.typeNumber = typeNumber;
977
+ this.rsBlock = rsBlock;
978
+ this.totalDataCount = totalDataCount;
979
+ break;
980
+ }
981
+ }
982
+ };
983
+
984
+ //---------------------------------------------------------------------
985
+ // QRBitBuffer
986
+ //---------------------------------------------------------------------
987
+ function QRBitBuffer() {
988
+ this.buffer = new Array();
989
+ this.length = 0;
990
+ }
991
+ QRBitBuffer.prototype = {
992
+ get: function (index) {
993
+ var bufIndex = Math.floor(index / 8);
994
+ return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1);
995
+ },
996
+ put: function (num, length) {
997
+ for (var i = 0; i < length; i++) {
998
+ this.putBit(((num >>> (length - i - 1)) & 1));
999
+ }
1000
+ },
1001
+ putBit: function (bit) {
1002
+ var bufIndex = Math.floor(this.length / 8);
1003
+ if (this.buffer.length <= bufIndex) {
1004
+ this.buffer.push(0);
1005
+ }
1006
+ if (bit) {
1007
+ this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
1008
+ }
1009
+ this.length++;
1010
+ }
1011
+ };
1012
+
1013
+
1014
+
1015
+ // xzedit
1016
+ let qrcodeAlgObjCache = [];
1017
+ /**
1018
+ * 二维码构造函数,主要用于绘制
1019
+ * @param {参数列表} opt 传递参数
1020
+ * @return {}
1021
+ */
1022
+ QRCode = function (opt) {
1023
+ //设置默认参数
1024
+ this.options = {
1025
+ text: '',
1026
+ size: 256,
1027
+ correctLevel: 3,
1028
+ background: '#ffffff',
1029
+ foreground: '#000000',
1030
+ pdground: '#000000',
1031
+ image: '',
1032
+ imageSize: 30,
1033
+ canvasId: opt.canvasId,
1034
+ context: opt.context,
1035
+ usingComponents: opt.usingComponents,
1036
+ showLoading: opt.showLoading,
1037
+ loadingText: opt.loadingText,
1038
+ };
1039
+ if (typeof opt === 'string') { // 只编码ASCII字符串
1040
+ opt = {
1041
+ text: opt
1042
+ };
1043
+ }
1044
+ if (opt) {
1045
+ for (var i in opt) {
1046
+ this.options[i] = opt[i];
1047
+ }
1048
+ }
1049
+ //使用QRCodeAlg创建二维码结构
1050
+ var qrCodeAlg = null;
1051
+ for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1052
+ if (qrcodeAlgObjCache[i].text == this.options.text && qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel) {
1053
+ qrCodeAlg = qrcodeAlgObjCache[i].obj;
1054
+ break;
1055
+ }
1056
+ }
1057
+ if (i == l) {
1058
+ qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel);
1059
+ qrcodeAlgObjCache.push({
1060
+ text: this.options.text,
1061
+ correctLevel: this.options.correctLevel,
1062
+ obj: qrCodeAlg
1063
+ });
1064
+ }
1065
+ /**
1066
+ * 计算矩阵点的前景色
1067
+ * @param {Obj} config
1068
+ * @param {Number} config.row 点x坐标
1069
+ * @param {Number} config.col 点y坐标
1070
+ * @param {Number} config.count 矩阵大小
1071
+ * @param {Number} config.options 组件的options
1072
+ * @return {String}
1073
+ */
1074
+ let getForeGround = function (config) {
1075
+ var options = config.options;
1076
+ if (options.pdground && (
1077
+ (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1078
+ (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) ||
1079
+ (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2))
1080
+ )) {
1081
+ return options.pdground;
1082
+ }
1083
+ return options.foreground;
1084
+ }
1085
+ // 创建canvas
1086
+ let createCanvas = function (options) {
1087
+ if(options.showLoading){
1088
+ uni.showLoading({
1089
+ title: options.loadingText,
1090
+ mask: true
1091
+ });
1092
+ }
1093
+ var ctx = uni.createCanvasContext(options.canvasId, options.context);
1094
+ var count = qrCodeAlg.getModuleCount();
1095
+ var ratioSize = options.size;
1096
+ var ratioImgSize = options.imageSize;
1097
+ //计算每个点的长宽
1098
+ var tileW = (ratioSize / count).toPrecision(4);
1099
+ var tileH = (ratioSize / count).toPrecision(4);
1100
+ //绘制
1101
+ for (var row = 0; row < count; row++) {
1102
+ for (var col = 0; col < count; col++) {
1103
+ var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
1104
+ var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
1105
+ var foreground = getForeGround({
1106
+ row: row,
1107
+ col: col,
1108
+ count: count,
1109
+ options: options
1110
+ });
1111
+ ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background);
1112
+ ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
1113
+ }
1114
+ }
1115
+ if (options.image) {
1116
+ var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
1117
+ var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
1118
+ drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1119
+ ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
1120
+ // 画圆角矩形
1121
+ function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1122
+ ctxi.setLineWidth(lineWidth);
1123
+ ctxi.setFillStyle(options.background);
1124
+ ctxi.setStrokeStyle(options.background);
1125
+ ctxi.beginPath(); // draw top and top right corner
1126
+ ctxi.moveTo(x + r, y);
1127
+ ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner
1128
+ ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner
1129
+ ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner
1130
+ ctxi.arcTo(x, y, x + r, y, r);
1131
+ ctxi.closePath();
1132
+ if (fill) {
1133
+ ctxi.fill();
1134
+ }
1135
+ if (stroke) {
1136
+ ctxi.stroke();
1137
+ }
1138
+ }
1139
+ }
1140
+ setTimeout(() => {
1141
+ ctx.draw(true, () => {
1142
+ // 保存到临时区域
1143
+ setTimeout(() => {
1144
+ uni.canvasToTempFilePath({
1145
+ width: options.width,
1146
+ height: options.height,
1147
+ destWidth: options.width,
1148
+ destHeight: options.height,
1149
+ canvasId: options.canvasId,
1150
+ quality: Number(1),
1151
+ success: function (res) {
1152
+ if (options.cbResult) {
1153
+ // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1154
+ if (!empty(res.tempFilePath)) {
1155
+ options.cbResult(res.tempFilePath)
1156
+ } else if (!empty(res.apFilePath)) {
1157
+ options.cbResult(res.apFilePath)
1158
+ } else {
1159
+ options.cbResult(res.tempFilePath)
1160
+ }
1161
+ }
1162
+ },
1163
+ fail: function (res) {
1164
+ if (options.cbResult) {
1165
+ options.cbResult(res)
1166
+ }
1167
+ },
1168
+ complete: function () {
1169
+ uni.hideLoading();
1170
+ },
1171
+ }, options.context);
1172
+ }, options.text.length + 100);
1173
+ });
1174
+ }, options.usingComponents ? 0 : 150);
1175
+ }
1176
+ createCanvas(this.options);
1177
+ // 空判定
1178
+ let empty = function (v) {
1179
+ let tp = typeof v,
1180
+ rt = false;
1181
+ if (tp == "number" && String(v) == "") {
1182
+ rt = true
1183
+ } else if (tp == "undefined") {
1184
+ rt = true
1185
+ } else if (tp == "object") {
1186
+ if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
1187
+ } else if (tp == "string") {
1188
+ if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
1189
+ } else if (tp == "function") {
1190
+ rt = false
1191
+ }
1192
+ return rt
1193
+ }
1194
+ };
1195
+ QRCode.prototype.clear = function (fn) {
1196
+ var ctx = uni.createCanvasContext(this.options.canvasId, this.options.context)
1197
+ ctx.clearRect(0, 0, this.options.size, this.options.size)
1198
+ ctx.draw(false, () => {
1199
+ if (fn) {
1200
+ fn()
1201
+ }
1202
+ })
1203
+ };
1204
+ })()
1205
+
1206
+ export default QRCode