Automattic / Automattic/node-canvas
How can I draw special characters in the canvas?
- Dominant language
- JavaScript
- Stars
- 10.7k
- Forks
- 1.2k
- Avg merge
- 4d 8h
- Merged PRs (30d)
- 1
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
```javascript
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.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.