画布对齐问题
Posted
技术标签:
【中文标题】画布对齐问题【英文标题】:Canvas alignment issue 【发布时间】:2018-10-17 10:09:00 【问题描述】:我想生成一个显示NxN
squares 的字段。 (在示例中显示 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()
<canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"></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" ></canvas>
<canvas style="background: green" id="canvas2" ></canvas>
<canvas style="background: green" id="canvas3" ></canvas>
<canvas style="background: green" id="canvas4" ></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();
<canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"></canvas>
【讨论】:
看起来是一个非常好的解决方案。非常感谢。但看起来 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()
<canvas style="background: green" id="canvas" width="300" height="300" id="codeCanvas"></canvas>
【讨论】:
以上是关于画布对齐问题的主要内容,如果未能解决你的问题,请参考以下文章
通过字母在画布上绘制文本,以控制单个字母的alpha,同时与中心对齐
R语言ggplot2可视化自定义配置标题(title)和整个画板(画布)左对齐(aligns with the whole plot)使用plot.title.position参数