Text to ASCII Art Generator

Bài viết này là hướng dẫn thực chiến để bạn tự tay dựng một bộ chuyển đổi “text → ASCII art” chạy ngay trong trình duyệt. Ta sẽ thiết kế font ma trận 5×6, viết engine ghép ký tự theo hàng/cột, hỗ trợ giãn tỉ lệ, khoảng cách, kiểu Block/Outline/Slim.

Text to ASCII Art Generator

Tổng quan giải pháp

  • Font ma trận: Mỗi ký tự là ma trận nhị phân 5×6 (0/1) — 1 là pixel bật, 0 là tắt.
  • Engine render: Duyệt chuỗi theo từng hàng (row-major), ghép cột của từng glyph, thêm spacing giữa các glyph.
  • Biến đổi kiểu chữ:
    • Block: hiển thị đầy đủ khối 1.
    • Outline: chỉ giữ viền (pixel 1 giáp pixel 0).
    • Slim: tinh chỉnh để mảnh hơn (lọc một số cụm 1-1-1 thành 1-0-1).
  • Giãn tỉ lệ: hscale/vscale nhân lặp phần tử theo chiều ngang/dọc.

Demo

Thiết kế font ma trận

Ý tưởng: mỗi ký tự là 6 chuỗi, mỗi chuỗi dài 5 ký tự ‘0’/’1′. Ví dụ, ký tự A:

01110
10001
10001
11111
10001
10001

Bảng font gốc (Block) được định nghĩa bằng đối tượng JavaScript. Tránh ký tự phân tách “|” để không bị CMS làm hỏng chuỗi.

const FONT_BLOCK = {
  'A': ['01110','10001','10001','11111','10001','10001'],
  'B': ['11110','10001','11110','10001','10001','11110'],
  // ...A-Z, 0-9, khoảng trắng, dấu -, ., !, ?
};

Engine ghép ASCII: từ ma trận đến văn bản

Chúng ta duyệt theo hàng (6 hàng). Với mỗi glyph, ghép chuỗi hàng tương ứng vào rows[r], sau đó thêm spacing cột 0 để tạo khoảng cách giữa các ký tự. Giãn ngang bằng lặp bit, giãn dọc bằng lặp dòng.

function renderASCII(text, { font='block', char='#', hscale=1, vscale=1, spacing=1 }) {
  text = (text ?? '').toUpperCase();
  const map = FONTS[font] || FONT_BLOCK;
  const glyphRows = 6, glyphCols = 5;
  const glyphs = Array.from(text, ch => map[ch] || map['?']);

  // Ghép theo hàng
  const rows = Array.from({ length: glyphRows }, () => '');
  for (const g of glyphs) {
    for (let r = 0; r < glyphRows; r++) {
      const row = g[r] || '0'.repeat(glyphCols);
      let scaled = '';
      for (const bit of row) scaled += bit.repeat(hscale); // giãn ngang
      rows[r] += scaled + '0'.repeat(spacing);             // khoảng trắng giữa glyph
    }
  }
  // Giãn dọc
  const out = [];
  for (const line of rows) for (let k = 0; k < vscale; k++) out.push(line);
  // Map 0/1 → ' '/char
  return out.map(line => line.replace(/1/g, char).replace(/0/g, ' ')).join('\n');
}

Tạo biến thể font: Outline và Slim

Outline: giữ pixel biên (1 tiếp giáp 0 ở 4 hướng). Slim: làm mảnh những cụm dày 1-1-1 thành 1-0-1.

function makeOutline(block) {
  const out = {};
  for (const k in block) {
    const g = block[k].map(r => r.split('').map(Number));
    const h = g.length, w = g[0].length, edge = [];
    const dirs = [[1,0],[-1,0],[0,1],[0,-1]];
    for (let y=0;y<h;y++){
      let line = '';
      for (let x=0;x<w;x++){
        if (!g[y][x]) { line += '0'; continue; }
        let boundary = false;
        for (const [dx,dy] of dirs){
          const nx=x+dx, ny=y+dy;
          if (nx<0||ny<0||nx>=w||ny>=h||g[ny][nx]===0){ boundary = true; break; }
        }
        line += boundary ? '1' : '0';
      }
      edge.push(line);
    }
    out[k] = edge;
  }
  return out;
}

function makeSlim(block) {
  const out = {};
  for (const k in block) {
    out[k] = block[k].map(row => row.replace(/111/g,'101'));
  }
  return out;
}

Mở rộng font: thêm ký tự mới

Ví dụ thêm dấu gạch dưới _ và dấu hai chấm : (tuỳ biến theo style của bạn):

FONT_BLOCK['_'] = ['00000','00000','00000','00000','00000','11111'];
FONT_BLOCK[':'] = ['00000','00100','00100','00000','00100','00100'];

Tiền xử lý văn bản đầu vào

Chúng ta giới hạn ASCII art ở A–Z, 0–9, khoảng trắng và một vài ký tự. Với ký tự khác, chuyển thành dấu hỏi ?. Bạn có thể thêm bước “latin hóa” nếu muốn hỗ trợ chữ có dấu, ví dụ “HÀO” → “HAO”.

function normalizeText(input) {
  return (input || '')
    .normalize('NFD')           // tách dấu
    .replace(/\p{Diacritic}+/gu,'') // bỏ dấu
    .toUpperCase()
    .replace(/[^A-Z0-9 \-\.!\?:]/g, '?'); // ràng buộc tập ký tự
}

Mẹo trình bày

  • Dùng font monospace khi hiển thị (đã cấu hình sẵn trong demo).
  • Giữ hscalevscale ở 1–3 cho độ đọc tốt; >=4 có thể “vỡ” bố cục trên màn hình nhỏ.
  • Chọn ký tự vẽ có độ phủ đều (ví dụ #/@) để đường viền rõ ràng; . sẽ mỏng, hợp kiểu Slim.

Mở rộng tính năng (gợi ý nâng cấp)

  • Tự thiết kế font: tạo công cụ “glyph editor” nhỏ dùng checkbox 5×6 để vẽ ký tự, xuất JSON vào FONT_BLOCK.
  • Kerning thô: với kí tự mảnh như I, giảm spacing riêng; với W, tăng spacing.
  • Multi-line: tách theo \n, render từng dòng rồi ghép bằng 2–3 dòng trống ở giữa.
  • Templates: thêm preset Matrix (char = 1), Dots (char = .), Solid (char = #).

Kết luận

Với một bảng font ma trận nhỏ gọn và engine ghép chuỗi đơn giản, bạn đã có một “Text to ASCII Art Generator” mượt, dễ mở rộng, chạy ngay trong bài viết — hoàn toàn không lệ thuộc thư viện ngoài, lại cách ly CSS tuyệt đối nhờ Shadow DOM.

Bình luận


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...