【问题标题】:Canvas alignment issue画布对齐问题
【发布时间】:2018-10-17 10:09:00
【问题描述】:

我想生成一个显示NxNsquares 的字段。 (在示例中显示 2x2 红色方块) 在画布的中心。方块所在的区域应在画布中水平和垂直居中。 (当然也是在更改 rowCount 之后)

此外,fieldSize 声明了红色方块对齐的计算区域的大小。更改因子将更改字段大小。 (1 == 画布大小,0.5 = 1/2 画布大小


我的问题:

在下面的示例中(很难看到),红色框并没有真正居中,但我希望它们居中。看看这张图片:

let canvas = document.getElementById("canvas")


/* edit these values */
let rowCount = 2
let fieldSize = canvas.width * 0.8
/********************/


let ctx = canvas.getContext("2d")

for (let y = 0; y < rowCount; y++) {
  for (let x = 0; x < rowCount; x++) {

    let squareSize = (fieldSize / rowCount) * 0.7

    let positionX = (fieldSize / rowCount) * (x) + (canvas.width - fieldSize) * 0.5
    let positionY = (fieldSize / rowCount) * (y) + (canvas.width - fieldSize) * 0.5

    ctx.rect(positionX, positionY, squareSize, squareSize);
    ctx.fillStyle = "red"
    ctx.fill()
  }

}
&lt;canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"&gt;&lt;/canvas&gt;

【问题讨论】:

    标签: javascript html css math canvas


    【解决方案1】:

    采用没有填充的“内部空间”,并在其上展开你的方块。 由于舍入问题,您不能随意使用填充/间距的所有组合。要生成完美的网格,您必须使用离散的正方形大小来防止锯齿或模糊效果。

    function tiled(canvas, rowCount) {
      const ctx = canvas.getContext("2d");
      const spacing = 10;
      const padding = 30;
      const cellSize = (canvas.width - 2 * padding + spacing) / rowCount;
      const squareSize = cellSize - spacing;
    
      let positionX = padding;
      let positionY = padding;
    
      for (let y = 0; y < rowCount; y++) {
        positionX = padding;
        for (let x = 0; x < rowCount; x++) {
          ctx.rect(positionX, positionY, squareSize, squareSize);
          ctx.fillStyle = "red"
          ctx.fill();
          positionX += cellSize;
        }
        positionY += cellSize;
      }
    }
    
    tiled(document.getElementById("canvas"), 2);
    tiled(document.getElementById("canvas2"), 3);
    tiled(document.getElementById("canvas3"), 4);
    tiled(document.getElementById("canvas4"), 5);
    <canvas style="background: green" id="canvas" width="300" height="300"></canvas>
    <canvas style="background: green" id="canvas2" width="300" height="300"></canvas>
    <canvas style="background: green" id="canvas3" width="300" height="300"></canvas>
    <canvas style="background: green" id="canvas4" width="300" height="300"></canvas>

    【讨论】:

    • 看起来也是一个非常好的解决方案。但也存在字段大小缺少属性的问题。你愿意编辑吗?
    • 隐式 fieldSize 存在,它是canvas.width - 2*padding 或者,填充是0.5*(canvas.width - fieldSize)
    【解决方案2】:

    这可能会有所帮助!

    let canvas = document.getElementById("canvas")
    
    /* edit these values */
    let rowCount = 2
    let fieldSize = canvas.width * 0.8
    /********************/
    
    let ctx = canvas.getContext("2d")
    
    let width = canvas.width;
    let height = canvas.height;
    
    let dist = canvas.width/(rowCount + 1)
    
    for(let i=1;i<=rowCount;i++){
      for(let j=1;j<=rowCount;j++){
      let w = (fieldSize / rowCount) * 0.8
        let posx = dist*i - w/2;
        let posy = dist*j - w/2;
        ctx.rect(posx,posy,w,w);
        ctx.fillStyle = "blue"
        ctx.fill();
      }
    }
    &lt;canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"&gt;&lt;/canvas&gt;

    【讨论】:

    • 看起来是一个非常好的解决方案。非常感谢。但看起来 fieldSize 属性不再起作用了。 (您应该能够指定正方形所在区域的大小,例如 0.8 作为画布宽度的因子。您介意更新您的解决方案吗?
    【解决方案3】:

    你可以这样做(它适用于任意数量的行):

    (canvas.width - fieldSize) / 2)
    

    用于填充字段

    x * (fieldSize / rowCount)
    

    是每个方格的相对位置

    (fieldSize / rowCount - squareSize) / 2
    

    用于每个正方形的填充,您的代码中缺少该填充

    /* edit these values */
    let rowCount = 2
    let fieldSize = canvas.width * 0.8
    let squareSize = (fieldSize / rowCount) * 0.8
    /********************/
    
    
    let ctx = canvas.getContext("2d")
    
    for (let y = 0; y < rowCount; y++) {
        for (let x = 0; x < rowCount; x++) {
    
            let positionX = (canvas.width - fieldSize) / 2 + x * (fieldSize / rowCount) + (fieldSize / rowCount - squareSize) / 2
            let positionY = (canvas.width - fieldSize) / 2 + y * (fieldSize / rowCount) + (fieldSize / rowCount - squareSize) / 2
    
            ctx.rect(positionX, positionY, squareSize, squareSize);
            ctx.fillStyle = "red"
            ctx.fill()
        }
    }
    &lt;canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 2012-11-08
      • 2014-01-12
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多