提高HTML5 Canvas分辨率

13

我尝试了这里的所有方法,但似乎没有一种能够在我的代码上起作用,或者说我不知道如何应用。

我想要在我的HTML画布中获得更好的分辨率,因为矩形看起来有些“模糊”。

这是我的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Resize</title>
    <style>
        canvas {
            border: 1px solid black;
        }

        body {
            margin: 0px;
        }
    </style>
</head>
<body>
    <canvas id="sig-canvas" width="1280" height="739"></canvas>
    <p id="timer"></p>
    <script src="canvas.js"></script>
</body>
</html>

JavaScript:

var canvas = document.getElementById("sig-canvas");
var ctx = canvas.getContext("2d");

var drawing = false;
var mousePos = { x:0, y:0 };
var lastPos = mousePos;
canvas.addEventListener("mousemove", function (e) {
  mousePos = getMousePos(canvas, e);
    drawing = true;
}, false);

// Get the position of the mouse relative to the canvas
function getMousePos(canvasDom, mouseEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: mouseEvent.clientX - rect.left,
    y: mouseEvent.clientY - rect.top
  };
}

// Get a regular interval for drawing to the screen
window.requestAnimFrame = (function (callback) {
        return window.requestAnimationFrame || 
           window.webkitRequestAnimationFrame ||
           window.mozRequestAnimationFrame ||
           window.oRequestAnimationFrame ||
           window.msRequestAnimaitonFrame ||
           function (callback) {
        window.setTimeout(callback, 1000/60);
           };
})();

// Draw to the canvas
function renderCanvas() {
  if (drawing) {
    ctx.fillStyle = "#FFFFFF";
    ctx.fillRect(mousePos.x, mousePos.y, 25, 25);

    ctx.strokeStyle = "#000000";
    ctx.lineWidth   = 2;
    ctx.strokeRect(mousePos.x, mousePos.y, 25, 25);
    lastPos = mousePos;
  }
}

// Allow for animation
(function drawLoop () {
  requestAnimFrame(drawLoop);
  renderCanvas();
})();

这是我的示例:https://jsfiddle.net/8cp5qmob/

谢谢!

3个回答

16
为了提高画布的分辨率,我建议您尝试混合使用canvas.style.widthcanvas.style.height(用于屏幕上占用的像素数量)以及canvas.widthcanvas.height (用于内部使用的像素数量)。代码如下所示:

JavaScript:

var displayWidth = 1280;
var displayHeight = 739;
var canvas = document.getElementById("sig-canvas");
var scale = 2;
canvas.style.width = displayWidth + 'px';
canvas.style.height = displayHeight + 'px';
canvas.width = displayWidth * scale;
canvas.height = displayHeight * scale;

画布的大小是有限制的。请参阅Mozilla 开发者网络页面了解更多信息。

使用这种技术的另一个棘手问题是,在屏幕坐标和画布坐标之间进行转换时,必须乘以或除以比例尺。在这种情况下,我在getMousePos中将屏幕坐标转换为画布坐标:

function getMousePos(canvasDom, mouseEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: (mouseEvent.clientX - rect.left) * scale,
    y: (mouseEvent.clientY - rect.top) * scale
  };
}

以下是一个展示所有内容的片段:

var displayWidth = 1280;
var displayHeight = 739;
var canvas = document.getElementById("sig-canvas");
var scale = 2;
canvas.style.width = displayWidth + 'px';
canvas.style.height = displayHeight + 'px';
canvas.width = displayWidth * scale;
canvas.height = displayHeight * scale;
var ctx = canvas.getContext("2d");

var drawing = false;
var mousePos = { x:0, y:0 };
var lastPos = mousePos;
canvas.addEventListener("mousemove", function (e) {
  mousePos = getMousePos(canvas, e);
    drawing = true;
}, false);

// Get the position of the mouse relative to the canvas
function getMousePos(canvasDom, mouseEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: (mouseEvent.clientX - rect.left) * scale,
    y: (mouseEvent.clientY - rect.top) * scale
  };
}

// Get a regular interval for drawing to the screen
window.requestAnimFrame = (function (callback) {
        return window.requestAnimationFrame || 
           window.webkitRequestAnimationFrame ||
           window.mozRequestAnimationFrame ||
           window.oRequestAnimationFrame ||
           window.msRequestAnimaitonFrame ||
           function (callback) {
        window.setTimeout(callback, 1000/60);
           };
})();

// Draw to the canvas
function renderCanvas() {
  if (drawing) {
    ctx.fillStyle = "#FFFFFF";
    ctx.fillRect(mousePos.x, mousePos.y, 25, 25);

    ctx.strokeStyle = "#000000";
    ctx.lineWidth   = 2;
    ctx.strokeRect(mousePos.x, mousePos.y, 25, 25);
    lastPos = mousePos;
  }
}

// Allow for animation
(function drawLoop () {
  requestAnimFrame(drawLoop);
  renderCanvas();
})();
canvas {
    border: 1px solid black;
}

body {
    margin: 0px;
}
<canvas id="sig-canvas"></canvas>


非常感谢!这正是我所寻找的! - Rita Duarte
我可以建议使用 ctx.scale 吗? - RamenChef
是的,最好的选择是使用ctx.scale,因为对于高分辨率显示器来说,矩形会更小。你还可以考虑使用onresize与更新函数一起使用,这样你可以将顶部的内容封装成一个函数,并像这样使用: onresize = myFunction - Infigon
哇,谢谢你提出这个问题和这个好答案,我几乎在所有的应用程序中都使用它。非常感谢。 - AlirezaBest

1
据我所见,它们对我来说似乎不模糊。但如果您想确保,您总是可以替换。
ctx.fillStyle = "#FFFFFF"; & ctx.strokeStyle = "#000000";

With

ctx.fillStyle = "rgba(255, 255, 255, 1)"; & ctx.strokeStyle = "rgba(0, 0, 0, 1)";

这样做可以使该行始终具有最大不透明度。

0

你应该让你的canvas元素使用%来定义大小,这样它总是可以在页面上占据最大的空间,这也有助于提高分辨率。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接