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

JS Canvas已显示但无法更新的问题排查求助

Canvas绘制内容不显示的问题排查与解决

核心问题原因

你遇到的问题根源在于:通过canvas.outerHTML将Canvas转为HTML字符串时,会生成一个全新的Canvas元素副本,而定时器中操作的是最初创建的、未被插入页面的Canvas上下文——两者不是同一个对象,所以所有绘制操作都作用在内存中的Canvas,页面上显示的副本自然是空白的。

解决方案

方案一:直接操作DOM元素(推荐)

放弃HTML字符串拼接的方式,直接创建DOM元素并挂载Canvas,确保定时器操作的是页面上实际显示的Canvas:

// 修改getWeaponTooltip方法
public static getWeaponTooltip(weapon: Weapon) {
    // 创建tooltip根容器
    const tooltipRoot = document.createElement('div');
    
    // 处理其他tooltip内容(示例:可通过innerHTML或createElement添加)
    // tooltipRoot.innerHTML = '<div class="weapon-name">' + weapon.name + '</div>';
    
    // 创建Canvas容器并添加Canvas
    const canvasWrapper = document.createElement('div');
    canvasWrapper.className = 'canvasWrapper';
    // 注意补上原方法定义的id参数
    const canvas = this.getTooltipParticlesCanvas(weapon.rarity, weapon.id);
    canvasWrapper.appendChild(canvas);
    tooltipRoot.appendChild(canvasWrapper);
    
    // 返回DOM元素,后续直接挂载到目标容器
    return tooltipRoot;
}

// 调用方式(替换原innerHTML赋值)
const targetDiv = document.getElementById('your-tooltip-div');
targetDiv.appendChild(YourClass.getWeaponTooltip(weapon));

方案二:若必须使用innerHTML(不推荐)

如果项目限制只能用字符串拼接,需要在Canvas插入DOM后重新获取元素并绑定定时器:

// 拆分Canvas逻辑为配置+初始化方法
public static getTooltipParticlesConfig(rarity: Data.Rarity, id: number) { 
    return {
        width: 232,
        height: 53,
        init: (canvas: HTMLCanvasElement) => {
            let posY = 25, posX = 25;
            const ctx = canvas.getContext("2d");
            
            clearInterval(this.particlesTooltipCanvasInterval);
            this.particlesTooltipCanvasInterval = setInterval(() => {
                ctx.fillStyle = "white";
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                posY -= 0.25;
        
                ctx.fillStyle = "green";
                ctx.fillRect(posX, posY, 5, 5);
                console.log("Refreshed");
            }, 30);
        }
    };
}

// 修改getWeaponTooltip方法
public static getWeaponTooltip(weapon: Weapon) {
    const config = this.getTooltipParticlesConfig(weapon.rarity, weapon.id);
    const canvasId = `tooltip-canvas-${weapon.id}`;
    let str = '';
    
    // 拼接其他tooltip内容
    // str += '<div class="weapon-info">...</div>';
    
    // 拼接带唯一ID的Canvas字符串
    str += `<div class="canvasWrapper"><canvas id="${canvasId}" width="${config.width}" height="${config.height}" style="border:1px dashed grey;position:absolute;left:0;"></canvas></div>`;
    
    // 确保DOM插入后初始化Canvas
    setTimeout(() => {
        const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
        config.init(canvas);
    }, 0);
    
    return str;
}

额外注意点

原getTooltipParticlesCanvas方法定义了id参数,但调用时未传递,需要补上参数避免语法错误。

内容的提问来源于stack exchange,提问作者nitroxone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:55:15