hy-app 0.5.1 → 0.5.3

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 (39) hide show
  1. package/components/hy-action-sheet/index.scss +0 -5
  2. package/components/hy-back-top/hy-back-top.vue +10 -9
  3. package/components/hy-back-top/props.ts +5 -3
  4. package/components/hy-badge/hy-badge.vue +2 -1
  5. package/components/hy-badge/props.ts +5 -3
  6. package/components/hy-button/hy-button.vue +5 -5
  7. package/components/hy-button/index.scss +9 -0
  8. package/components/hy-button/props.ts +11 -6
  9. package/components/hy-coupon/hy-coupon.vue +159 -167
  10. package/components/hy-coupon/index.scss +130 -516
  11. package/components/hy-coupon/props.ts +98 -127
  12. package/components/hy-coupon/typing.d.ts +147 -146
  13. package/components/hy-folding-panel-item/hy-folding-panel-item.vue +1 -3
  14. package/components/hy-folding-panel-item/index.scss +0 -8
  15. package/components/hy-form-group/hy-form-group.vue +308 -511
  16. package/components/hy-form-group/index.scss +0 -33
  17. package/components/hy-form-group/props.ts +103 -13
  18. package/components/hy-form-group/typing.d.ts +0 -77
  19. package/components/hy-form-item/hy-form-item.vue +3 -3
  20. package/components/hy-input/hy-input.vue +16 -10
  21. package/components/hy-input/index.scss +4 -0
  22. package/components/hy-input/props.ts +2 -2
  23. package/components/hy-notice-bar/hy-column-notice.vue +63 -70
  24. package/components/hy-notice-bar/hy-row-notice.vue +92 -110
  25. package/components/hy-notice-bar/index.scss +2 -4
  26. package/components/hy-notice-bar/props.ts +4 -1
  27. package/components/hy-qrcode/hy-qrcode.vue +1 -1
  28. package/components/hy-qrcode/index.scss +1 -0
  29. package/components/hy-qrcode/qrcode.js +1208 -1402
  30. package/components/hy-rate/hy-rate.vue +0 -1
  31. package/components/hy-read-more/hy-read-more.vue +1 -1
  32. package/components/hy-textarea/hy-textarea.vue +1 -1
  33. package/components/hy-textarea/index.scss +8 -7
  34. package/components/hy-toast/index.scss +2 -7
  35. package/libs/css/common.scss +0 -5
  36. package/libs/typing/modules/form.ts +159 -163
  37. package/package.json +2 -2
  38. package/web-types.json +1 -1
  39. package/components/hy-coupon/README.md +0 -133
@@ -1,1498 +1,1304 @@
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 (
110
- (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
- (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
- (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
- ) {
114
- this.modules[row + r][col + c] = true;
115
- } else {
116
- this.modules[row + r][col + c] = false;
117
- }
118
- }
119
- }
120
- },
121
- /**
122
- * 创建二维码
123
- * @return {[type]} [description]
124
- */
125
- createQrcode: function () {
126
- var minLostPoint = 0;
127
- var pattern = 0;
128
- var bestModules = null;
129
- for (var i = 0; i < 8; i++) {
130
- this.makeImpl(i);
131
- var lostPoint = QRUtil.getLostPoint(this);
132
- if (i == 0 || minLostPoint > lostPoint) {
133
- minLostPoint = lostPoint;
134
- pattern = i;
135
- bestModules = this.modules;
136
- }
137
- }
138
- this.modules = bestModules;
139
- this.setupTypeInfo(false, pattern);
140
- if (this.typeNumber >= 7) {
141
- this.setupTypeNumber(false);
142
- }
143
- },
144
- /**
145
- * 设置定位图形
146
- * @return {[type]} [description]
147
- */
148
- setupTimingPattern: function () {
149
- for (var r = 8; r < this.moduleCount - 8; r++) {
150
- if (this.modules[r][6] != null) {
151
- continue;
152
- }
153
- this.modules[r][6] = r % 2 == 0;
154
- if (this.modules[6][r] != null) {
155
- continue;
156
- }
157
- this.modules[6][r] = r % 2 == 0;
158
- }
159
- },
160
- /**
161
- * 设置矫正图形
162
- * @return {[type]} [description]
163
- */
164
- setupPositionAdjustPattern: function () {
165
- var pos = QRUtil.getPatternPosition(this.typeNumber);
166
- for (var i = 0; i < pos.length; i++) {
167
- for (var j = 0; j < pos.length; j++) {
168
- var row = pos[i];
169
- var col = pos[j];
170
- if (this.modules[row][col] != null) {
171
- continue;
172
- }
173
- for (var r = -2; r <= 2; r++) {
174
- for (var c = -2; c <= 2; c++) {
175
- if (
176
- r == -2 ||
177
- r == 2 ||
178
- c == -2 ||
179
- c == 2 ||
180
- (r == 0 && c == 0)
181
- ) {
182
- this.modules[row + r][col + c] = true;
183
- } else {
184
- this.modules[row + r][col + c] = false;
185
- }
186
- }
187
- }
188
- }
189
- }
190
- },
191
- /**
192
- * 设置版本信息(7以上版本才有)
193
- * @param {bool} test 是否处于判断最佳掩膜阶段
194
- * @return {[type]} [description]
195
- */
196
- setupTypeNumber: function (test) {
197
- var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
198
- for (var i = 0; i < 18; i++) {
199
- var mod = !test && ((bits >> i) & 1) == 1;
200
- this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] =
201
- mod;
202
- this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] =
203
- mod;
204
- }
205
- },
1
+ let QRCode = {}
2
+ ;(function () {
206
3
  /**
207
- * 设置格式信息(纠错等级和掩膜版本)
208
- * @param {bool} test
209
- * @param {num} maskPattern 掩膜版本
210
- * @return {}
4
+ * 获取单个字符的utf8编码
5
+ * unicode BMP平面约65535个字符
6
+ * @param {num} code
7
+ * return {array}
211
8
  */
212
- setupTypeInfo: function (test, maskPattern) {
213
- var data =
214
- (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern;
215
- var bits = QRUtil.getBCHTypeInfo(data);
216
- // vertical
217
- for (var i = 0; i < 15; i++) {
218
- var mod = !test && ((bits >> i) & 1) == 1;
219
- if (i < 6) {
220
- this.modules[i][8] = mod;
221
- } else if (i < 8) {
222
- this.modules[i + 1][8] = mod;
223
- } else {
224
- this.modules[this.moduleCount - 15 + i][8] = mod;
225
- }
226
- // horizontal
227
- var mod = !test && ((bits >> i) & 1) == 1;
228
- if (i < 8) {
229
- this.modules[8][this.moduleCount - i - 1] = mod;
230
- } else if (i < 9) {
231
- this.modules[8][15 - i - 1 + 1] = mod;
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
232
20
  } else {
233
- this.modules[8][15 - i - 1] = mod;
234
- }
235
- }
236
- // fixed module
237
- this.modules[this.moduleCount - 8][8] = !test;
238
- },
239
- /**
240
- * 数据编码
241
- * @return {[type]} [description]
242
- */
243
- createData: function () {
244
- var buffer = new QRBitBuffer();
245
- var lengthBits = this.typeNumber > 9 ? 16 : 8;
246
- buffer.put(4, 4); //添加模式
247
- buffer.put(this.utf8bytes.length, lengthBits);
248
- for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
249
- buffer.put(this.utf8bytes[i], 8);
250
- }
251
- if (buffer.length + 4 <= this.totalDataCount * 8) {
252
- buffer.put(0, 4);
253
- }
254
- // padding
255
- while (buffer.length % 8 != 0) {
256
- buffer.putBit(false);
257
- }
258
- // padding
259
- while (true) {
260
- if (buffer.length >= this.totalDataCount * 8) {
261
- break;
21
+ c0 = 224 + (code >> 12)
22
+ c1 = 128 + ((code >> 6) & 63)
23
+ c2 = 128 + (code & 63)
24
+ return [c0, c1, c2]
262
25
  }
263
- buffer.put(QRCodeAlg.PAD0, 8);
264
- if (buffer.length >= this.totalDataCount * 8) {
265
- break;
266
- }
267
- buffer.put(QRCodeAlg.PAD1, 8);
268
- }
269
- return this.createBytes(buffer);
270
- },
26
+ }
271
27
  /**
272
- * 纠错码编码
273
- * @param {buffer} buffer 数据编码
274
- * @return {[type]}
28
+ * 获取字符串的utf8编码字节串
29
+ * @param {string} string
30
+ * @return {array}
275
31
  */
276
- createBytes: function (buffer) {
277
- var offset = 0;
278
- var maxDcCount = 0;
279
- var maxEcCount = 0;
280
- var length = this.rsBlock.length / 3;
281
- var rsBlocks = new Array();
282
- for (var i = 0; i < length; i++) {
283
- var count = this.rsBlock[i * 3 + 0];
284
- var totalCount = this.rsBlock[i * 3 + 1];
285
- var dataCount = this.rsBlock[i * 3 + 2];
286
- for (var j = 0; j < count; j++) {
287
- rsBlocks.push([dataCount, totalCount]);
288
- }
289
- }
290
- var dcdata = new Array(rsBlocks.length);
291
- var ecdata = new Array(rsBlocks.length);
292
- for (var r = 0; r < rsBlocks.length; r++) {
293
- var dcCount = rsBlocks[r][0];
294
- var ecCount = rsBlocks[r][1] - dcCount;
295
- maxDcCount = Math.max(maxDcCount, dcCount);
296
- maxEcCount = Math.max(maxEcCount, ecCount);
297
- dcdata[r] = new Array(dcCount);
298
- for (var i = 0; i < dcdata[r].length; i++) {
299
- dcdata[r][i] = 0xff & buffer.buffer[i + offset];
300
- }
301
- offset += dcCount;
302
- var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
303
- var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
304
- var modPoly = rawPoly.mod(rsPoly);
305
- ecdata[r] = new Array(rsPoly.getLength() - 1);
306
- for (var i = 0; i < ecdata[r].length; i++) {
307
- var modIndex = i + modPoly.getLength() - ecdata[r].length;
308
- ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
309
- }
310
- }
311
- var data = new Array(this.totalDataCount);
312
- var index = 0;
313
- for (var i = 0; i < maxDcCount; i++) {
314
- for (var r = 0; r < rsBlocks.length; r++) {
315
- if (i < dcdata[r].length) {
316
- data[index++] = dcdata[r][i];
317
- }
318
- }
319
- }
320
- for (var i = 0; i < maxEcCount; i++) {
321
- for (var r = 0; r < rsBlocks.length; r++) {
322
- if (i < ecdata[r].length) {
323
- data[index++] = ecdata[r][i];
324
- }
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
+ }
325
40
  }
326
- }
327
- return data;
328
- },
41
+ return utf8codes
42
+ }
329
43
  /**
330
- * 布置模块,构建最终信息
331
- * @param {} data
332
- * @param {} maskPattern
333
- * @return {}
44
+ * 二维码算法实现
45
+ * @param {string} data 要编码的信息字符串
46
+ * @param {num} errorCorrectLevel 纠错等级
334
47
  */
335
- mapData: function (data, maskPattern) {
336
- var inc = -1;
337
- var row = this.moduleCount - 1;
338
- var bitIndex = 7;
339
- var byteIndex = 0;
340
- for (var col = this.moduleCount - 1; col > 0; col -= 2) {
341
- if (col == 6) col--;
342
- while (true) {
343
- for (var c = 0; c < 2; c++) {
344
- if (this.modules[row][col - c] == null) {
345
- var dark = false;
346
- if (byteIndex < data.length) {
347
- dark = ((data[byteIndex] >>> bitIndex) & 1) == 1;
348
- }
349
- var mask = QRUtil.getMask(maskPattern, row, col - c);
350
- if (mask) {
351
- dark = !dark;
352
- }
353
- this.modules[row][col - c] = dark;
354
- bitIndex--;
355
- if (bitIndex == -1) {
356
- byteIndex++;
357
- bitIndex = 7;
358
- }
359
- }
360
- }
361
- row += inc;
362
- if (row < 0 || this.moduleCount <= row) {
363
- row -= inc;
364
- inc = -inc;
365
- break;
366
- }
367
- }
368
- }
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()
369
59
  }
370
- };
371
- /**
372
- * 填充字段
373
- */
374
- QRCodeAlg.PAD0 = 0xec;
375
- QRCodeAlg.PAD1 = 0x11;
376
- //---------------------------------------------------------------------
377
- // 纠错等级对应的编码
378
- //---------------------------------------------------------------------
379
- var QRErrorCorrectLevel = [1, 0, 3, 2];
380
- //---------------------------------------------------------------------
381
- // 掩膜版本
382
- //---------------------------------------------------------------------
383
- var QRMaskPattern = {
384
- PATTERN000: 0,
385
- PATTERN001: 1,
386
- PATTERN010: 2,
387
- PATTERN011: 3,
388
- PATTERN100: 4,
389
- PATTERN101: 5,
390
- PATTERN110: 6,
391
- PATTERN111: 7
392
- };
393
- //---------------------------------------------------------------------
394
- // 工具类
395
- //---------------------------------------------------------------------
396
- var QRUtil = {
397
- /*
398
- 每个版本矫正图形的位置
60
+ QRCodeAlg.prototype = {
61
+ constructor: QRCodeAlg,
62
+ /**
63
+ * 获取二维码矩阵大小
64
+ * @return {num} 矩阵大小
399
65
  */
400
- PATTERN_POSITION_TABLE: [
401
- [],
402
- [6, 18],
403
- [6, 22],
404
- [6, 26],
405
- [6, 30],
406
- [6, 34],
407
- [6, 22, 38],
408
- [6, 24, 42],
409
- [6, 26, 46],
410
- [6, 28, 50],
411
- [6, 30, 54],
412
- [6, 32, 58],
413
- [6, 34, 62],
414
- [6, 26, 46, 66],
415
- [6, 26, 48, 70],
416
- [6, 26, 50, 74],
417
- [6, 30, 54, 78],
418
- [6, 30, 56, 82],
419
- [6, 30, 58, 86],
420
- [6, 34, 62, 90],
421
- [6, 28, 50, 72, 94],
422
- [6, 26, 50, 74, 98],
423
- [6, 30, 54, 78, 102],
424
- [6, 28, 54, 80, 106],
425
- [6, 32, 58, 84, 110],
426
- [6, 30, 58, 86, 114],
427
- [6, 34, 62, 90, 118],
428
- [6, 26, 50, 74, 98, 122],
429
- [6, 30, 54, 78, 102, 126],
430
- [6, 26, 52, 78, 104, 130],
431
- [6, 30, 56, 82, 108, 134],
432
- [6, 34, 60, 86, 112, 138],
433
- [6, 30, 58, 86, 114, 142],
434
- [6, 34, 62, 90, 118, 146],
435
- [6, 30, 54, 78, 102, 126, 150],
436
- [6, 24, 50, 76, 102, 128, 154],
437
- [6, 28, 54, 80, 106, 132, 158],
438
- [6, 32, 58, 84, 110, 136, 162],
439
- [6, 26, 54, 82, 110, 138, 166],
440
- [6, 30, 58, 86, 114, 142, 170]
441
- ],
442
- G15:
443
- (1 << 10) |
444
- (1 << 8) |
445
- (1 << 5) |
446
- (1 << 4) |
447
- (1 << 2) |
448
- (1 << 1) |
449
- (1 << 0),
450
- G18:
451
- (1 << 12) |
452
- (1 << 11) |
453
- (1 << 10) |
454
- (1 << 9) |
455
- (1 << 8) |
456
- (1 << 5) |
457
- (1 << 2) |
458
- (1 << 0),
459
- G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
460
- /*
461
- BCH编码格式信息
66
+ getModuleCount: function () {
67
+ return this.moduleCount
68
+ },
69
+ /**
70
+ * 编码
462
71
  */
463
- getBCHTypeInfo: function (data) {
464
- var d = data << 10;
465
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
466
- d ^=
467
- QRUtil.G15 <<
468
- (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15));
469
- }
470
- return ((data << 10) | d) ^ QRUtil.G15_MASK;
471
- },
472
- /*
473
- BCH编码版本信息
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 掩膜的版本
474
81
  */
475
- getBCHTypeNumber: function (data) {
476
- var d = data << 12;
477
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
478
- d ^=
479
- QRUtil.G18 <<
480
- (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18));
481
- }
482
- return (data << 12) | d;
483
- },
484
- /*
485
- 获取BCH位信息
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 探测图形的中心纵坐标
486
103
  */
487
- getBCHDigit: function (data) {
488
- var digit = 0;
489
- while (data != 0) {
490
- digit++;
491
- data >>>= 1;
492
- }
493
- return digit;
494
- },
495
- /*
496
- 获取版本对应的矫正图形位置
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 (
110
+ (0 <= r && r <= 6 && (c == 0 || c == 6)) ||
111
+ (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
112
+ (2 <= r && r <= 4 && 2 <= c && c <= 4)
113
+ ) {
114
+ this.modules[row + r][col + c] = true
115
+ } else {
116
+ this.modules[row + r][col + c] = false
117
+ }
118
+ }
119
+ }
120
+ },
121
+ /**
122
+ * 创建二维码
123
+ * @return {[type]} [description]
497
124
  */
498
- getPatternPosition: function (typeNumber) {
499
- return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
500
- },
501
- /*
502
- 掩膜算法
125
+ createQrcode: function () {
126
+ var minLostPoint = 0
127
+ var pattern = 0
128
+ var bestModules = null
129
+ for (var i = 0; i < 8; i++) {
130
+ this.makeImpl(i)
131
+ var lostPoint = QRUtil.getLostPoint(this)
132
+ if (i == 0 || minLostPoint > lostPoint) {
133
+ minLostPoint = lostPoint
134
+ pattern = i
135
+ bestModules = this.modules
136
+ }
137
+ }
138
+ this.modules = bestModules
139
+ this.setupTypeInfo(false, pattern)
140
+ if (this.typeNumber >= 7) {
141
+ this.setupTypeNumber(false)
142
+ }
143
+ },
144
+ /**
145
+ * 设置定位图形
146
+ * @return {[type]} [description]
503
147
  */
504
- getMask: function (maskPattern, i, j) {
505
- switch (maskPattern) {
506
- case QRMaskPattern.PATTERN000:
507
- return (i + j) % 2 == 0;
508
- case QRMaskPattern.PATTERN001:
509
- return i % 2 == 0;
510
- case QRMaskPattern.PATTERN010:
511
- return j % 3 == 0;
512
- case QRMaskPattern.PATTERN011:
513
- return (i + j) % 3 == 0;
514
- case QRMaskPattern.PATTERN100:
515
- return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
516
- case QRMaskPattern.PATTERN101:
517
- return ((i * j) % 2) + ((i * j) % 3) == 0;
518
- case QRMaskPattern.PATTERN110:
519
- return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0;
520
- case QRMaskPattern.PATTERN111:
521
- return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0;
522
- default:
523
- throw new Error("bad maskPattern:" + maskPattern);
524
- }
525
- },
526
- /*
527
- 获取RS的纠错多项式
148
+ setupTimingPattern: function () {
149
+ for (var r = 8; r < this.moduleCount - 8; r++) {
150
+ if (this.modules[r][6] != null) {
151
+ continue
152
+ }
153
+ this.modules[r][6] = r % 2 == 0
154
+ if (this.modules[6][r] != null) {
155
+ continue
156
+ }
157
+ this.modules[6][r] = r % 2 == 0
158
+ }
159
+ },
160
+ /**
161
+ * 设置矫正图形
162
+ * @return {[type]} [description]
528
163
  */
529
- getErrorCorrectPolynomial: function (errorCorrectLength) {
530
- var a = new QRPolynomial([1], 0);
531
- for (var i = 0; i < errorCorrectLength; i++) {
532
- a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
533
- }
534
- return a;
535
- },
536
- /*
537
- 获取评价
164
+ setupPositionAdjustPattern: function () {
165
+ var pos = QRUtil.getPatternPosition(this.typeNumber)
166
+ for (var i = 0; i < pos.length; i++) {
167
+ for (var j = 0; j < pos.length; j++) {
168
+ var row = pos[i]
169
+ var col = pos[j]
170
+ if (this.modules[row][col] != null) {
171
+ continue
172
+ }
173
+ for (var r = -2; r <= 2; r++) {
174
+ for (var c = -2; c <= 2; c++) {
175
+ if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
176
+ this.modules[row + r][col + c] = true
177
+ } else {
178
+ this.modules[row + r][col + c] = false
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ },
185
+ /**
186
+ * 设置版本信息(7以上版本才有)
187
+ * @param {bool} test 是否处于判断最佳掩膜阶段
188
+ * @return {[type]} [description]
538
189
  */
539
- getLostPoint: function (qrCode) {
540
- var moduleCount = qrCode.getModuleCount(),
541
- lostPoint = 0,
542
- darkCount = 0;
543
- for (var row = 0; row < moduleCount; row++) {
544
- var sameCount = 0;
545
- var head = qrCode.modules[row][0];
546
- for (var col = 0; col < moduleCount; col++) {
547
- var current = qrCode.modules[row][col];
548
- //level 3 评价
549
- if (col < moduleCount - 6) {
550
- if (
551
- current &&
552
- !qrCode.modules[row][col + 1] &&
553
- qrCode.modules[row][col + 2] &&
554
- qrCode.modules[row][col + 3] &&
555
- qrCode.modules[row][col + 4] &&
556
- !qrCode.modules[row][col + 5] &&
557
- qrCode.modules[row][col + 6]
558
- ) {
559
- if (col < moduleCount - 10) {
560
- if (
561
- qrCode.modules[row][col + 7] &&
562
- qrCode.modules[row][col + 8] &&
563
- qrCode.modules[row][col + 9] &&
564
- qrCode.modules[row][col + 10]
565
- ) {
566
- lostPoint += 40;
190
+ setupTypeNumber: function (test) {
191
+ var bits = QRUtil.getBCHTypeNumber(this.typeNumber)
192
+ for (var i = 0; i < 18; i++) {
193
+ var mod = !test && ((bits >> i) & 1) == 1
194
+ this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
195
+ this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod
196
+ }
197
+ },
198
+ /**
199
+ * 设置格式信息(纠错等级和掩膜版本)
200
+ * @param {bool} test
201
+ * @param {num} maskPattern 掩膜版本
202
+ * @return {}
203
+ */
204
+ setupTypeInfo: function (test, maskPattern) {
205
+ var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern
206
+ var bits = QRUtil.getBCHTypeInfo(data)
207
+ // vertical
208
+ for (var i = 0; i < 15; i++) {
209
+ var mod = !test && ((bits >> i) & 1) == 1
210
+ if (i < 6) {
211
+ this.modules[i][8] = mod
212
+ } else if (i < 8) {
213
+ this.modules[i + 1][8] = mod
214
+ } else {
215
+ this.modules[this.moduleCount - 15 + i][8] = mod
567
216
  }
568
- } else if (col > 3) {
569
- if (
570
- qrCode.modules[row][col - 1] &&
571
- qrCode.modules[row][col - 2] &&
572
- qrCode.modules[row][col - 3] &&
573
- qrCode.modules[row][col - 4]
574
- ) {
575
- lostPoint += 40;
217
+ // horizontal
218
+ var mod = !test && ((bits >> i) & 1) == 1
219
+ if (i < 8) {
220
+ this.modules[8][this.moduleCount - i - 1] = mod
221
+ } else if (i < 9) {
222
+ this.modules[8][15 - i - 1 + 1] = mod
223
+ } else {
224
+ this.modules[8][15 - i - 1] = mod
576
225
  }
577
- }
578
226
  }
579
- }
580
- //level 2 评价
581
- if (row < moduleCount - 1 && col < moduleCount - 1) {
582
- var count = 0;
583
- if (current) count++;
584
- if (qrCode.modules[row + 1][col]) count++;
585
- if (qrCode.modules[row][col + 1]) count++;
586
- if (qrCode.modules[row + 1][col + 1]) count++;
587
- if (count == 0 || count == 4) {
588
- lostPoint += 3;
227
+ // fixed module
228
+ this.modules[this.moduleCount - 8][8] = !test
229
+ },
230
+ /**
231
+ * 数据编码
232
+ * @return {[type]} [description]
233
+ */
234
+ createData: function () {
235
+ var buffer = new QRBitBuffer()
236
+ var lengthBits = this.typeNumber > 9 ? 16 : 8
237
+ buffer.put(4, 4) //添加模式
238
+ buffer.put(this.utf8bytes.length, lengthBits)
239
+ for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
240
+ buffer.put(this.utf8bytes[i], 8)
589
241
  }
590
- }
591
- //level 1 评价
592
- if (head ^ current) {
593
- sameCount++;
594
- } else {
595
- head = current;
596
- if (sameCount >= 5) {
597
- lostPoint += 3 + sameCount - 5;
242
+ if (buffer.length + 4 <= this.totalDataCount * 8) {
243
+ buffer.put(0, 4)
598
244
  }
599
- sameCount = 1;
600
- }
601
- //level 4 评价
602
- if (current) {
603
- darkCount++;
604
- }
605
- }
606
- }
607
- for (var col = 0; col < moduleCount; col++) {
608
- var sameCount = 0;
609
- var head = qrCode.modules[0][col];
610
- for (var row = 0; row < moduleCount; row++) {
611
- var current = qrCode.modules[row][col];
612
- //level 3 评价
613
- if (row < moduleCount - 6) {
614
- if (
615
- current &&
616
- !qrCode.modules[row + 1][col] &&
617
- qrCode.modules[row + 2][col] &&
618
- qrCode.modules[row + 3][col] &&
619
- qrCode.modules[row + 4][col] &&
620
- !qrCode.modules[row + 5][col] &&
621
- qrCode.modules[row + 6][col]
622
- ) {
623
- if (row < moduleCount - 10) {
624
- if (
625
- qrCode.modules[row + 7][col] &&
626
- qrCode.modules[row + 8][col] &&
627
- qrCode.modules[row + 9][col] &&
628
- qrCode.modules[row + 10][col]
629
- ) {
630
- lostPoint += 40;
245
+ // padding
246
+ while (buffer.length % 8 != 0) {
247
+ buffer.putBit(false)
248
+ }
249
+ // padding
250
+ while (true) {
251
+ if (buffer.length >= this.totalDataCount * 8) {
252
+ break
253
+ }
254
+ buffer.put(QRCodeAlg.PAD0, 8)
255
+ if (buffer.length >= this.totalDataCount * 8) {
256
+ break
257
+ }
258
+ buffer.put(QRCodeAlg.PAD1, 8)
259
+ }
260
+ return this.createBytes(buffer)
261
+ },
262
+ /**
263
+ * 纠错码编码
264
+ * @param {buffer} buffer 数据编码
265
+ * @return {[type]}
266
+ */
267
+ createBytes: function (buffer) {
268
+ var offset = 0
269
+ var maxDcCount = 0
270
+ var maxEcCount = 0
271
+ var length = this.rsBlock.length / 3
272
+ var rsBlocks = new Array()
273
+ for (var i = 0; i < length; i++) {
274
+ var count = this.rsBlock[i * 3 + 0]
275
+ var totalCount = this.rsBlock[i * 3 + 1]
276
+ var dataCount = this.rsBlock[i * 3 + 2]
277
+ for (var j = 0; j < count; j++) {
278
+ rsBlocks.push([dataCount, totalCount])
279
+ }
280
+ }
281
+ var dcdata = new Array(rsBlocks.length)
282
+ var ecdata = new Array(rsBlocks.length)
283
+ for (var r = 0; r < rsBlocks.length; r++) {
284
+ var dcCount = rsBlocks[r][0]
285
+ var ecCount = rsBlocks[r][1] - dcCount
286
+ maxDcCount = Math.max(maxDcCount, dcCount)
287
+ maxEcCount = Math.max(maxEcCount, ecCount)
288
+ dcdata[r] = new Array(dcCount)
289
+ for (var i = 0; i < dcdata[r].length; i++) {
290
+ dcdata[r][i] = 0xff & buffer.buffer[i + offset]
631
291
  }
632
- } else if (row > 3) {
633
- if (
634
- qrCode.modules[row - 1][col] &&
635
- qrCode.modules[row - 2][col] &&
636
- qrCode.modules[row - 3][col] &&
637
- qrCode.modules[row - 4][col]
638
- ) {
639
- lostPoint += 40;
292
+ offset += dcCount
293
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
294
+ var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
295
+ var modPoly = rawPoly.mod(rsPoly)
296
+ ecdata[r] = new Array(rsPoly.getLength() - 1)
297
+ for (var i = 0; i < ecdata[r].length; i++) {
298
+ var modIndex = i + modPoly.getLength() - ecdata[r].length
299
+ ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0
640
300
  }
641
- }
642
301
  }
643
- }
644
- //level 1 评价
645
- if (head ^ current) {
646
- sameCount++;
647
- } else {
648
- head = current;
649
- if (sameCount >= 5) {
650
- lostPoint += 3 + sameCount - 5;
302
+ var data = new Array(this.totalDataCount)
303
+ var index = 0
304
+ for (var i = 0; i < maxDcCount; i++) {
305
+ for (var r = 0; r < rsBlocks.length; r++) {
306
+ if (i < dcdata[r].length) {
307
+ data[index++] = dcdata[r][i]
308
+ }
309
+ }
310
+ }
311
+ for (var i = 0; i < maxEcCount; i++) {
312
+ for (var r = 0; r < rsBlocks.length; r++) {
313
+ if (i < ecdata[r].length) {
314
+ data[index++] = ecdata[r][i]
315
+ }
316
+ }
317
+ }
318
+ return data
319
+ },
320
+ /**
321
+ * 布置模块,构建最终信息
322
+ * @param {} data
323
+ * @param {} maskPattern
324
+ * @return {}
325
+ */
326
+ mapData: function (data, maskPattern) {
327
+ var inc = -1
328
+ var row = this.moduleCount - 1
329
+ var bitIndex = 7
330
+ var byteIndex = 0
331
+ for (var col = this.moduleCount - 1; col > 0; col -= 2) {
332
+ if (col == 6) col--
333
+ while (true) {
334
+ for (var c = 0; c < 2; c++) {
335
+ if (this.modules[row][col - c] == null) {
336
+ var dark = false
337
+ if (byteIndex < data.length) {
338
+ dark = ((data[byteIndex] >>> bitIndex) & 1) == 1
339
+ }
340
+ var mask = QRUtil.getMask(maskPattern, row, col - c)
341
+ if (mask) {
342
+ dark = !dark
343
+ }
344
+ this.modules[row][col - c] = dark
345
+ bitIndex--
346
+ if (bitIndex == -1) {
347
+ byteIndex++
348
+ bitIndex = 7
349
+ }
350
+ }
351
+ }
352
+ row += inc
353
+ if (row < 0 || this.moduleCount <= row) {
354
+ row -= inc
355
+ inc = -inc
356
+ break
357
+ }
358
+ }
651
359
  }
652
- sameCount = 1;
653
- }
654
360
  }
655
- }
656
- // LEVEL4
657
- var ratio =
658
- Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5;
659
- lostPoint += ratio * 10;
660
- return lostPoint;
661
361
  }
662
- };
663
- //---------------------------------------------------------------------
664
- // QRMath使用的数学工具
665
- //---------------------------------------------------------------------
666
- var QRMath = {
667
- /*
668
- 将n转化为a^m
669
- */
670
- glog: function (n) {
671
- if (n < 1) {
672
- throw new Error("glog(" + n + ")");
673
- }
674
- return QRMath.LOG_TABLE[n];
675
- },
676
- /*
677
- 将a^m转化为n
678
- */
679
- gexp: function (n) {
680
- while (n < 0) {
681
- n += 255;
682
- }
683
- while (n >= 256) {
684
- n -= 255;
685
- }
686
- return QRMath.EXP_TABLE[n];
687
- },
688
- EXP_TABLE: new Array(256),
689
- LOG_TABLE: new Array(256)
690
- };
691
- for (var i = 0; i < 8; i++) {
692
- QRMath.EXP_TABLE[i] = 1 << i;
693
- }
694
- for (var i = 8; i < 256; i++) {
695
- QRMath.EXP_TABLE[i] =
696
- QRMath.EXP_TABLE[i - 4] ^
697
- QRMath.EXP_TABLE[i - 5] ^
698
- QRMath.EXP_TABLE[i - 6] ^
699
- QRMath.EXP_TABLE[i - 8];
700
- }
701
- for (var i = 0; i < 255; i++) {
702
- QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
703
- }
704
- //---------------------------------------------------------------------
705
- // QRPolynomial 多项式
706
- //---------------------------------------------------------------------
707
- /**
708
- * 多项式类
709
- * @param {Array} num 系数
710
- * @param {num} shift a^shift
711
- */
712
- function QRPolynomial(num, shift) {
713
- if (num.length == undefined) {
714
- throw new Error(num.length + "/" + shift);
362
+ /**
363
+ * 填充字段
364
+ */
365
+ QRCodeAlg.PAD0 = 0xec
366
+ QRCodeAlg.PAD1 = 0x11
367
+ //---------------------------------------------------------------------
368
+ // 纠错等级对应的编码
369
+ //---------------------------------------------------------------------
370
+ var QRErrorCorrectLevel = [1, 0, 3, 2]
371
+ //---------------------------------------------------------------------
372
+ // 掩膜版本
373
+ //---------------------------------------------------------------------
374
+ var QRMaskPattern = {
375
+ PATTERN000: 0,
376
+ PATTERN001: 1,
377
+ PATTERN010: 2,
378
+ PATTERN011: 3,
379
+ PATTERN100: 4,
380
+ PATTERN101: 5,
381
+ PATTERN110: 6,
382
+ PATTERN111: 7
715
383
  }
716
- var offset = 0;
717
- while (offset < num.length && num[offset] == 0) {
718
- offset++;
384
+ //---------------------------------------------------------------------
385
+ // 工具类
386
+ //---------------------------------------------------------------------
387
+ var QRUtil = {
388
+ /*
389
+ 每个版本矫正图形的位置
390
+ */
391
+ PATTERN_POSITION_TABLE: [
392
+ [],
393
+ [6, 18],
394
+ [6, 22],
395
+ [6, 26],
396
+ [6, 30],
397
+ [6, 34],
398
+ [6, 22, 38],
399
+ [6, 24, 42],
400
+ [6, 26, 46],
401
+ [6, 28, 50],
402
+ [6, 30, 54],
403
+ [6, 32, 58],
404
+ [6, 34, 62],
405
+ [6, 26, 46, 66],
406
+ [6, 26, 48, 70],
407
+ [6, 26, 50, 74],
408
+ [6, 30, 54, 78],
409
+ [6, 30, 56, 82],
410
+ [6, 30, 58, 86],
411
+ [6, 34, 62, 90],
412
+ [6, 28, 50, 72, 94],
413
+ [6, 26, 50, 74, 98],
414
+ [6, 30, 54, 78, 102],
415
+ [6, 28, 54, 80, 106],
416
+ [6, 32, 58, 84, 110],
417
+ [6, 30, 58, 86, 114],
418
+ [6, 34, 62, 90, 118],
419
+ [6, 26, 50, 74, 98, 122],
420
+ [6, 30, 54, 78, 102, 126],
421
+ [6, 26, 52, 78, 104, 130],
422
+ [6, 30, 56, 82, 108, 134],
423
+ [6, 34, 60, 86, 112, 138],
424
+ [6, 30, 58, 86, 114, 142],
425
+ [6, 34, 62, 90, 118, 146],
426
+ [6, 30, 54, 78, 102, 126, 150],
427
+ [6, 24, 50, 76, 102, 128, 154],
428
+ [6, 28, 54, 80, 106, 132, 158],
429
+ [6, 32, 58, 84, 110, 136, 162],
430
+ [6, 26, 54, 82, 110, 138, 166],
431
+ [6, 30, 58, 86, 114, 142, 170]
432
+ ],
433
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
434
+ G18:
435
+ (1 << 12) |
436
+ (1 << 11) |
437
+ (1 << 10) |
438
+ (1 << 9) |
439
+ (1 << 8) |
440
+ (1 << 5) |
441
+ (1 << 2) |
442
+ (1 << 0),
443
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
444
+ /*
445
+ BCH编码格式信息
446
+ */
447
+ getBCHTypeInfo: function (data) {
448
+ var d = data << 10
449
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
450
+ d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
451
+ }
452
+ return ((data << 10) | d) ^ QRUtil.G15_MASK
453
+ },
454
+ /*
455
+ BCH编码版本信息
456
+ */
457
+ getBCHTypeNumber: function (data) {
458
+ var d = data << 12
459
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
460
+ d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
461
+ }
462
+ return (data << 12) | d
463
+ },
464
+ /*
465
+ 获取BCH位信息
466
+ */
467
+ getBCHDigit: function (data) {
468
+ var digit = 0
469
+ while (data != 0) {
470
+ digit++
471
+ data >>>= 1
472
+ }
473
+ return digit
474
+ },
475
+ /*
476
+ 获取版本对应的矫正图形位置
477
+ */
478
+ getPatternPosition: function (typeNumber) {
479
+ return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]
480
+ },
481
+ /*
482
+ 掩膜算法
483
+ */
484
+ getMask: function (maskPattern, i, j) {
485
+ switch (maskPattern) {
486
+ case QRMaskPattern.PATTERN000:
487
+ return (i + j) % 2 == 0
488
+ case QRMaskPattern.PATTERN001:
489
+ return i % 2 == 0
490
+ case QRMaskPattern.PATTERN010:
491
+ return j % 3 == 0
492
+ case QRMaskPattern.PATTERN011:
493
+ return (i + j) % 3 == 0
494
+ case QRMaskPattern.PATTERN100:
495
+ return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0
496
+ case QRMaskPattern.PATTERN101:
497
+ return ((i * j) % 2) + ((i * j) % 3) == 0
498
+ case QRMaskPattern.PATTERN110:
499
+ return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0
500
+ case QRMaskPattern.PATTERN111:
501
+ return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0
502
+ default:
503
+ throw new Error('bad maskPattern:' + maskPattern)
504
+ }
505
+ },
506
+ /*
507
+ 获取RS的纠错多项式
508
+ */
509
+ getErrorCorrectPolynomial: function (errorCorrectLength) {
510
+ var a = new QRPolynomial([1], 0)
511
+ for (var i = 0; i < errorCorrectLength; i++) {
512
+ a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
513
+ }
514
+ return a
515
+ },
516
+ /*
517
+ 获取评价
518
+ */
519
+ getLostPoint: function (qrCode) {
520
+ var moduleCount = qrCode.getModuleCount(),
521
+ lostPoint = 0,
522
+ darkCount = 0
523
+ for (var row = 0; row < moduleCount; row++) {
524
+ var sameCount = 0
525
+ var head = qrCode.modules[row][0]
526
+ for (var col = 0; col < moduleCount; col++) {
527
+ var current = qrCode.modules[row][col]
528
+ //level 3 评价
529
+ if (col < moduleCount - 6) {
530
+ if (
531
+ current &&
532
+ !qrCode.modules[row][col + 1] &&
533
+ qrCode.modules[row][col + 2] &&
534
+ qrCode.modules[row][col + 3] &&
535
+ qrCode.modules[row][col + 4] &&
536
+ !qrCode.modules[row][col + 5] &&
537
+ qrCode.modules[row][col + 6]
538
+ ) {
539
+ if (col < moduleCount - 10) {
540
+ if (
541
+ qrCode.modules[row][col + 7] &&
542
+ qrCode.modules[row][col + 8] &&
543
+ qrCode.modules[row][col + 9] &&
544
+ qrCode.modules[row][col + 10]
545
+ ) {
546
+ lostPoint += 40
547
+ }
548
+ } else if (col > 3) {
549
+ if (
550
+ qrCode.modules[row][col - 1] &&
551
+ qrCode.modules[row][col - 2] &&
552
+ qrCode.modules[row][col - 3] &&
553
+ qrCode.modules[row][col - 4]
554
+ ) {
555
+ lostPoint += 40
556
+ }
557
+ }
558
+ }
559
+ }
560
+ //level 2 评价
561
+ if (row < moduleCount - 1 && col < moduleCount - 1) {
562
+ var count = 0
563
+ if (current) count++
564
+ if (qrCode.modules[row + 1][col]) count++
565
+ if (qrCode.modules[row][col + 1]) count++
566
+ if (qrCode.modules[row + 1][col + 1]) count++
567
+ if (count == 0 || count == 4) {
568
+ lostPoint += 3
569
+ }
570
+ }
571
+ //level 1 评价
572
+ if (head ^ current) {
573
+ sameCount++
574
+ } else {
575
+ head = current
576
+ if (sameCount >= 5) {
577
+ lostPoint += 3 + sameCount - 5
578
+ }
579
+ sameCount = 1
580
+ }
581
+ //level 4 评价
582
+ if (current) {
583
+ darkCount++
584
+ }
585
+ }
586
+ }
587
+ for (var col = 0; col < moduleCount; col++) {
588
+ var sameCount = 0
589
+ var head = qrCode.modules[0][col]
590
+ for (var row = 0; row < moduleCount; row++) {
591
+ var current = qrCode.modules[row][col]
592
+ //level 3 评价
593
+ if (row < moduleCount - 6) {
594
+ if (
595
+ current &&
596
+ !qrCode.modules[row + 1][col] &&
597
+ qrCode.modules[row + 2][col] &&
598
+ qrCode.modules[row + 3][col] &&
599
+ qrCode.modules[row + 4][col] &&
600
+ !qrCode.modules[row + 5][col] &&
601
+ qrCode.modules[row + 6][col]
602
+ ) {
603
+ if (row < moduleCount - 10) {
604
+ if (
605
+ qrCode.modules[row + 7][col] &&
606
+ qrCode.modules[row + 8][col] &&
607
+ qrCode.modules[row + 9][col] &&
608
+ qrCode.modules[row + 10][col]
609
+ ) {
610
+ lostPoint += 40
611
+ }
612
+ } else if (row > 3) {
613
+ if (
614
+ qrCode.modules[row - 1][col] &&
615
+ qrCode.modules[row - 2][col] &&
616
+ qrCode.modules[row - 3][col] &&
617
+ qrCode.modules[row - 4][col]
618
+ ) {
619
+ lostPoint += 40
620
+ }
621
+ }
622
+ }
623
+ }
624
+ //level 1 评价
625
+ if (head ^ current) {
626
+ sameCount++
627
+ } else {
628
+ head = current
629
+ if (sameCount >= 5) {
630
+ lostPoint += 3 + sameCount - 5
631
+ }
632
+ sameCount = 1
633
+ }
634
+ }
635
+ }
636
+ // LEVEL4
637
+ var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
638
+ lostPoint += ratio * 10
639
+ return lostPoint
640
+ }
641
+ }
642
+ //---------------------------------------------------------------------
643
+ // QRMath使用的数学工具
644
+ //---------------------------------------------------------------------
645
+ var QRMath = {
646
+ /*
647
+ 将n转化为a^m
648
+ */
649
+ glog: function (n) {
650
+ if (n < 1) {
651
+ throw new Error('glog(' + n + ')')
652
+ }
653
+ return QRMath.LOG_TABLE[n]
654
+ },
655
+ /*
656
+ 将a^m转化为n
657
+ */
658
+ gexp: function (n) {
659
+ while (n < 0) {
660
+ n += 255
661
+ }
662
+ while (n >= 256) {
663
+ n -= 255
664
+ }
665
+ return QRMath.EXP_TABLE[n]
666
+ },
667
+ EXP_TABLE: new Array(256),
668
+ LOG_TABLE: new Array(256)
669
+ }
670
+ for (var i = 0; i < 8; i++) {
671
+ QRMath.EXP_TABLE[i] = 1 << i
672
+ }
673
+ for (var i = 8; i < 256; i++) {
674
+ QRMath.EXP_TABLE[i] =
675
+ QRMath.EXP_TABLE[i - 4] ^
676
+ QRMath.EXP_TABLE[i - 5] ^
677
+ QRMath.EXP_TABLE[i - 6] ^
678
+ QRMath.EXP_TABLE[i - 8]
719
679
  }
720
- this.num = new Array(num.length - offset + shift);
721
- for (var i = 0; i < num.length - offset; i++) {
722
- this.num[i] = num[i + offset];
680
+ for (var i = 0; i < 255; i++) {
681
+ QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
723
682
  }
724
- }
725
- QRPolynomial.prototype = {
726
- get: function (index) {
727
- return this.num[index];
728
- },
729
- getLength: function () {
730
- return this.num.length;
731
- },
683
+ //---------------------------------------------------------------------
684
+ // QRPolynomial 多项式
685
+ //---------------------------------------------------------------------
732
686
  /**
733
- * 多项式乘法
734
- * @param {QRPolynomial} e 被乘多项式
735
- * @return {[type]} [description]
687
+ * 多项式类
688
+ * @param {Array} num 系数
689
+ * @param {num} shift a^shift
736
690
  */
737
- multiply: function (e) {
738
- var num = new Array(this.getLength() + e.getLength() - 1);
739
- for (var i = 0; i < this.getLength(); i++) {
740
- for (var j = 0; j < e.getLength(); j++) {
741
- num[i + j] ^= QRMath.gexp(
742
- QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))
743
- );
691
+ function QRPolynomial(num, shift) {
692
+ if (num.length == undefined) {
693
+ throw new Error(num.length + '/' + shift)
744
694
  }
745
- }
746
- return new QRPolynomial(num, 0);
747
- },
748
- /**
749
- * 多项式模运算
750
- * @param {QRPolynomial} e 模多项式
751
- * @return {}
752
- */
753
- mod: function (e) {
754
- var tl = this.getLength(),
755
- el = e.getLength();
756
- if (tl - el < 0) {
757
- return this;
758
- }
759
- var num = new Array(tl);
760
- for (var i = 0; i < tl; i++) {
761
- num[i] = this.get(i);
762
- }
763
- while (num.length >= el) {
764
- var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0));
765
-
766
- for (var i = 0; i < e.getLength(); i++) {
767
- num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
695
+ var offset = 0
696
+ while (offset < num.length && num[offset] == 0) {
697
+ offset++
768
698
  }
769
- while (num[0] == 0) {
770
- num.shift();
699
+ this.num = new Array(num.length - offset + shift)
700
+ for (var i = 0; i < num.length - offset; i++) {
701
+ this.num[i] = num[i + offset]
771
702
  }
772
- }
773
- return new QRPolynomial(num, 0);
774
703
  }
775
- };
704
+ QRPolynomial.prototype = {
705
+ get: function (index) {
706
+ return this.num[index]
707
+ },
708
+ getLength: function () {
709
+ return this.num.length
710
+ },
711
+ /**
712
+ * 多项式乘法
713
+ * @param {QRPolynomial} e 被乘多项式
714
+ * @return {[type]} [description]
715
+ */
716
+ multiply: function (e) {
717
+ var num = new Array(this.getLength() + e.getLength() - 1)
718
+ for (var i = 0; i < this.getLength(); i++) {
719
+ for (var j = 0; j < e.getLength(); j++) {
720
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
721
+ }
722
+ }
723
+ return new QRPolynomial(num, 0)
724
+ },
725
+ /**
726
+ * 多项式模运算
727
+ * @param {QRPolynomial} e 模多项式
728
+ * @return {}
729
+ */
730
+ mod: function (e) {
731
+ var tl = this.getLength(),
732
+ el = e.getLength()
733
+ if (tl - el < 0) {
734
+ return this
735
+ }
736
+ var num = new Array(tl)
737
+ for (var i = 0; i < tl; i++) {
738
+ num[i] = this.get(i)
739
+ }
740
+ while (num.length >= el) {
741
+ var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0))
776
742
 
777
- //---------------------------------------------------------------------
778
- // RS_BLOCK_TABLE
779
- //---------------------------------------------------------------------
780
- /*
781
- 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
782
- */
783
- var RS_BLOCK_TABLE = [
784
- // L
785
- // M
786
- // Q
787
- // H
788
- // 1
789
- [1, 26, 19],
790
- [1, 26, 16],
791
- [1, 26, 13],
792
- [1, 26, 9],
743
+ for (var i = 0; i < e.getLength(); i++) {
744
+ num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
745
+ }
746
+ while (num[0] == 0) {
747
+ num.shift()
748
+ }
749
+ }
750
+ return new QRPolynomial(num, 0)
751
+ }
752
+ }
793
753
 
794
- // 2
795
- [1, 44, 34],
796
- [1, 44, 28],
797
- [1, 44, 22],
798
- [1, 44, 16],
754
+ //---------------------------------------------------------------------
755
+ // RS_BLOCK_TABLE
756
+ //---------------------------------------------------------------------
757
+ /*
758
+ 二维码各个版本信息[块数, 每块中的数据块数, 每块中的信息块数]
759
+ */
760
+ var RS_BLOCK_TABLE = [
761
+ // L
762
+ // M
763
+ // Q
764
+ // H
765
+ // 1
766
+ [1, 26, 19],
767
+ [1, 26, 16],
768
+ [1, 26, 13],
769
+ [1, 26, 9],
799
770
 
800
- // 3
801
- [1, 70, 55],
802
- [1, 70, 44],
803
- [2, 35, 17],
804
- [2, 35, 13],
771
+ // 2
772
+ [1, 44, 34],
773
+ [1, 44, 28],
774
+ [1, 44, 22],
775
+ [1, 44, 16],
805
776
 
806
- // 4
807
- [1, 100, 80],
808
- [2, 50, 32],
809
- [2, 50, 24],
810
- [4, 25, 9],
777
+ // 3
778
+ [1, 70, 55],
779
+ [1, 70, 44],
780
+ [2, 35, 17],
781
+ [2, 35, 13],
811
782
 
812
- // 5
813
- [1, 134, 108],
814
- [2, 67, 43],
815
- [2, 33, 15, 2, 34, 16],
816
- [2, 33, 11, 2, 34, 12],
783
+ // 4
784
+ [1, 100, 80],
785
+ [2, 50, 32],
786
+ [2, 50, 24],
787
+ [4, 25, 9],
817
788
 
818
- // 6
819
- [2, 86, 68],
820
- [4, 43, 27],
821
- [4, 43, 19],
822
- [4, 43, 15],
789
+ // 5
790
+ [1, 134, 108],
791
+ [2, 67, 43],
792
+ [2, 33, 15, 2, 34, 16],
793
+ [2, 33, 11, 2, 34, 12],
823
794
 
824
- // 7
825
- [2, 98, 78],
826
- [4, 49, 31],
827
- [2, 32, 14, 4, 33, 15],
828
- [4, 39, 13, 1, 40, 14],
795
+ // 6
796
+ [2, 86, 68],
797
+ [4, 43, 27],
798
+ [4, 43, 19],
799
+ [4, 43, 15],
829
800
 
830
- // 8
831
- [2, 121, 97],
832
- [2, 60, 38, 2, 61, 39],
833
- [4, 40, 18, 2, 41, 19],
834
- [4, 40, 14, 2, 41, 15],
801
+ // 7
802
+ [2, 98, 78],
803
+ [4, 49, 31],
804
+ [2, 32, 14, 4, 33, 15],
805
+ [4, 39, 13, 1, 40, 14],
835
806
 
836
- // 9
837
- [2, 146, 116],
838
- [3, 58, 36, 2, 59, 37],
839
- [4, 36, 16, 4, 37, 17],
840
- [4, 36, 12, 4, 37, 13],
807
+ // 8
808
+ [2, 121, 97],
809
+ [2, 60, 38, 2, 61, 39],
810
+ [4, 40, 18, 2, 41, 19],
811
+ [4, 40, 14, 2, 41, 15],
841
812
 
842
- // 10
843
- [2, 86, 68, 2, 87, 69],
844
- [4, 69, 43, 1, 70, 44],
845
- [6, 43, 19, 2, 44, 20],
846
- [6, 43, 15, 2, 44, 16],
813
+ // 9
814
+ [2, 146, 116],
815
+ [3, 58, 36, 2, 59, 37],
816
+ [4, 36, 16, 4, 37, 17],
817
+ [4, 36, 12, 4, 37, 13],
847
818
 
848
- // 11
849
- [4, 101, 81],
850
- [1, 80, 50, 4, 81, 51],
851
- [4, 50, 22, 4, 51, 23],
852
- [3, 36, 12, 8, 37, 13],
819
+ // 10
820
+ [2, 86, 68, 2, 87, 69],
821
+ [4, 69, 43, 1, 70, 44],
822
+ [6, 43, 19, 2, 44, 20],
823
+ [6, 43, 15, 2, 44, 16],
853
824
 
854
- // 12
855
- [2, 116, 92, 2, 117, 93],
856
- [6, 58, 36, 2, 59, 37],
857
- [4, 46, 20, 6, 47, 21],
858
- [7, 42, 14, 4, 43, 15],
825
+ // 11
826
+ [4, 101, 81],
827
+ [1, 80, 50, 4, 81, 51],
828
+ [4, 50, 22, 4, 51, 23],
829
+ [3, 36, 12, 8, 37, 13],
859
830
 
860
- // 13
861
- [4, 133, 107],
862
- [8, 59, 37, 1, 60, 38],
863
- [8, 44, 20, 4, 45, 21],
864
- [12, 33, 11, 4, 34, 12],
831
+ // 12
832
+ [2, 116, 92, 2, 117, 93],
833
+ [6, 58, 36, 2, 59, 37],
834
+ [4, 46, 20, 6, 47, 21],
835
+ [7, 42, 14, 4, 43, 15],
865
836
 
866
- // 14
867
- [3, 145, 115, 1, 146, 116],
868
- [4, 64, 40, 5, 65, 41],
869
- [11, 36, 16, 5, 37, 17],
870
- [11, 36, 12, 5, 37, 13],
837
+ // 13
838
+ [4, 133, 107],
839
+ [8, 59, 37, 1, 60, 38],
840
+ [8, 44, 20, 4, 45, 21],
841
+ [12, 33, 11, 4, 34, 12],
871
842
 
872
- // 15
873
- [5, 109, 87, 1, 110, 88],
874
- [5, 65, 41, 5, 66, 42],
875
- [5, 54, 24, 7, 55, 25],
876
- [11, 36, 12],
843
+ // 14
844
+ [3, 145, 115, 1, 146, 116],
845
+ [4, 64, 40, 5, 65, 41],
846
+ [11, 36, 16, 5, 37, 17],
847
+ [11, 36, 12, 5, 37, 13],
877
848
 
878
- // 16
879
- [5, 122, 98, 1, 123, 99],
880
- [7, 73, 45, 3, 74, 46],
881
- [15, 43, 19, 2, 44, 20],
882
- [3, 45, 15, 13, 46, 16],
849
+ // 15
850
+ [5, 109, 87, 1, 110, 88],
851
+ [5, 65, 41, 5, 66, 42],
852
+ [5, 54, 24, 7, 55, 25],
853
+ [11, 36, 12],
883
854
 
884
- // 17
885
- [1, 135, 107, 5, 136, 108],
886
- [10, 74, 46, 1, 75, 47],
887
- [1, 50, 22, 15, 51, 23],
888
- [2, 42, 14, 17, 43, 15],
855
+ // 16
856
+ [5, 122, 98, 1, 123, 99],
857
+ [7, 73, 45, 3, 74, 46],
858
+ [15, 43, 19, 2, 44, 20],
859
+ [3, 45, 15, 13, 46, 16],
889
860
 
890
- // 18
891
- [5, 150, 120, 1, 151, 121],
892
- [9, 69, 43, 4, 70, 44],
893
- [17, 50, 22, 1, 51, 23],
894
- [2, 42, 14, 19, 43, 15],
861
+ // 17
862
+ [1, 135, 107, 5, 136, 108],
863
+ [10, 74, 46, 1, 75, 47],
864
+ [1, 50, 22, 15, 51, 23],
865
+ [2, 42, 14, 17, 43, 15],
895
866
 
896
- // 19
897
- [3, 141, 113, 4, 142, 114],
898
- [3, 70, 44, 11, 71, 45],
899
- [17, 47, 21, 4, 48, 22],
900
- [9, 39, 13, 16, 40, 14],
867
+ // 18
868
+ [5, 150, 120, 1, 151, 121],
869
+ [9, 69, 43, 4, 70, 44],
870
+ [17, 50, 22, 1, 51, 23],
871
+ [2, 42, 14, 19, 43, 15],
901
872
 
902
- // 20
903
- [3, 135, 107, 5, 136, 108],
904
- [3, 67, 41, 13, 68, 42],
905
- [15, 54, 24, 5, 55, 25],
906
- [15, 43, 15, 10, 44, 16],
873
+ // 19
874
+ [3, 141, 113, 4, 142, 114],
875
+ [3, 70, 44, 11, 71, 45],
876
+ [17, 47, 21, 4, 48, 22],
877
+ [9, 39, 13, 16, 40, 14],
907
878
 
908
- // 21
909
- [4, 144, 116, 4, 145, 117],
910
- [17, 68, 42],
911
- [17, 50, 22, 6, 51, 23],
912
- [19, 46, 16, 6, 47, 17],
879
+ // 20
880
+ [3, 135, 107, 5, 136, 108],
881
+ [3, 67, 41, 13, 68, 42],
882
+ [15, 54, 24, 5, 55, 25],
883
+ [15, 43, 15, 10, 44, 16],
913
884
 
914
- // 22
915
- [2, 139, 111, 7, 140, 112],
916
- [17, 74, 46],
917
- [7, 54, 24, 16, 55, 25],
918
- [34, 37, 13],
885
+ // 21
886
+ [4, 144, 116, 4, 145, 117],
887
+ [17, 68, 42],
888
+ [17, 50, 22, 6, 51, 23],
889
+ [19, 46, 16, 6, 47, 17],
919
890
 
920
- // 23
921
- [4, 151, 121, 5, 152, 122],
922
- [4, 75, 47, 14, 76, 48],
923
- [11, 54, 24, 14, 55, 25],
924
- [16, 45, 15, 14, 46, 16],
891
+ // 22
892
+ [2, 139, 111, 7, 140, 112],
893
+ [17, 74, 46],
894
+ [7, 54, 24, 16, 55, 25],
895
+ [34, 37, 13],
925
896
 
926
- // 24
927
- [6, 147, 117, 4, 148, 118],
928
- [6, 73, 45, 14, 74, 46],
929
- [11, 54, 24, 16, 55, 25],
930
- [30, 46, 16, 2, 47, 17],
897
+ // 23
898
+ [4, 151, 121, 5, 152, 122],
899
+ [4, 75, 47, 14, 76, 48],
900
+ [11, 54, 24, 14, 55, 25],
901
+ [16, 45, 15, 14, 46, 16],
931
902
 
932
- // 25
933
- [8, 132, 106, 4, 133, 107],
934
- [8, 75, 47, 13, 76, 48],
935
- [7, 54, 24, 22, 55, 25],
936
- [22, 45, 15, 13, 46, 16],
903
+ // 24
904
+ [6, 147, 117, 4, 148, 118],
905
+ [6, 73, 45, 14, 74, 46],
906
+ [11, 54, 24, 16, 55, 25],
907
+ [30, 46, 16, 2, 47, 17],
937
908
 
938
- // 26
939
- [10, 142, 114, 2, 143, 115],
940
- [19, 74, 46, 4, 75, 47],
941
- [28, 50, 22, 6, 51, 23],
942
- [33, 46, 16, 4, 47, 17],
909
+ // 25
910
+ [8, 132, 106, 4, 133, 107],
911
+ [8, 75, 47, 13, 76, 48],
912
+ [7, 54, 24, 22, 55, 25],
913
+ [22, 45, 15, 13, 46, 16],
943
914
 
944
- // 27
945
- [8, 152, 122, 4, 153, 123],
946
- [22, 73, 45, 3, 74, 46],
947
- [8, 53, 23, 26, 54, 24],
948
- [12, 45, 15, 28, 46, 16],
915
+ // 26
916
+ [10, 142, 114, 2, 143, 115],
917
+ [19, 74, 46, 4, 75, 47],
918
+ [28, 50, 22, 6, 51, 23],
919
+ [33, 46, 16, 4, 47, 17],
949
920
 
950
- // 28
951
- [3, 147, 117, 10, 148, 118],
952
- [3, 73, 45, 23, 74, 46],
953
- [4, 54, 24, 31, 55, 25],
954
- [11, 45, 15, 31, 46, 16],
921
+ // 27
922
+ [8, 152, 122, 4, 153, 123],
923
+ [22, 73, 45, 3, 74, 46],
924
+ [8, 53, 23, 26, 54, 24],
925
+ [12, 45, 15, 28, 46, 16],
955
926
 
956
- // 29
957
- [7, 146, 116, 7, 147, 117],
958
- [21, 73, 45, 7, 74, 46],
959
- [1, 53, 23, 37, 54, 24],
960
- [19, 45, 15, 26, 46, 16],
927
+ // 28
928
+ [3, 147, 117, 10, 148, 118],
929
+ [3, 73, 45, 23, 74, 46],
930
+ [4, 54, 24, 31, 55, 25],
931
+ [11, 45, 15, 31, 46, 16],
961
932
 
962
- // 30
963
- [5, 145, 115, 10, 146, 116],
964
- [19, 75, 47, 10, 76, 48],
965
- [15, 54, 24, 25, 55, 25],
966
- [23, 45, 15, 25, 46, 16],
933
+ // 29
934
+ [7, 146, 116, 7, 147, 117],
935
+ [21, 73, 45, 7, 74, 46],
936
+ [1, 53, 23, 37, 54, 24],
937
+ [19, 45, 15, 26, 46, 16],
967
938
 
968
- // 31
969
- [13, 145, 115, 3, 146, 116],
970
- [2, 74, 46, 29, 75, 47],
971
- [42, 54, 24, 1, 55, 25],
972
- [23, 45, 15, 28, 46, 16],
939
+ // 30
940
+ [5, 145, 115, 10, 146, 116],
941
+ [19, 75, 47, 10, 76, 48],
942
+ [15, 54, 24, 25, 55, 25],
943
+ [23, 45, 15, 25, 46, 16],
973
944
 
974
- // 32
975
- [17, 145, 115],
976
- [10, 74, 46, 23, 75, 47],
977
- [10, 54, 24, 35, 55, 25],
978
- [19, 45, 15, 35, 46, 16],
945
+ // 31
946
+ [13, 145, 115, 3, 146, 116],
947
+ [2, 74, 46, 29, 75, 47],
948
+ [42, 54, 24, 1, 55, 25],
949
+ [23, 45, 15, 28, 46, 16],
979
950
 
980
- // 33
981
- [17, 145, 115, 1, 146, 116],
982
- [14, 74, 46, 21, 75, 47],
983
- [29, 54, 24, 19, 55, 25],
984
- [11, 45, 15, 46, 46, 16],
951
+ // 32
952
+ [17, 145, 115],
953
+ [10, 74, 46, 23, 75, 47],
954
+ [10, 54, 24, 35, 55, 25],
955
+ [19, 45, 15, 35, 46, 16],
985
956
 
986
- // 34
987
- [13, 145, 115, 6, 146, 116],
988
- [14, 74, 46, 23, 75, 47],
989
- [44, 54, 24, 7, 55, 25],
990
- [59, 46, 16, 1, 47, 17],
957
+ // 33
958
+ [17, 145, 115, 1, 146, 116],
959
+ [14, 74, 46, 21, 75, 47],
960
+ [29, 54, 24, 19, 55, 25],
961
+ [11, 45, 15, 46, 46, 16],
991
962
 
992
- // 35
993
- [12, 151, 121, 7, 152, 122],
994
- [12, 75, 47, 26, 76, 48],
995
- [39, 54, 24, 14, 55, 25],
996
- [22, 45, 15, 41, 46, 16],
963
+ // 34
964
+ [13, 145, 115, 6, 146, 116],
965
+ [14, 74, 46, 23, 75, 47],
966
+ [44, 54, 24, 7, 55, 25],
967
+ [59, 46, 16, 1, 47, 17],
997
968
 
998
- // 36
999
- [6, 151, 121, 14, 152, 122],
1000
- [6, 75, 47, 34, 76, 48],
1001
- [46, 54, 24, 10, 55, 25],
1002
- [2, 45, 15, 64, 46, 16],
969
+ // 35
970
+ [12, 151, 121, 7, 152, 122],
971
+ [12, 75, 47, 26, 76, 48],
972
+ [39, 54, 24, 14, 55, 25],
973
+ [22, 45, 15, 41, 46, 16],
1003
974
 
1004
- // 37
1005
- [17, 152, 122, 4, 153, 123],
1006
- [29, 74, 46, 14, 75, 47],
1007
- [49, 54, 24, 10, 55, 25],
1008
- [24, 45, 15, 46, 46, 16],
975
+ // 36
976
+ [6, 151, 121, 14, 152, 122],
977
+ [6, 75, 47, 34, 76, 48],
978
+ [46, 54, 24, 10, 55, 25],
979
+ [2, 45, 15, 64, 46, 16],
1009
980
 
1010
- // 38
1011
- [4, 152, 122, 18, 153, 123],
1012
- [13, 74, 46, 32, 75, 47],
1013
- [48, 54, 24, 14, 55, 25],
1014
- [42, 45, 15, 32, 46, 16],
981
+ // 37
982
+ [17, 152, 122, 4, 153, 123],
983
+ [29, 74, 46, 14, 75, 47],
984
+ [49, 54, 24, 10, 55, 25],
985
+ [24, 45, 15, 46, 46, 16],
1015
986
 
1016
- // 39
1017
- [20, 147, 117, 4, 148, 118],
1018
- [40, 75, 47, 7, 76, 48],
1019
- [43, 54, 24, 22, 55, 25],
1020
- [10, 45, 15, 67, 46, 16],
987
+ // 38
988
+ [4, 152, 122, 18, 153, 123],
989
+ [13, 74, 46, 32, 75, 47],
990
+ [48, 54, 24, 14, 55, 25],
991
+ [42, 45, 15, 32, 46, 16],
1021
992
 
1022
- // 40
1023
- [19, 148, 118, 6, 149, 119],
1024
- [18, 75, 47, 31, 76, 48],
1025
- [34, 54, 24, 34, 55, 25],
1026
- [20, 45, 15, 61, 46, 16]
1027
- ];
993
+ // 39
994
+ [20, 147, 117, 4, 148, 118],
995
+ [40, 75, 47, 7, 76, 48],
996
+ [43, 54, 24, 22, 55, 25],
997
+ [10, 45, 15, 67, 46, 16],
1028
998
 
1029
- /**
1030
- * 根据数据获取对应版本
1031
- * @return {[type]} [description]
1032
- */
1033
- QRCodeAlg.prototype.getRightType = function () {
1034
- for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1035
- var rsBlock =
1036
- RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel];
1037
- if (rsBlock == undefined) {
1038
- throw new Error(
1039
- "bad rs block @ typeNumber:" +
1040
- typeNumber +
1041
- "/errorCorrectLevel:" +
1042
- this.errorCorrectLevel
1043
- );
1044
- }
1045
- var length = rsBlock.length / 3;
1046
- var totalDataCount = 0;
1047
- for (var i = 0; i < length; i++) {
1048
- var count = rsBlock[i * 3 + 0];
1049
- var dataCount = rsBlock[i * 3 + 2];
1050
- totalDataCount += dataCount * count;
1051
- }
1052
- var lengthBytes = typeNumber > 9 ? 2 : 1;
1053
- if (
1054
- this.utf8bytes.length + lengthBytes < totalDataCount ||
1055
- typeNumber == 40
1056
- ) {
1057
- this.typeNumber = typeNumber;
1058
- this.rsBlock = rsBlock;
1059
- this.totalDataCount = totalDataCount;
1060
- break;
1061
- }
1062
- }
1063
- };
999
+ // 40
1000
+ [19, 148, 118, 6, 149, 119],
1001
+ [18, 75, 47, 31, 76, 48],
1002
+ [34, 54, 24, 34, 55, 25],
1003
+ [20, 45, 15, 61, 46, 16]
1004
+ ]
1064
1005
 
1065
- //---------------------------------------------------------------------
1066
- // QRBitBuffer
1067
- //---------------------------------------------------------------------
1068
- function QRBitBuffer() {
1069
- this.buffer = new Array();
1070
- this.length = 0;
1071
- }
1072
- QRBitBuffer.prototype = {
1073
- get: function (index) {
1074
- var bufIndex = Math.floor(index / 8);
1075
- return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1;
1076
- },
1077
- put: function (num, length) {
1078
- for (var i = 0; i < length; i++) {
1079
- this.putBit((num >>> (length - i - 1)) & 1);
1080
- }
1081
- },
1082
- putBit: function (bit) {
1083
- var bufIndex = Math.floor(this.length / 8);
1084
- if (this.buffer.length <= bufIndex) {
1085
- this.buffer.push(0);
1086
- }
1087
- if (bit) {
1088
- this.buffer[bufIndex] |= 0x80 >>> this.length % 8;
1089
- }
1090
- this.length++;
1006
+ /**
1007
+ * 根据数据获取对应版本
1008
+ * @return {[type]} [description]
1009
+ */
1010
+ QRCodeAlg.prototype.getRightType = function () {
1011
+ for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
1012
+ var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel]
1013
+ if (rsBlock == undefined) {
1014
+ throw new Error(
1015
+ 'bad rs block @ typeNumber:' +
1016
+ typeNumber +
1017
+ '/errorCorrectLevel:' +
1018
+ this.errorCorrectLevel
1019
+ )
1020
+ }
1021
+ var length = rsBlock.length / 3
1022
+ var totalDataCount = 0
1023
+ for (var i = 0; i < length; i++) {
1024
+ var count = rsBlock[i * 3 + 0]
1025
+ var dataCount = rsBlock[i * 3 + 2]
1026
+ totalDataCount += dataCount * count
1027
+ }
1028
+ var lengthBytes = typeNumber > 9 ? 2 : 1
1029
+ if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
1030
+ this.typeNumber = typeNumber
1031
+ this.rsBlock = rsBlock
1032
+ this.totalDataCount = totalDataCount
1033
+ break
1034
+ }
1035
+ }
1091
1036
  }
1092
- };
1093
1037
 
1094
- // xzedit
1095
- let qrcodeAlgObjCache = [];
1096
- /**
1097
- * 二维码构造函数,主要用于绘制
1098
- * @param {参数列表} opt 传递参数
1099
- * @return {}
1100
- */
1101
- QRCode = function (opt) {
1102
- //设置默认参数
1103
- this.options = {
1104
- text: "",
1105
- size: 256,
1106
- correctLevel: 3,
1107
- background: "#ffffff",
1108
- foreground: "#000000",
1109
- pdground: "#000000",
1110
- image: "",
1111
- imageSize: 30,
1112
- canvasId: opt.canvasId,
1113
- nvueContext: opt.nvueContext,
1114
- context: opt.context,
1115
- usingComponents: opt.usingComponents,
1116
- showLoading: opt.showLoading,
1117
- loadingText: opt.loadingText
1118
- };
1119
- if (typeof opt === "string") {
1120
- // 只编码ASCII字符串
1121
- opt = {
1122
- text: opt
1123
- };
1124
- }
1125
- if (opt) {
1126
- for (var i in opt) {
1127
- this.options[i] = opt[i];
1128
- }
1038
+ //---------------------------------------------------------------------
1039
+ // QRBitBuffer
1040
+ //---------------------------------------------------------------------
1041
+ function QRBitBuffer() {
1042
+ this.buffer = new Array()
1043
+ this.length = 0
1129
1044
  }
1130
- //使用QRCodeAlg创建二维码结构
1131
- var qrCodeAlg = null;
1132
- for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1133
- if (
1134
- qrcodeAlgObjCache[i].text == this.options.text &&
1135
- qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1136
- ) {
1137
- qrCodeAlg = qrcodeAlgObjCache[i].obj;
1138
- break;
1139
- }
1140
- }
1141
- if (i == l) {
1142
- qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel);
1143
- qrcodeAlgObjCache.push({
1144
- text: this.options.text,
1145
- correctLevel: this.options.correctLevel,
1146
- obj: qrCodeAlg
1147
- });
1045
+ QRBitBuffer.prototype = {
1046
+ get: function (index) {
1047
+ var bufIndex = Math.floor(index / 8)
1048
+ return (this.buffer[bufIndex] >>> (7 - (index % 8))) & 1
1049
+ },
1050
+ put: function (num, length) {
1051
+ for (var i = 0; i < length; i++) {
1052
+ this.putBit((num >>> (length - i - 1)) & 1)
1053
+ }
1054
+ },
1055
+ putBit: function (bit) {
1056
+ var bufIndex = Math.floor(this.length / 8)
1057
+ if (this.buffer.length <= bufIndex) {
1058
+ this.buffer.push(0)
1059
+ }
1060
+ if (bit) {
1061
+ this.buffer[bufIndex] |= 0x80 >>> this.length % 8
1062
+ }
1063
+ this.length++
1064
+ }
1148
1065
  }
1066
+
1067
+ // xzedit
1068
+ let qrcodeAlgObjCache = []
1149
1069
  /**
1150
- * 计算矩阵点的前景色
1151
- * @param {Obj} config
1152
- * @param {Number} config.row 点x坐标
1153
- * @param {Number} config.col 点y坐标
1154
- * @param {Number} config.count 矩阵大小
1155
- * @param {Number} config.options 组件的options
1156
- * @return {String}
1070
+ * 二维码构造函数,主要用于绘制
1071
+ * @param {参数列表} opt 传递参数
1072
+ * @return {}
1157
1073
  */
1158
- let getForeGround = function (config) {
1159
- var options = config.options;
1160
- if (
1161
- options.pdground &&
1162
- ((config.row > 1 &&
1163
- config.row < 5 &&
1164
- config.col > 1 &&
1165
- config.col < 5) ||
1166
- (config.row > config.count - 6 &&
1167
- config.row < config.count - 2 &&
1168
- config.col > 1 &&
1169
- config.col < 5) ||
1170
- (config.row > 1 &&
1171
- config.row < 5 &&
1172
- config.col > config.count - 6 &&
1173
- config.col < config.count - 2))
1174
- ) {
1175
- return options.pdground;
1176
- }
1177
- return options.foreground;
1178
- };
1179
- // 为2D Canvas添加辅助函数
1180
- function drawIconWithBackground(canvas, ctx, options, qrCodeAlg) {
1181
- // 在小程序中使用canvas.createImage()而不是wx.createImage()
1182
- const img = canvas.createImage();
1183
- img.src = options.image;
1184
- img.onload = function() {
1185
- var ratioImgSize = options.imageSize || 40;
1186
- var x = Number(((options.size - ratioImgSize) / 2).toFixed(2));
1187
- var y = Number(((options.size - ratioImgSize) / 2).toFixed(2));
1188
-
1189
- // 绘制圆角矩形背景
1190
- drawRoundedRect2D(ctx, x, y, ratioImgSize, ratioImgSize, 2, options.background);
1191
-
1192
- // 绘制图标
1193
- ctx.drawImage(img, x, y, ratioImgSize, ratioImgSize);
1194
-
1195
- // 导出图片
1196
- exportCanvasImage(canvas, options);
1197
- };
1198
-
1199
- // 添加错误处理
1200
- img.onerror = function(e) {
1201
- console.error('Failed to load QR code icon:', e);
1202
- // 即使图标加载失败也要导出二维码
1203
- exportCanvasImage(canvas, options);
1204
- };
1205
- }
1206
-
1207
- function drawRoundedRect2D(ctx, x, y, width, height, r, fillColor) {
1208
- ctx.beginPath();
1209
- ctx.moveTo(x + r, y);
1210
- ctx.arcTo(x + width, y, x + width, y + r, r);
1211
- ctx.arcTo(x + width, y + height, x + width - r, y + height, r);
1212
- ctx.arcTo(x, y + height, x, y + height - r, r);
1213
- ctx.arcTo(x, y, x + r, y, r);
1214
- ctx.closePath();
1215
- ctx.fillStyle = fillColor;
1216
- ctx.fill();
1217
- }
1218
-
1219
- function exportCanvasImage(canvas, options) {
1220
- setTimeout(() => {
1221
- wx.canvasToTempFilePath({
1222
- canvas: canvas,
1223
- quality: 1,
1224
- success: function(res) {
1225
- if (options.cbResult) {
1226
- options.cbResult(res.tempFilePath);
1074
+ QRCode = function (opt) {
1075
+ //设置默认参数
1076
+ this.options = {
1077
+ text: '',
1078
+ size: 256,
1079
+ correctLevel: 3,
1080
+ background: '#ffffff',
1081
+ foreground: '#000000',
1082
+ pdground: '#000000',
1083
+ image: '',
1084
+ imageSize: 30,
1085
+ canvasId: opt.canvasId,
1086
+ nvueContext: opt.nvueContext,
1087
+ context: opt.context,
1088
+ usingComponents: opt.usingComponents,
1089
+ showLoading: opt.showLoading,
1090
+ loadingText: opt.loadingText
1091
+ }
1092
+ if (typeof opt === 'string') {
1093
+ // 只编码ASCII字符串
1094
+ opt = {
1095
+ text: opt
1227
1096
  }
1228
- },
1229
- fail: function(res) {
1230
- if (options.cbResult) {
1231
- options.cbResult(res);
1097
+ }
1098
+ if (opt) {
1099
+ for (var i in opt) {
1100
+ this.options[i] = opt[i]
1232
1101
  }
1233
- },
1234
- complete: function() {
1235
- uni.hideLoading();
1236
- }
1237
- }, options.context);
1238
- }, options.text.length + 100);
1239
- }
1240
-
1241
- // 2D Canvas二维码绘制函数
1242
- function drawQRCode2D(canvas, ctx, options, qrCodeAlg) {
1243
- var count = qrCodeAlg.getModuleCount();
1244
- var ratioSize = options.size;
1245
-
1246
- // 清除画布
1247
- ctx.clearRect(0, 0, ratioSize, ratioSize);
1248
- // 设置背景色
1249
- ctx.fillStyle = options.background;
1250
- ctx.fillRect(0, 0, ratioSize, ratioSize);
1251
-
1252
- //计算每个点的长宽
1253
- var tileW = (ratioSize / count).toPrecision(4);
1254
- var tileH = (ratioSize / count).toPrecision(4);
1255
-
1256
- //绘制二维码
1257
- for (var row = 0; row < count; row++) {
1258
- for (var col = 0; col < count; col++) {
1259
- var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
1260
- var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
1261
- var foreground = getForeGround({
1262
- row: row,
1263
- col: col,
1264
- count: count,
1265
- options: options
1266
- });
1267
- ctx.fillStyle = qrCodeAlg.modules[row][col] ? foreground : options.background;
1268
- ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
1269
1102
  }
1270
- }
1271
-
1272
- if (options.image) {
1273
- // 绘制中间图标
1274
- drawIconWithBackground(canvas, ctx, options, qrCodeAlg);
1275
- } else {
1276
- // 导出图片
1277
- exportCanvasImage(canvas, options);
1278
- }
1279
- }
1280
-
1281
- // 创建canvas
1282
- let createCanvas = function (options) {
1283
- if (options.showLoading) {
1284
- uni.showLoading({
1285
- title: options.loadingText,
1286
- mask: true
1287
- });
1288
- }
1289
-
1290
- // 尝试使用2D Canvas (小程序端)
1291
- try {
1292
- if (!options.nvueContext && typeof wx !== 'undefined' && wx.createSelectorQuery) {
1293
- const query = wx.createSelectorQuery().in(options.context);
1294
- query.select('#' + options.canvasId)
1295
- .fields({ node: true, size: true })
1296
- .exec((res) => {
1297
- if (res[0] && res[0].node) {
1298
- const canvas = res[0].node;
1299
- const ctx = canvas.getContext('2d');
1300
-
1301
- // 设置canvas尺寸
1302
- const dpr = wx.getSystemInfoSync().pixelRatio;
1303
- canvas.width = options.size * dpr;
1304
- canvas.height = options.size * dpr;
1305
- ctx.scale(dpr, dpr);
1306
-
1307
- // 创建二维码算法实例
1308
- var qrCodeAlg = new QRCodeAlg(options.text, options.correctLevel);
1309
-
1310
- // 使用2D Canvas绘制
1311
- drawQRCode2D(canvas, ctx, options, qrCodeAlg);
1312
- return;
1313
- }
1314
- });
1103
+ //使用QRCodeAlg创建二维码结构
1104
+ var qrCodeAlg = null
1105
+ for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
1106
+ if (
1107
+ qrcodeAlgObjCache[i].text == this.options.text &&
1108
+ qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel
1109
+ ) {
1110
+ qrCodeAlg = qrcodeAlgObjCache[i].obj
1111
+ break
1112
+ }
1315
1113
  }
1316
- } catch (e) {
1317
- console.warn('2D Canvas initialization failed, falling back to legacy mode:', e);
1318
- }
1319
-
1320
- // 回退到传统Canvas方式
1321
- var ctx = "";
1322
- if (options.nvueContext) {
1323
- ctx = options.nvueContext;
1324
- } else {
1325
- ctx = uni.createCanvasContext(options.canvasId, options.context);
1326
- }
1327
- var count = qrCodeAlg.getModuleCount();
1328
- var ratioSize = options.size;
1329
- var ratioImgSize = options.imageSize;
1330
- //计算每个点的长宽
1331
- var tileW = (ratioSize / count).toPrecision(4);
1332
- var tileH = (ratioSize / count).toPrecision(4);
1333
- //绘制
1334
- for (var row = 0; row < count; row++) {
1335
- for (var col = 0; col < count; col++) {
1336
- var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
1337
- var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
1338
- var foreground = getForeGround({
1339
- row: row,
1340
- col: col,
1341
- count: count,
1342
- options: options
1343
- });
1344
- ctx.setFillStyle(
1345
- qrCodeAlg.modules[row][col] ? foreground : options.background
1346
- );
1347
- ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
1114
+ if (i == l) {
1115
+ qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel)
1116
+ qrcodeAlgObjCache.push({
1117
+ text: this.options.text,
1118
+ correctLevel: this.options.correctLevel,
1119
+ obj: qrCodeAlg
1120
+ })
1348
1121
  }
1349
- }
1350
- if (options.image) {
1351
- var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
1352
- var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
1353
- drawRoundedRect(
1354
- ctx,
1355
- x,
1356
- y,
1357
- ratioImgSize,
1358
- ratioImgSize,
1359
- 2,
1360
- 6,
1361
- true,
1362
- true
1363
- );
1364
- ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
1365
- // 画圆角矩形
1366
- function drawRoundedRect(
1367
- ctxi,
1368
- x,
1369
- y,
1370
- width,
1371
- height,
1372
- r,
1373
- lineWidth,
1374
- fill,
1375
- stroke
1376
- ) {
1377
- ctxi.setLineWidth(lineWidth);
1378
- ctxi.setFillStyle(options.background);
1379
- ctxi.setStrokeStyle(options.background);
1380
- ctxi.beginPath(); // draw top and top right corner
1381
- ctxi.moveTo(x + r, y);
1382
- ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner
1383
- ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner
1384
- ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner
1385
- ctxi.arcTo(x, y, x + r, y, r);
1386
- ctxi.closePath();
1387
- if (fill) {
1388
- ctxi.fill();
1389
- }
1390
- if (stroke) {
1391
- ctxi.stroke();
1392
- }
1122
+ /**
1123
+ * 计算矩阵点的前景色
1124
+ * @param {Obj} config
1125
+ * @param {Number} config.row 点x坐标
1126
+ * @param {Number} config.col 点y坐标
1127
+ * @param {Number} config.count 矩阵大小
1128
+ * @param {Number} config.options 组件的options
1129
+ * @return {String}
1130
+ */
1131
+ let getForeGround = function (config) {
1132
+ var options = config.options
1133
+ if (
1134
+ options.pdground &&
1135
+ ((config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
1136
+ (config.row > config.count - 6 &&
1137
+ config.row < config.count - 2 &&
1138
+ config.col > 1 &&
1139
+ config.col < 5) ||
1140
+ (config.row > 1 &&
1141
+ config.row < 5 &&
1142
+ config.col > config.count - 6 &&
1143
+ config.col < config.count - 2))
1144
+ ) {
1145
+ return options.pdground
1146
+ }
1147
+ return options.foreground
1393
1148
  }
1394
- }
1395
- setTimeout(
1396
- () => {
1397
- ctx.draw(true, () => {
1398
- // 保存到临时区域
1399
- setTimeout(() => {
1400
- if (options.nvueContext) {
1401
- ctx.toTempFilePath(
1402
- 0,
1403
- 0,
1404
- options.width,
1405
- options.height,
1406
- options.width,
1407
- options.height,
1408
- "",
1409
- 1,
1410
- function (res) {
1411
- if (options.cbResult) {
1412
- options.cbResult(res.tempFilePath);
1149
+ // 创建canvas
1150
+ let createCanvas = function (options) {
1151
+ if (options.showLoading) {
1152
+ uni.showLoading({
1153
+ title: options.loadingText,
1154
+ mask: true
1155
+ })
1156
+ }
1157
+ var ctx = ''
1158
+ if (options.nvueContext) {
1159
+ ctx = options.nvueContext
1160
+ } else {
1161
+ ctx = uni.createCanvasContext(options.canvasId, options.context)
1162
+ }
1163
+ var count = qrCodeAlg.getModuleCount()
1164
+ var ratioSize = options.size
1165
+ var ratioImgSize = options.imageSize
1166
+ //计算每个点的长宽
1167
+ var tileW = (ratioSize / count).toPrecision(4)
1168
+ var tileH = (ratioSize / count).toPrecision(4)
1169
+ //绘制
1170
+ for (var row = 0; row < count; row++) {
1171
+ for (var col = 0; col < count; col++) {
1172
+ var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW)
1173
+ var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW)
1174
+ var foreground = getForeGround({
1175
+ row: row,
1176
+ col: col,
1177
+ count: count,
1178
+ options: options
1179
+ })
1180
+ ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background)
1181
+ ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h)
1182
+ }
1183
+ }
1184
+ if (options.image) {
1185
+ var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1186
+ var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2))
1187
+ drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
1188
+ ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize)
1189
+ // 画圆角矩形
1190
+ function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
1191
+ ctxi.setLineWidth(lineWidth)
1192
+ ctxi.setFillStyle(options.background)
1193
+ ctxi.setStrokeStyle(options.background)
1194
+ ctxi.beginPath() // draw top and top right corner
1195
+ ctxi.moveTo(x + r, y)
1196
+ ctxi.arcTo(x + width, y, x + width, y + r, r) // draw right side and bottom right corner
1197
+ ctxi.arcTo(x + width, y + height, x + width - r, y + height, r) // draw bottom and bottom left corner
1198
+ ctxi.arcTo(x, y + height, x, y + height - r, r) // draw left and top left corner
1199
+ ctxi.arcTo(x, y, x + r, y, r)
1200
+ ctxi.closePath()
1201
+ if (fill) {
1202
+ ctxi.fill()
1413
1203
  }
1414
- }
1415
- );
1416
- } else {
1417
- uni.canvasToTempFilePath(
1418
- {
1419
- width: options.width,
1420
- height: options.height,
1421
- destWidth: options.width,
1422
- destHeight: options.height,
1423
- canvasId: options.canvasId,
1424
- quality: Number(1),
1425
- success: function (res) {
1426
- if (options.cbResult) {
1427
- // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1428
- if (!empty(res.tempFilePath)) {
1429
- options.cbResult(res.tempFilePath);
1430
- } else if (!empty(res.apFilePath)) {
1431
- options.cbResult(res.apFilePath);
1432
- } else {
1433
- options.cbResult(res.tempFilePath);
1434
- }
1435
- }
1436
- },
1437
- fail: function (res) {
1438
- if (options.cbResult) {
1439
- options.cbResult(res);
1440
- }
1441
- },
1442
- complete: function () {
1443
- uni.hideLoading();
1204
+ if (stroke) {
1205
+ ctxi.stroke()
1444
1206
  }
1445
- },
1446
- options.context
1447
- );
1448
- }
1449
- }, options.text.length + 100);
1450
- });
1451
- },
1452
- options.usingComponents ? 0 : 150
1453
- );
1454
- };
1455
- createCanvas(this.options);
1456
- // 空判定
1457
- let empty = function (v) {
1458
- let tp = typeof v,
1459
- rt = false;
1460
- if (tp == "number" && String(v) == "") {
1461
- rt = true;
1462
- } else if (tp == "undefined") {
1463
- rt = true;
1464
- } else if (tp == "object") {
1465
- if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null)
1466
- rt = true;
1467
- } else if (tp == "string") {
1468
- if (
1469
- v == "" ||
1470
- v == "undefined" ||
1471
- v == "null" ||
1472
- v == "{}" ||
1473
- v == "[]"
1474
- )
1475
- rt = true;
1476
- } else if (tp == "function") {
1477
- rt = false;
1478
- }
1479
- return rt;
1480
- };
1481
- };
1482
- QRCode.prototype.clear = function (fn) {
1483
- var ctx = "";
1484
- if (options.nvueContext) {
1485
- ctx = options.nvueContext;
1486
- } else {
1487
- uni.createCanvasContext(this.options.canvasId, this.options.context);
1207
+ }
1208
+ }
1209
+ setTimeout(
1210
+ () => {
1211
+ ctx.draw(true, () => {
1212
+ // 保存到临时区域
1213
+ setTimeout(() => {
1214
+ if (options.nvueContext) {
1215
+ ctx.toTempFilePath(
1216
+ 0,
1217
+ 0,
1218
+ options.width,
1219
+ options.height,
1220
+ options.width,
1221
+ options.height,
1222
+ '',
1223
+ 1,
1224
+ function (res) {
1225
+ if (options.cbResult) {
1226
+ options.cbResult(res.tempFilePath)
1227
+ }
1228
+ }
1229
+ )
1230
+ } else {
1231
+ uni.canvasToTempFilePath(
1232
+ {
1233
+ width: options.width,
1234
+ height: options.height,
1235
+ destWidth: options.width,
1236
+ destHeight: options.height,
1237
+ canvasId: options.canvasId,
1238
+ quality: Number(1),
1239
+ success: function (res) {
1240
+ if (options.cbResult) {
1241
+ // 由于官方还没有统一此接口的输出字段,所以先判定下 支付宝为 res.apFilePath
1242
+ if (!empty(res.tempFilePath)) {
1243
+ options.cbResult(res.tempFilePath)
1244
+ } else if (!empty(res.apFilePath)) {
1245
+ options.cbResult(res.apFilePath)
1246
+ } else {
1247
+ options.cbResult(res.tempFilePath)
1248
+ }
1249
+ }
1250
+ },
1251
+ fail: function (res) {
1252
+ if (options.cbResult) {
1253
+ options.cbResult(res)
1254
+ }
1255
+ },
1256
+ complete: function () {
1257
+ uni.hideLoading()
1258
+ }
1259
+ },
1260
+ options.context
1261
+ )
1262
+ }
1263
+ }, options.text.length + 100)
1264
+ })
1265
+ },
1266
+ options.usingComponents ? 0 : 150
1267
+ )
1268
+ }
1269
+ createCanvas(this.options)
1270
+ // 空判定
1271
+ let empty = function (v) {
1272
+ let tp = typeof v,
1273
+ rt = false
1274
+ if (tp == 'number' && String(v) == '') {
1275
+ rt = true
1276
+ } else if (tp == 'undefined') {
1277
+ rt = true
1278
+ } else if (tp == 'object') {
1279
+ if (JSON.stringify(v) == '{}' || JSON.stringify(v) == '[]' || v == null) rt = true
1280
+ } else if (tp == 'string') {
1281
+ if (v == '' || v == 'undefined' || v == 'null' || v == '{}' || v == '[]') rt = true
1282
+ } else if (tp == 'function') {
1283
+ rt = false
1284
+ }
1285
+ return rt
1286
+ }
1287
+ }
1288
+ QRCode.prototype.clear = function (fn) {
1289
+ var ctx = ''
1290
+ if (options.nvueContext) {
1291
+ ctx = options.nvueContext
1292
+ } else {
1293
+ uni.createCanvasContext(this.options.canvasId, this.options.context)
1294
+ }
1295
+ ctx.clearRect(0, 0, this.options.size, this.options.size)
1296
+ ctx.draw(false, () => {
1297
+ if (fn) {
1298
+ fn()
1299
+ }
1300
+ })
1488
1301
  }
1489
- ctx.clearRect(0, 0, this.options.size, this.options.size);
1490
- ctx.draw(false, () => {
1491
- if (fn) {
1492
- fn();
1493
- }
1494
- });
1495
- };
1496
- })();
1302
+ })()
1497
1303
 
1498
- export default QRCode;
1304
+ export default QRCode