Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 25x 25x 25x 625x 625x 625x 214x 214x 625x 625x 625x 625x 25x 25x 25x 25x 25x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 65x 65x 65x 1641x 1641x 1641x 65x 65x 5x 5x 4x 4x 1x 1x 1x | /** * * @param {object} opts - function parameters * @param {number} [opts.cellSize] - cell size in pixels, defaults to 1 * @param {number} [opts.margin] - margin in pixels, defaults to {@link cellSize} * 2 * @param {import('../qr-code.js').QrCode} opts.qrcode - QR Code data * @returns {string} qr code in ASCII */ export function renderASCII ({ cellSize = 1, margin, qrcode }) { if (cellSize < 2) { return _createHalfASCII({ margin, qrcode }) } cellSize -= 1 margin ??= cellSize * 2 const size = qrcode.moduleCount * cellSize + margin * 2 const min = margin const max = size - margin let y, x, r, p const white = Array(cellSize + 1).join('██') const black = Array(cellSize + 1).join(' ') let ascii = '' let line = '' for (y = 0; y < size; y += 1) { r = Math.floor((y - min) / cellSize) line = '' for (x = 0; x < size; x += 1) { p = 1 if (min <= x && x < max && min <= y && y < max && qrcode.isDark(r, Math.floor((x - min) / cellSize))) { p = 0 } // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. line += p ? white : black } for (r = 0; r < cellSize; r += 1) { ascii += line + '\n' } } return ascii.slice(0, -1) } /** * * @param {object} opts - function parameters * @param {number} [opts.margin] - margin in pixels, defaults to 2 * @param {import('../qr-code.js').QrCode} opts.qrcode - QR Code data * @returns {string} qr code in ASCII */ function _createHalfASCII ({ margin = 2, qrcode }) { const cellSize = 1 const size = qrcode.moduleCount * cellSize + margin * 2 const min = margin const max = size - margin /** @type {Record<string, string>} */ const blocks = { '██': '█', '█ ': '▀', ' █': '▄', ' ': ' ', } /** @type {Record<string, string>} */ const blocksLastLineNoMargin = { '██': '▀', '█ ': '▀', ' █': ' ', ' ': ' ', } /** @type {(x: number, y: number) => boolean} */ const isDarkPoint = (x, y) => min <= x && x < max && min <= y && y < max && qrcode.isDark((y - min), (x - min)) /** @type {(x: number, y: number) => '█'|' '} */ const codePoint = (x, y) => isDarkPoint(x, y) ? ' ' : '█' let ascii = '' for (let y = 0; y < size; y += 2) { // used to output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. const blockToUse = (margin < 1 && y + 1 >= max) ? blocksLastLineNoMargin : blocks for (let x = 0; x < size; x += 1) { const p = codePoint(x, y) + codePoint(x, y + 1) ascii += blockToUse[p] } ascii += '\n' } if (size % 2 && margin > 0) { return ascii.slice(0, -size - 1) + Array(size + 1).join('▀') } return ascii.slice(0, -1) } |