import QRCodeUtil from 'qrcode'; import { createMemo, JSXElement } from "solid-js" const generateMatrix = ( value: string, errorCorrectionLevel: QRCodeUtil.QRCodeErrorCorrectionLevel ) => { const arr = Array.prototype.slice.call( QRCodeUtil.create(value, { errorCorrectionLevel }).modules.data, 0 ); const sqrt = Math.sqrt(arr.length); return arr.reduce( (rows, key, index) => (index % sqrt === 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) && rows, [] ); }; type Props = { ecl?: QRCodeUtil.QRCodeErrorCorrectionLevel; size?: number; uri: string; clearArea?: boolean; image?: HTMLImageElement; imageBackground?: string; }; export function QRCode({ ecl = 'M', size: sizeProp = 200, uri, clearArea = false, image, imageBackground = 'transparent', }: Props) { const logoSize = clearArea ? 32 : 0; const size = sizeProp - 10 * 2; const dots = createMemo(() => { const dots: JSXElement[] = []; const matrix = generateMatrix(uri, ecl); const cellSize = size / matrix.length; let qrList = [ { x: 0, y: 0 }, { x: 1, y: 0 }, { x: 0, y: 1 }, ]; qrList.forEach(({ x, y }) => { const x1 = (matrix.length - 7) * cellSize * x; const y1 = (matrix.length - 7) * cellSize * y; for (let i = 0; i < 3; i++) { dots.push( ); } }); if (image) { const x1 = (matrix.length - 7) * cellSize * 1; const y1 = (matrix.length - 7) * cellSize * 1; dots.push( <>
{image}
); } const clearArenaSize = Math.floor((logoSize + 25) / cellSize); const matrixMiddleStart = matrix.length / 2 - clearArenaSize / 2; const matrixMiddleEnd = matrix.length / 2 + clearArenaSize / 2 - 1; matrix.forEach((row: QRCodeUtil.QRCode[], i: number) => { row.forEach((_: any, j: number) => { if (matrix[i][j]) { // Do not render dots under position squares if ( !( (i < 7 && j < 7) || (i > matrix.length - 8 && j < 7) || (i < 7 && j > matrix.length - 8) ) ) { //if (image && i > matrix.length - 9 && j > matrix.length - 9) return; if ( image || !( i > matrixMiddleStart && i < matrixMiddleEnd && j > matrixMiddleStart && j < matrixMiddleEnd ) ) { dots.push( ); } } } }); }); return dots; }, [ecl, size, uri]); return ( {dots()} ); }