alipay-emulator/uni_modules/lime-barcode/components/l-barcode/barcode.ts

178 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 导入所有条形码
// @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)
}
}