如何解决HTML画布大小的奇数问题?

时间:2019-02-21 20:10:55

标签: javascript html html5 canvas html5-canvas

我正在使用HTML-canvas-element。

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(0, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(canvas.width / 3, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();
<canvas id="c" width="541" height="541"></canvas>

问题:当我选择一个奇数(在本例中为质数541)作为画布大小并在其上绘制一个矩形(大小:整个画布的1/3)时。

但这是结果:

enter image description here

放大:

enter image description here

如您所见:2个矩形之间有一条多余的线。我该如何解决这个问题?

Math.floor()Math.round()Math.ceil()舍入值(可能)不是一种选择,因为3个矩形的宽度之和必须等于画布的宽度

3 个答案:

答案 0 :(得分:1)

您似乎在使用不兼容HiDPI的画布方法时,正在使用HiDPI(高DPI,视网膜)模式(操作系统级别的缩放超过100%)。

解决方案是将width元素的heightwindow.devicePixelRatio HTML 属性(或元素的DOM属性)的值与{{1 }},同时将其相应的 CSS 属性设置为您当前的大小。然后,您的画布将与HiDPI兼容且无模糊。这就是我在web demo的非模糊整数比例缩放中所使用的:

var pixelRatio = window.devicePixelRatio;

canvas.width  = 541 * pixelRatio;
canvas.height = 541 * pixelRatio;

canvas.style.width  = '' + 541 + 'px';
canvas.style.height = '' + 541 + 'px';

另一种方法是使用上下文对象的scale()方法,而不是设置CSS大小。这就是HTML5Rocks recommends中的Paul Lewis:

var pixelRatio = window.devicePixelRatio;

canvas.width  = 541 * pixelRatio;
canvas.height = 541 * pixelRatio;

canvas.getContext('2d').scale(pixelRatio, pixelRatio);

答案 1 :(得分:0)

如果使用样式标签或CSS文件,效果很好

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(0, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(canvas.width / 3, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();
.canvas {
    width: 541px;
    height: 541px;
}
<canvas id="c" class="canvas"></canvas>

答案 2 :(得分:0)

不确定是否喜欢此解决方案,但只能在x2上使用Math.floor()

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(0, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();

// use here to make sure that the start position of the secound rect is right
var x2 = Math.floor(canvas.width / 3);

ctx.beginPath();
ctx.fillStyle = "#FF0000";
ctx.rect(x2, 0, canvas.width / 3, canvas.height / 3);
ctx.fill();
ctx.closePath();
<canvas id="c" width="541" height="541"></canvas>