我有一个<div style="border:1px solid border;" />
和画布,使用:
context.lineWidth = 1;
context.strokeStyle = "gray";
绘图看起来相当模糊(lineWidth小于1会创建更糟糕的图片),并且没有任何靠近div的边框。是否可以使用画布获得与HTML相同的绘图质量?
var ctx = document.getElementById("canvas").getContext("2d");
ctx.lineWidth = 1;
ctx.moveTo(2, 2);
ctx.lineTo(98, 2);
ctx.lineTo(98, 98);
ctx.lineTo(2, 98);
ctx.lineTo(2, 2);
ctx.stroke();
div {
border: 1px solid black;
width: 100px;
height: 100px;
}
canvas, div {background-color: #F5F5F5;}
canvas {border: 1px solid white;display: block;}
<table>
<tr><td>Line on canvas:</td><td>1px border:</td></tr>
<tr><td><canvas id="canvas" width="100" height="100"/></td><td><div> </div></td></tr>
</table>
答案 0 :(得分:58)
我发现在CSS中设置画布大小会导致我的图像以模糊的方式显示。
试试这个:
<canvas id="preview" width="640" height="260"></canvas>
根据我的帖子:HTML Blurry Canvas Images
答案 1 :(得分:49)
更容易解决的问题就是使用它:
context = canvas.context2d;
context.translate(0.5, 0.5);
从现在开始,您的坐标应该调整为0.5像素。
答案 2 :(得分:40)
在画布中绘制线条时,实际上需要跨越像素。在我看来,这是API中一个奇怪的选择,但易于使用:
而不是:
context.moveTo(10, 0);
context.lineTo(10, 30);
这样做:
context.moveTo(10.5, 0);
context.lineTo(10.5, 30);
dive into HTML5's canvas chapter talks about this nicely
(寻找'ASK PROFESSOR MARKUP'框大约1/4的方式)
答案 3 :(得分:7)
我使用视网膜显示器,我找到了一个适合我的解决方案here。
小概述:
首先,您需要将画布的大小设置为您想要的两倍,例如:
canvas = document.getElementById('myCanvas');
canvas.width = 200;
canvas.height = 200;
然后使用CSS将其设置为所需的大小:
canvas.style.width = "100px";
canvas.style.height = "100px";
最后,您将绘图上下文缩放为2:
canvas.getContext('2d').scale(2,2);
答案 4 :(得分:3)
线条模糊,因为画布虚拟尺寸 已缩放为其HTML元素实际尺寸。要解决此问题,您需要在绘制之前调整画布虚拟大小:
function Draw () {
var e, surface;
e = document.getElementById ("surface");
/* Begin size adjusting. */
e.width = e.offsetWidth;
e.height = e.offsetHeight;
/* End size adjusting. */
surface = e.getContext ("2d");
surface.strokeRect (10, 10, 20, 20);
}
window.onload = Draw ()
&#13;
<!DOCTYPE html>
<html>
<head>
<title>Canvas size adjusting demo</title>
</head>
<body>
<canvas id="surface"></canvas>
</body>
</html>
&#13;
HTML:
答案 5 :(得分:2)
好的,我已经一劳永逸了。您需要做两件事:
为此,您需要将css的高度和宽度计算为:
var myCanvasEl = document.getElementById('myCanvas');
var ctx = myCanvasEl.getContext('2d');
myCanvasEl.style.height = myCanvasEl.height / window.devicePixelRatio + "px";
myCanvasEl.style.width = myCanvasEl.width / window.devicePixelRatio + "px";
其中myCanvasEl.style.height
和myCanvasEl.style.width
是元素的css样式高度和宽度,而myCanvasEl.height
和myCanvasEl.width
是画布的高度和宽度。
旧答案(被以上内容取代):
这是我在2020年找到的最佳解决方案。请注意,我已将devicePixelRatio乘以2:
var size = 100;
var scale = window.devicePixelRatio*2;
context.width = size * scale;
cartesian_001El.style.height = cartesian_001El.height / window.devicePixelRatio + "px";
cartesian_001El.style.height = cartesian_001El.height / window.devicePixelRatio + "px";
context.height = size * scale;
context.scale(scale, scale);
答案 6 :(得分:1)
要在动画中避免此问题,我想分享一个小demo。
基本上我每次检查增量值&amp;通过删除浮点值来跳入一组1px。
HTML:
<canvas id="canvas" width="600" height="600"></canvas>
CSS:
html, body{
height: 100%;
}
body{
font-family: monaco, Consolas,"Lucida Console", monospace;
background: #000;
}
canvas{
position: fixed;
top: 0;
left: 0;
transform: translateZ(0);
}
JS:
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
ctx.translate(0.5, 0.5);
var i = 0;
var iInc = 0.005;
var range = 0.5;
raf = window.requestAnimationFrame(draw);
function draw() {
var animInc = EasingFunctions.easeInQuad(i) * 250;
ctx.clearRect(0, 0, 600, 600);
ctx.save();
ctx.beginPath();
ctx.strokeStyle = '#fff';
var rectInc = 10 + animInc;
// Avoid Half Pixel
rectIncFloat = rectInc % 1; // Getting decimal value.
rectInc = rectInc - rectIncFloat; // Removing decimal.
// console.log(rectInc);
ctx.rect(rectInc, rectInc, 130, 60);
ctx.stroke();
ctx.closePath();
ctx.font = "14px arial";
ctx.fillStyle = '#fff';
ctx.textAlign = 'center';
ctx.fillText("MAIN BUTTON", 65.5 + rectInc, 35.5 + rectInc);
i += iInc;
if (i >= 1) {
iInc = -iInc;
}
if (i <= 0) {
iInc = Math.abs(iInc);
}
raf = window.requestAnimationFrame(draw);
}
// Easing
EasingFunctions = {
// no easing, no acceleration
linear: function(t) {
return t
},
// accelerating from zero velocity
easeInQuad: function(t) {
return t * t
},
// decelerating to zero velocity
easeOutQuad: function(t) {
return t * (2 - t)
},
// acceleration until halfway, then deceleration
easeInOutQuad: function(t) {
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t
},
// accelerating from zero velocity
easeInCubic: function(t) {
return t * t * t
},
// decelerating to zero velocity
easeOutCubic: function(t) {
return (--t) * t * t + 1
},
// acceleration until halfway, then deceleration
easeInOutCubic: function(t) {
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
},
// accelerating from zero velocity
easeInQuart: function(t) {
return t * t * t * t
},
// decelerating to zero velocity
easeOutQuart: function(t) {
return 1 - (--t) * t * t * t
},
// acceleration until halfway, then deceleration
easeInOutQuart: function(t) {
return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t
},
// accelerating from zero velocity
easeInQuint: function(t) {
return t * t * t * t * t
},
// decelerating to zero velocity
easeOutQuint: function(t) {
return 1 + (--t) * t * t * t * t
},
// acceleration until halfway, then deceleration
easeInOutQuint: function(t) {
return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t
}
}
答案 7 :(得分:0)
正如@langpavel在评论中提到的那样,Mozilla网站上有示例代码,说明了如何在画布中更正分辨率: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set display size (css pixels).
var size = 200;
canvas.style.width = size + "px";
canvas.style.height = size + "px";
// Set actual size in memory (scaled to account for extra pixel density).
var scale = window.devicePixelRatio; // Change to 1 on retina screens to see blurry canvas.
canvas.width = size * scale;
canvas.height = size * scale;
// Normalize coordinate system to use css pixels.
ctx.scale(scale, scale);
ctx.fillStyle = "#bada55";
ctx.fillRect(10, 10, 300, 300);
ctx.fillStyle = "#ffffff";
ctx.font = '18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var x = size / 2;
var y = size / 2;
var textString = "I love MDN";
ctx.fillText(textString, x, y);
答案 8 :(得分:0)
为了消除模糊,您需要以两种方式设置画布的大小:
首先是canvas.width = yourwidthhere;
和canvas.height = yourheighthere;
第二,通过js或样式表设置css属性
答案 9 :(得分:0)
HTML:
<canvas class="canvas_hangman"></canvas>
JS:
function setUpCanvas(){
canvas = document.getElementsByClassName("canvas_hangman")[0];
ctx = canvas.getContext('2d');
ctx.translate(0.5, 0.5);
// Set display size (vw/vh).
var sizeWidth = 80 * window.innerWidth / 100,
sizeHeight = 100 * window.innerHeight / 100 || 766;
// console.log(sizeWidth, sizeHeight);
//Setting the canvas site and width to be responsive
canvas.width = sizeWidth;
canvas.height = sizeHeight;
canvas.style.width = sizeWidth;
canvas.style.height = sizeHeight;
}
window.onload = setUpCanvas();
这也以响应方式完美地设置了HTML画布以进行绘制:)
答案 10 :(得分:0)
当图像被缩放时(这是我的问题),这里没人讨论过的其他问题是 imageSmoothingEnabled
。
CanvasRenderingContext2D 接口的 imageSmoothingEnabled
属性,Canvas API 的一部分,确定缩放图像是否平滑(真,默认)或不平滑(假).在获取 imageSmoothingEnabled 属性时,将返回其设置的最后一个值。
此属性对于使用像素艺术的游戏和其他应用非常有用。放大图像时,默认的调整大小算法会模糊像素。将此属性设置为 false 以保留像素的清晰度。
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled
要禁用它,只需将属性设置为 false:
ctx.imageSmoothingEnabled = false;