utils.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // import extend from 'extend'
  2. // import { extend } from "@/utils/lodash";
  3. import {
  4. QRCode,
  5. QRErrorCorrectLevel
  6. } from './qrcode.js'
  7. // support Chinese
  8. function utf16to8(str) {
  9. var out, i, len, c
  10. out = ''
  11. len = str.length
  12. for (i = 0; i < len; i++) {
  13. c = str.charCodeAt(i)
  14. if ((c >= 0x0001) && (c <= 0x007F)) {
  15. out += str.charAt(i)
  16. } else if (c > 0x07FF) {
  17. out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
  18. out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
  19. out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
  20. } else {
  21. out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
  22. out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
  23. }
  24. }
  25. return out
  26. }
  27. function drawQrcode(options, debug) {
  28. options = options || {}
  29. options = Object.assign(true, {
  30. canvasId: 'myQrcode',
  31. // canvas: canvas,
  32. text: '爱一个人就要勇敢说出来',
  33. width: 260,
  34. height: 260,
  35. padding: 20,
  36. // paddingColor: '#ffffff', // 默认与background一致
  37. typeNumber: -1,
  38. correctLevel: QRErrorCorrectLevel.H,
  39. background: '#ffffff',
  40. foreground: '#000000',
  41. image: {
  42. imageResource: '',
  43. width: 80,
  44. height: 80,
  45. round: true
  46. }
  47. }, options)
  48. if (!options.canvasId && !options.canvas) {
  49. console.warn('please set canvasId or canvas!')
  50. return
  51. }
  52. if (!options.paddingColor) options.paddingColor = options.background
  53. if (debug) {
  54. var qrcode = new QRCode(options.typeNumber, options.correctLevel)
  55. qrcode.addData(utf16to8(options.text))
  56. qrcode.make()
  57. return new Promise(function (resolve, reject) {
  58. resolve(qrcode);
  59. })
  60. } else {
  61. return new Promise(function (resolve, reject) {
  62. return resolve(createCanvas());
  63. })
  64. }
  65. function createCanvas() {
  66. // create the qrcode itself
  67. var qrcode = new QRCode(options.typeNumber, options.correctLevel)
  68. qrcode.addData(utf16to8(options.text))
  69. qrcode.make()
  70. var dpr = 1
  71. // #ifdef MP-WEIXIN
  72. dpr = wx.getSystemInfoSync().pixelRatio
  73. // #endif
  74. var canvas = options.canvas
  75. const ctx = canvas.getContext('2d')
  76. canvas.width = options.width * dpr
  77. canvas.height = options.width * dpr
  78. const width = canvas.width
  79. // 背景色
  80. ctx.fillStyle = options.paddingColor
  81. ctx.fillRect(0, 0, width + options.padding * 2, width + options.padding * 2);
  82. var tileW = (width - options.padding * 2) / qrcode.getModuleCount()
  83. var tileH = (width - options.padding * 2) / qrcode.getModuleCount()
  84. // 开始画二维码
  85. for (var row = 0; row < qrcode.getModuleCount(); row++) {
  86. for (var col = 0; col < qrcode.getModuleCount(); col++) {
  87. ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background
  88. var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW))
  89. var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW))
  90. ctx.fillRect(Math.round(col * tileW) + options.padding, Math.round(row * tileH) + options.padding, w, h);
  91. }
  92. }
  93. if (options.image.imageResource) {
  94. const imgW = options.image.width * dpr
  95. const imgH = options.image.height * dpr
  96. const dx = (width - imgW) / 2
  97. const dy = (width - imgH) / 2
  98. if (options.image.round) {
  99. // Logo边框
  100. const imgW2 = options.image.width * dpr + 5
  101. const dx2 = (width - imgW2) / 2
  102. const r2 = imgW2 / 2
  103. const cx2 = dx2 + r2;
  104. ctx.beginPath();
  105. ctx.arc(cx2, cx2, r2, 0, 2 * Math.PI);
  106. ctx.fillStyle = '#ffffff'
  107. ctx.fill();
  108. ctx.restore();
  109. // 画Logo
  110. const r = imgW / 2
  111. const cx = dx + r;
  112. const cy = dy + r;
  113. ctx.beginPath();
  114. ctx.arc(cx, cy, r, 0, 2 * Math.PI);
  115. ctx.clip();
  116. ctx.drawImage(options.image.imageResource, dx, dy, imgW, imgW);
  117. ctx.restore();
  118. } else {
  119. ctx.drawImage(options.image.imageResource, dx, dy, imgW, imgH)
  120. ctx.restore();
  121. }
  122. }
  123. return ctx
  124. }
  125. }
  126. export default drawQrcode