Discord.js 14中Canvas绘制文字不显示问题求助
问题分析与解决方案
你的文字无法显示主要有两个核心原因:
- 字体加载异常:
@napi-rs/canvas依赖系统已安装的字体,Sans-Serif作为通用字体族,若你的环境中没有对应的 fallback 字体,会导致文字无法渲染。 - 上下文状态未恢复:设置裁剪路径后未恢复上下文状态,虽文字绘制在裁剪前,但后续操作可能间接影响渲染;同时将文字放在头像之后绘制,能确保文字处于最上层,避免被其他元素意外覆盖。
修正后的代码
const { AttachmentBuilder, Client, Events, GatewayIntentBits, Partials } = require('discord.js'); const Canvas = require('@napi-rs/canvas'); const token = require('./config.json'); const client = new Client({ intents: [ GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildPresences, GatewayIntentBits.DirectMessages, GatewayIntentBits.Guilds, GatewayIntentBits.GuildBans, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ], partials: [Partials.Channel], }); client.once(Events.ClientReady, () => { console.log('Im ready!'); }); client.on('interactionCreate', async i => { if (i.commandName === "profilepic") { const canvas = Canvas.createCanvas(1920, 1080); const context = canvas.getContext('2d'); // 绘制背景图 const background = await Canvas.loadImage('./profpic.jpg'); context.drawImage(background, 0, 0, canvas.width, canvas.height); // 绘制边框 context.strokeStyle = '#b21f00'; context.strokeRect(0, 0, canvas.width, canvas.height); // 保存当前上下文状态(裁剪操作前) context.save(); // 创建头像裁剪圆形路径 context.beginPath(); context.arc(879, 350, 115, 0, Math.PI * 2, true); context.closePath(); context.clip(); // 绘制用户头像 const avatar = await Canvas.loadImage(i.user.displayAvatarURL({ extension: 'jpg' })); context.drawImage(avatar, 755, 220, 250, 250); // 恢复上下文状态,解除裁剪限制 context.restore(); // 绘制文字(放在最后,确保显示在最上层) // 使用系统确定存在的字体,比如Arial,可替换为你环境中已安装的字体 context.font = 'bold 100px Arial'; context.fillStyle = '#ffffff'; // 调整y坐标为文字基线位置,让文字更居中 context.fillText("test", 720, canvas.height / 2 + 40); const attachment = new AttachmentBuilder(await canvas.encode('png'), {name: 'profile-image.png'}); await i.reply({files: [attachment]}); } }); client.login(token);
额外注意事项
- 字体自定义:若Arial仍无法显示,可手动加载本地字体文件,示例如下:
// 在创建canvas前加载字体 await Canvas.loadFont('./your-font-file.ttf'); // 使用字体名称(需与字体文件内的名称一致) context.font = 'bold 100px "Your Font Name"'; - 坐标微调:
fillText的y参数是文字的基线位置,可根据背景图布局调整数值,让文字位置更贴合需求。
内容的提问来源于stack exchange,提问作者Servantr
相关产品推荐
相关产品推荐

