barcode.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. const barcodes = require('./barcodes/index.js')['default'];
  2. let barcode = {};
  3. (function () {
  4. // 初始化
  5. barcode = function (cont, ctxid, options, ctxsize, result) {
  6. let ops = {}, newOptions, encodings, globaContext, ctx, globaCtxid, cbCanvasSize, cbResult;
  7. globaCtxid = ctxid
  8. cbCanvasSize = ctxsize
  9. cbResult = result
  10. newOptions = Object.assign(ops, options);
  11. // 修成margin
  12. fixMargin(newOptions)
  13. // 处理options 数据
  14. if (newOptions.text == '' || cont == '') {
  15. return false
  16. }
  17. // 获取ctx
  18. globaContext = cont
  19. ctx = uni.createCanvasContext(globaCtxid, globaContext)
  20. // 获取编码数据
  21. encodings = new barcodes[newOptions.format.toUpperCase()](newOptions.text, newOptions).encode()
  22. let fixencodings = fixEncodings(encodings, newOptions)
  23. // 返回canvas实际大小
  24. cbCanvasSize({ width: fixencodings.width, height: fixencodings.height })
  25. // 绘制canvas
  26. setTimeout(() => {
  27. drawCanvas.render(newOptions, fixencodings)
  28. }, 50);
  29. // 绘制canvas
  30. let drawCanvas = {
  31. render(options, encoding) {
  32. this.prepare(options, encoding)
  33. encoding.encodings.forEach((v, i) => {
  34. this.barcode(options, v)
  35. this.text(options, v)
  36. this.move(v)
  37. });
  38. this.draw(options, encoding)
  39. },
  40. barcode(options, encoding) {
  41. let binary = encoding.data;
  42. let yFrom;
  43. if (options.textPosition == "top") {
  44. yFrom = options.marginTop + options.fontSize + options.textMargin;
  45. } else {
  46. yFrom = options.marginTop;
  47. }
  48. // 绘制条码
  49. ctx.fillStyle = options.lineColor;
  50. for (let b = 0; b < binary.length; b++) {
  51. let x = b * options.width + encoding.barcodePadding;
  52. let height = options.height
  53. if (encoding.options) {
  54. if (encoding.options.height != undefined) {
  55. height = encoding.options.height
  56. }
  57. }
  58. if (binary[b] === "1") {
  59. ctx.fillRect(x, yFrom, options.width, height);
  60. } else if (binary[b]) {
  61. ctx.fillRect(x, yFrom, options.width, height * binary[b]);
  62. }
  63. }
  64. },
  65. text(options, encoding) {
  66. return
  67. if (options.displayValue) {
  68. let x, y, align, size;
  69. if (options.textPosition == "top") {
  70. y = options.marginTop + options.fontSize;
  71. } else {
  72. y = options.height + options.textMargin + options.marginTop + options.fontSize;
  73. }
  74. if (encoding.options) {
  75. if (encoding.options.textAlign != undefined) {
  76. align = encoding.options.textAlign
  77. }
  78. if (encoding.options.fontSize != undefined) {
  79. size = encoding.options.fontSize
  80. }
  81. } else {
  82. align = options.textAlign
  83. size = options.fontSize
  84. }
  85. ctx.setFontSize(size)
  86. if (align == "left" || encoding.barcodePadding > 0) {
  87. x = 0;
  88. ctx.setTextAlign('left')
  89. } else if (align == "right") {
  90. x = encoding.width - 1;
  91. ctx.setTextAlign('right')
  92. }
  93. else {
  94. x = encoding.width / 2;
  95. ctx.setTextAlign('center');
  96. }
  97. ctx.fillStyle = options.fontColor;
  98. if (encoding.text != undefined) {
  99. ctx.fillText(encoding.text, x, y);
  100. }
  101. }
  102. },
  103. move(encoding) {
  104. ctx.translate(encoding.width, 0);
  105. },
  106. prepare(options, encoding) {
  107. // 绘制背景
  108. if (options.background) {
  109. ctx.fillStyle = options.background;
  110. ctx.fillRect(0, 0, encoding.width, encoding.height);
  111. }
  112. ctx.translate(options.marginLeft, 0);
  113. },
  114. draw(options, encoding) {
  115. ctx.draw(false, () => {
  116. this.toImgs(options, encoding)
  117. })
  118. },
  119. toImgs(options, encoding) {
  120. setTimeout(() => {
  121. uni.canvasToTempFilePath({
  122. width: encoding.width,
  123. height: encoding.height,
  124. destWidth: encoding.width,
  125. destHeight: encoding.height,
  126. canvasId: globaCtxid,
  127. fileType: 'png',
  128. success: function (res) {
  129. cbResult(res.tempFilePath)
  130. },
  131. fail: function (res) {
  132. cbResult(res)
  133. },
  134. complete: function () {
  135. uni.hideLoading();
  136. },
  137. }, globaContext);
  138. }, options.text.length + 100);
  139. }
  140. }
  141. // 混入canvas数据
  142. function fixEncodings(encoding, options) {
  143. let encodingArr = [], width = options.marginLeft + options.marginRight, height;
  144. if (!Array.isArray(encoding)) {
  145. encodingArr[0] = JSON.parse(JSON.stringify(encoding))
  146. } else {
  147. encodingArr = [...encoding]
  148. }
  149. encodingArr.forEach((v, i) => {
  150. // 获取文本宽度
  151. let textWidth = ctx.measureText(encodingArr[i].text ? encodingArr[i].text : '').width;
  152. // 获取条形码宽度
  153. let barcodeWidth = encodingArr[i].data.length * options.width;
  154. // 获取内边距
  155. let barcodePadding = 0;
  156. if (options.displayValue && barcodeWidth < textWidth) {
  157. if (options.textAlign == "center") {
  158. barcodePadding = Math.floor((textWidth - barcodeWidth) / 2);
  159. } else if (options.textAlign == "left") {
  160. barcodePadding = 0;
  161. } else if (options.textAlign == "right") {
  162. barcodePadding = Math.floor(textWidth - barcodeWidth);
  163. }
  164. }
  165. // 混入encodingArr[i]
  166. encodingArr[i].barcodePadding = barcodePadding
  167. encodingArr[i].width = Math.ceil(Math.max(textWidth, barcodeWidth))
  168. width += encodingArr[i].width
  169. if (encodingArr[i].options) {
  170. if (encodingArr[i].options.height != undefined) {
  171. encodingArr[i].height = encodingArr[i].options.height + (options.displayValue && (encodingArr[i].text ? encodingArr[i].text : '').length > 0 ? options.fontSize + options.textMargin : 0) + options.marginTop + options.marginBottom;
  172. } else {
  173. encodingArr[i].height = height = options.height + (options.displayValue && (encodingArr[i].text ? encodingArr[i].text : '').length > 0 ? options.fontSize + options.textMargin : 0) + options.marginTop + options.marginBottom;
  174. }
  175. } else {
  176. encodingArr[i].height = height = options.height + (options.displayValue && (encodingArr[i].text ? encodingArr[i].text : '').length > 0 ? options.fontSize + options.textMargin : 0) + options.marginTop + options.marginBottom;
  177. }
  178. });
  179. return { encodings: encodingArr, width, height };
  180. }
  181. // 修正Margin
  182. function fixMargin(options) {
  183. options.marginTop = options.marginTop == undefined ? options.margin : options.marginTop;
  184. options.marginBottom = options.marginBottom == undefined ? options.margin : options.marginBottom;
  185. options.marginRight = options.marginRight == undefined ? options.margin : options.marginRight;
  186. options.marginLeft = options.marginLeft == undefined ? options.margin : options.marginLeft;
  187. }
  188. };
  189. })()
  190. export default barcode