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

JavaScript Canvas绘制骰子时矩形点位置异常问题求解

骰子绘制问题修复方案

问题原因

你的代码存在2处核心错误:

  • 绘制逻辑错误:当前使用fillRect绘制占满3x3网格单元格的矩形,既不符合骰子点数的圆形形态,也会因为铺满单元格导致你认为位置偏移。
  • 缺少画布清空逻辑:每次调用drawDice方法前没有清空画布,多次调用会残留之前的点数内容,叠加后显示异常。

修复后代码

export class Dice {
    constructor() {
        this.canvas_dice = document.getElementById("dice-canvas");
    }

    drawDice(value) {
        let ctx = this.canvas_dice.getContext('2d');
        let canvas_size = this.canvas_dice.width;
        let grid_size = canvas_size / 3; // 3x3网格每个单元格的尺寸
        let dot_radius = grid_size * 0.3; // 圆点半径,可自行调整大小

        // 3x3网格的点位置矩阵保持原有逻辑不变
        let matrice = {
            1: [[1, 1]],
            2: [[0, 0], [2, 2]],
            3: [[0, 0], [1, 1], [2, 2]],
            4: [[0, 0], [2, 0], [0, 2], [2, 2]],
            5: [[0, 0], [2, 0], [0, 2], [2, 2], [1, 1]],
            6: [[0, 0], [0, 1], [0, 2], [2, 0], [2, 1], [2, 2]]
        }

        // 新增:绘制前清空画布,避免残留之前的内容
        ctx.clearRect(0, 0, canvas_size, canvas_size);

        // 可选优化:绘制骰子白色背景和边框,更贴近真实样式
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas_size, canvas_size);
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 2;
        ctx.strokeRect(0, 0, canvas_size, canvas_size);

        matrice[value].forEach(dot => {
            // 计算网格单元格中心点作为圆点圆心
            let centerX = dot[0] * grid_size + grid_size / 2;
            let centerY = dot[1] * grid_size + grid_size / 2;

            ctx.fillStyle = 'rgb(255, 0, 0)';
            // 用圆形绘制替代原有的矩形绘制
            ctx.beginPath();
            ctx.arc(centerX, centerY, dot_radius, 0, Math.PI * 2);
            ctx.fill();
        });
    }
}

注意事项

请确保canvas标签的width和height属性值和你需要的实际显示尺寸一致,不要只通过CSS设置canvas的宽高,否则会出现绘制内容拉伸变形的问题。
调用方式和原有逻辑完全一致,不需要修改现有调用代码。如果觉得圆点大小不合适,调整dot_radius的计算系数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:06:01