You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js 14中Canvas绘制文字不显示问题求助

问题分析与解决方案

你的文字无法显示主要有两个核心原因:

  1. 字体加载异常:@napi-rs/canvas依赖系统已安装的字体,Sans-Serif作为通用字体族,若你的环境中没有对应的 fallback 字体,会导致文字无法渲染。
  2. 上下文状态未恢复:设置裁剪路径后未恢复上下文状态,虽文字绘制在裁剪前,但后续操作可能间接影响渲染;同时将文字放在头像之后绘制,能确保文字处于最上层,避免被其他元素意外覆盖。

修正后的代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:27:01