Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I draw special characters in the canvas? #2479

Open
dinhduchuy-dev opened this issue Jan 5, 2025 · 0 comments
Open

How can I draw special characters in the canvas? #2479

dinhduchuy-dev opened this issue Jan 5, 2025 · 0 comments

Comments

@dinhduchuy-dev
Copy link

dinhduchuy-dev commented Jan 5, 2025

I realized a problem when working with canvas is that my special characters always become a square, I tried to find out and realized that the font format I am using is tff instead of woff2 but I still get the error in my code. Because I use canvas version 3.0.1 they don't support woff2 format fonts so tooii uses the included fontkit as a 3rd library. Here is my code

function drawAlignedText(ctx, text, x, y, font, options = {}) {
  const {
    fontSize = 30,
    color = "black",
    horizontalAlign = "start", // Căn chỉnh ngang: left, center, right
    verticalAlign = "top", // Căn chỉnh dọc: top, middle, bottom
  } = options;

  const scale = fontSize / font.unitsPerEm;

  if (isNaN(scale)) {
    console.error('Giá trị scale là NaN. Kiểm tra lại giá trị fontSize và font.unitsPerEm.');
    console.log('fontSize:', fontSize);
    console.log('font.unitsPerEm:', font.unitsPerEm);
  }
  

  // Tính glyphs và chiều rộng của văn bản
  const glyphs = font.glyphsForString(text);
  const textWidth =
    glyphs.reduce((width, glyph) => width + glyph.advanceWidth, 0) * scale;
  const textHeight = (font.ascent - font.descent) * scale;

  // Điều chỉnh vị trí bắt đầu vẽ dựa vào lựa chọn căn chỉnh
  let startX = x;
  let startY = y;

  // Căn chỉnh ngang
  if (horizontalAlign === "center") {
    startX = x - textWidth / 2; // Căn giữa theo chiều ngang
  } else if (horizontalAlign === "end") {
    startX = x - textWidth; // Căn phải
  }

  // Căn chỉnh dọc
  if (verticalAlign === "middle") {
    startY = y + textHeight / 2 - font.ascent * scale; // Căn giữa theo chiều dọc
  } else if (verticalAlign === "bottom") {
    startY = y - font.ascent * scale; // Căn dưới
  }

  // Vẽ từng glyph
  ctx.fillStyle = color;
  let currentX = startX;

  glyphs.forEach((glyph) => {
    ctx.save();
    ctx.translate(currentX, startY);
    ctx.scale(scale, -scale); // Lật theo trục y để đúng hướng
    ctx.beginPath();

    // Vẽ đường dẫn glyph lên canvas
    glyph.path.commands.forEach((cmd) => {
      if (cmd.command === "moveTo") {
        ctx.moveTo(cmd.args[0], cmd.args[1]);
      } else if (cmd.command === "lineTo") {
        ctx.lineTo(cmd.args[0], cmd.args[1]);
      } else if (cmd.command === "quadraticCurveTo") {
        ctx.quadraticCurveTo(
          cmd.args[0],
          cmd.args[1],
          cmd.args[2],
          cmd.args[3]
        );
      } else if (cmd.command === "bezierCurveTo") {
        ctx.bezierCurveTo(
          cmd.args[0],
          cmd.args[1],
          cmd.args[2],
          cmd.args[3],
          cmd.args[4],
          cmd.args[5]
        );
      } else if (cmd.command === "closePath") {
        ctx.closePath();
      }
    });

    ctx.fill();
    ctx.restore();
    currentX += glyph.advanceWidth * scale;
  });
}

Uh when I pass the parameter to the text as a string "AG丶NhanMBム" They get an error and no longer display the correct string I pass in, even when I use a font with woff2 format and this makes me quite sad. headache

Is there any way I can print all kinds of special characters on canvas images? I really need an answer because my Messenger Bot has to handle special data like this...

Because I used canvas's ctx.fillText and it was broken, I asked ChatGPT for advice. The above code is just ChatGPT's code that was modified by drawing each glyph.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant