barcode.js 6.5 KB

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