Description
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.
Activity