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

基于长度输入动态填充4个Canvas的切换问题排查

问题分析与解决方案

你的问题核心有三个:

  • 所有绘制逻辑都硬编码在canvas1上,完全没处理超出画布宽度后切换到其他画布的逻辑
  • 后端传入的长度是字符串类型,直接用于计算会导致错误
  • fillRect的起始坐标计算错误,你用的是单个元素的长度,而不是累计已绘制的总宽度

下面是修复后的完整代码,我把重复的变量改成了数组,用循环来处理绘制和画布切换,逻辑更清晰:

<canvas id="canvas1" width="300" height="50"></canvas>
<canvas id="canvas2" width="300" height="50"></canvas>
<canvas id="canvas3" width="300" height="50"></canvas>
<canvas id="canvas4" width="100" height="50"></canvas>

<script type="text/javascript">
    // 把后端传入的值转成数组,同时把长度转为数字
    const heads = [
        <%=head[0]%>, <%=head[1]%>, <%=head[2]%>, <%=head[3]%>, <%=head[4]%>,
        <%=head[5]%>, <%=head[6]%>, <%=head[7]%>, <%=head[8]%>, <%=head[9]%>
    ].map(Number);
    
    const colors = [
        '<%=prd_color[0]%>', '<%=prd_color[1]%>', '<%=prd_color[2]%>', '<%=prd_color[3]%>', '<%=prd_color[4]%>',
        '<%=prd_color[5]%>', '<%=prd_color[6]%>', '<%=prd_color[7]%>', '<%=prd_color[8]%>', '<%=prd_color[9]%>'
    ];

    // 画布列表,按顺序处理
    const canvases = [
        document.getElementById("canvas1"),
        document.getElementById("canvas2"),
        document.getElementById("canvas3"),
        document.getElementById("canvas4")
    ];
    
    let currentCanvasIndex = 0;
    let currentCtx = canvases[currentCanvasIndex].getContext("2d");
    let remainingWidth = canvases[currentCanvasIndex].width;
    let totalDrawn = 0; // 累计已绘制的总宽度

    for (let i = 0; i < heads.length; i++) {
        const itemWidth = heads[i];
        const itemColor = colors[i];

        // 如果当前元素能完全放进剩余空间,直接绘制
        if (itemWidth <= remainingWidth) {
            currentCtx.fillStyle = itemColor;
            currentCtx.fillRect(totalDrawn % canvases[currentCanvasIndex].width, 0, itemWidth, 50);
            totalDrawn += itemWidth;
            remainingWidth -= itemWidth;
        } else {
            // 先绘制当前画布剩余的部分
            currentCtx.fillStyle = itemColor;
            currentCtx.fillRect(totalDrawn % canvases[currentCanvasIndex].width, 0, remainingWidth, 50);
            
            // 切换到下一个画布
            currentCanvasIndex++;
            if (currentCanvasIndex >= canvases.length) break; // 没有更多画布,停止绘制
            
            currentCtx = canvases[currentCanvasIndex].getContext("2d");
            const remainingItemWidth = itemWidth - remainingWidth;
            
            // 绘制剩余部分到新画布
            currentCtx.fillStyle = itemColor;
            currentCtx.fillRect(0, 0, remainingItemWidth, 50);
            
            totalDrawn += itemWidth;
            remainingWidth = canvases[currentCanvasIndex].width - remainingItemWidth;
        }
    }
</script>

关键改进点:

  1. 数组化处理:把10个单独的变量改成数组,用循环遍历,避免重复代码,也方便后续扩展
  2. 类型转换:用map(Number)把后端传入的字符串长度转为数字,确保计算正确
  3. 画布切换逻辑:实时判断当前画布剩余空间,不够时自动切换到下一个画布,同时拆分当前元素的绘制
  4. 坐标计算修正:用totalDrawn % 当前画布宽度来获取当前画布上的起始坐标,确保绘制位置正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:50:24