// 导入所有条形码 // @ts-nocheck import barcodes from './jsbarcode/barcodes/'; import fixOptions from './jsbarcode/help/fixOptions'; import merge from './jsbarcode/help/merge'; import defaultOptions from './jsbarcode/options/defaults'; import { InvalidInputException } from './jsbarcode/exceptions/exceptions'; import linearizeEncodings from './jsbarcode/help/linearizeEncodings'; import { calculateEncodingAttributes, getTotalWidthOfEncodings, getMaximumHeightOfEncodings } from "./jsbarcode/renderers/shared"; import { LBarcodeOptions, EncodeResult } from './type' function autoSelectBarcode() : string { // 如果有 CODE128,则使用它 if (barcodes["CODE128"]) { return "CODE128"; } // 否则,使用第一个(或唯一)条形码 return Object.keys(barcodes)[0]; } // encode() 处理编码器调用并生成要呈现的二进制数据 function encode(text : string, Encoder : any, options : LBarcodeOptions) : any { // 确保文本是字符串 text = "" + text; let encoder = new Encoder(text, options); // 如果输入对编码器无效,则抛出错误。如果已设置有效回调选项,则调用该选项 if (!encoder.valid()) { throw new InvalidInputException(encoder.constructor.name, text); } // 为要呈现的二进制数据发出请求(和其他信息) let encoded = encoder.encode(); // 编码可以像 [1-1, 1-2], 2, [3-1, 3-2] 一样嵌套 // 将其转换为 [1-1, 1-2, 2, 3-1, 3-2] encoded = linearizeEncodings(encoded); // 合并 for (let i = 0; i< encoded.length; i++) { encoded[i].options = merge(options, encoded[i].options); } return encoded; } let timer = null function prepareCanvas(element : any, encodings : any, options : LBarcodeOptions) { const ctx = element.getContext('2d'); ctx.save(); calculateEncodingAttributes(encodings, options, ctx); const totalWidth = getTotalWidthOfEncodings(encodings); const maxHeight = getMaximumHeightOfEncodings(encodings); const width = totalWidth + options.marginLeft + options.marginRight // 为避免报黄 Multiple readback operations using getImageData element.width = width; element.height = maxHeight } function drawCanvasBarcode(element : any, options : LBarcodeOptions, encoding : EncodeResult) { // Get the canvas context const ctx = element.getContext("2d"); const binary = encoding.data; // Creates the barcode out of the encoded binary let yFrom = 0; if (options.textPosition == "top") { yFrom = options.marginTop + options.fontSize + options.textMargin; } else { yFrom = options.marginTop; } ctx.fillStyle = options.lineColor; for (let b = 0; b < binary.length; b++) { let x = b * options.width + encoding.barcodePadding; if (binary[b] === "1") { ctx.fillRect(x, yFrom, options.width, options.height); } else if (binary[b]) { ctx.fillRect(x, yFrom, options.width, options.height * parseInt(binary[b])); } } } function drawCanvasText(element : any, options : LBarcodeOptions, encoding : EncodeResult) { // Get the canvas context const ctx = element.getContext("2d"); const font = `${options.fontOptions} ${options.fontSize}px ${options.font}`.trim(); // Draw the text if displayValue is set if (options.displayValue) { let x = 0, y = 0; if (options.textPosition == "top") { y = options.marginTop + options.fontSize - options.textMargin; } else { y = options.height + options.textMargin + options.marginTop + options.fontSize; } ctx.font = font; // Draw the text in the correct X depending on the textAlign option if (options.textAlign == "left" || encoding.barcodePadding > 0) { x = 0; ctx.textAlign = 'left'; } else if (options.textAlign == "right") { x = encoding.width - 1; ctx.textAlign = 'right'; } // In all other cases, center the text else { x = encoding.width / 2; ctx.textAlign = 'center'; } ctx.fillText(encoding.text, x, y); } } function moveCanvasDrawing(element : any, encoding: EncodeResult) { const ctx = element.getContext("2d"); ctx.translate(encoding.width, 0); } export function CanvasRenderer(element : any, text : string, options : LBarcodeOptions, cb: ()=> void) { if (typeof element === "undefined") { throw Error("No element to render on was provided."); } if (text) { let newOptions = { ...defaultOptions, text }; for (let key in options) { const value = options[key] if (value || typeof value == 'boolean') { newOptions[key] = value } } newOptions = fixOptions(newOptions); if (!newOptions.format || newOptions.format == "auto") { newOptions.format = autoSelectBarcode(); } if (!element.getContext) { throw new Error('不存在 getContext'); } const ctx = element.getContext('2d'); const Encoder = barcodes[newOptions.format.toUpperCase()]; const encodings = encode(text, Encoder, newOptions); prepareCanvas(element, encodings, newOptions) // Paint the canvas // clearTimeout(timer) setTimeout(() => { ctx.clearRect(0, 0, element.width, element.height); if (newOptions.background) { ctx.fillStyle = newOptions.background; ctx.fillRect(0, 0, element.width, element.height); } ctx.translate(newOptions.marginLeft, 0); // render for (let i = 0; i < encodings.length; i++) { const encodingOptions = merge(newOptions, encodings[i].options); drawCanvasBarcode(element, encodingOptions, encodings[i]); drawCanvasText(element, encodingOptions, encodings[i]); moveCanvasDrawing(element, encodings[i]); } // render end ctx.restore(); if (ctx.draw) { ctx.draw(false, cb) } else { cb && cb() } }, 300) } }