Html 画布绘图,如线条,是模糊的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8696631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Canvas drawings, like lines, are blurry
提问by revgum
I have a <div style="border:1px solid border;" />
and canvas, which is drawn using:
我有一个<div style="border:1px solid border;" />
画布,它是使用以下方法绘制的:
context.lineWidth = 1;
context.strokeStyle = "gray";
The drawing looks quite blurry (lineWidth less than one creates even worse picture), and nothing near to the div's border. Is it possible to get the same quality of drawing as HTML using canvas?
绘图看起来很模糊(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>
回答by Ben Pretorius
I found that setting the canvas size in CSS caused my images to be displayed in a blurry manner.
我发现在 CSS 中设置画布大小会导致我的图像以模糊的方式显示。
Try this:
尝试这个:
<canvas id="preview" width="640" height="260"></canvas>
as per my post: HTML Blurry Canvas Images
根据我的帖子:HTML Blurry Canvas Images
回答by Matt Greer
When drawing lines in canvas, you actually need to straddle the pixels. It was a bizarre choice in the API in my opinion, but easy to work with:
在画布中绘制线条时,您实际上需要跨越像素。在我看来,这是 API 中的一个奇怪的选择,但很容易使用:
instead of this:
而不是这个:
context.moveTo(10, 0);
context.lineTo(10, 30);
do this:
做这个:
context.moveTo(10.5, 0);
context.lineTo(10.5, 30);
dive into HTML5's canvas chapter talks about this nicely
(look for the 'ASK PROFESSOR MARKUP' box about 1/4th of the way down)
潜入 HTML5 的画布章节很好地讨论了这一点
(寻找大约 1/4 处的“ASK PROFESSOR MARKUP”框)
回答by revgum
Even easier fix is to just use this:
更简单的解决方法是使用这个:
context = canvas.context2d;
context.translate(0.5, 0.5);
From here on out your coordinates should be adjusted by that 0.5 pixel.
从这里开始,您的坐标应调整为 0.5 像素。
回答by LittleJoe
I use a retina display and I found a solution that worked for me here.
我使用视网膜显示器,我在这里找到了一个对我有用的解决方案。
Small recap :
小回顾:
First you need to set the size of your canvas twice as large as you want it, for example :
首先,您需要将画布的大小设置为您想要的两倍大,例如:
canvas = document.getElementById('myCanvas');
canvas.width = 200;
canvas.height = 200;
Then using CSS you set it to the desired size :
然后使用 CSS 将其设置为所需的大小:
canvas.style.width = "100px";
canvas.style.height = "100px";
And finally you scale the drawing context by 2 :
最后将绘图上下文缩放 2 :
canvas.getContext('2d').scale(2,2);
回答by R0bur
Lines are blurred because the canvas virtual sizeis zoomed toits HTML element actual size. To overcome this issue you need to adjust canvas virtual size before drawing:
线条模糊是因为画布虚拟大小被缩放到其 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 ()
<!DOCTYPE html>
<html>
<head>
<title>Canvas size adjusting demo</title>
</head>
<body>
<canvas id="surface"></canvas>
</body>
</html>
HTML:
HTML:
回答by Nic Scozzaro
As @langpavel mentioned in a comment, the Mozilla website has example code for how to correct resolution in a canvas: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
正如@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);
回答by Normajean
This is the best solution I've found in 2020. Notice I've multiplied the devicePixelRatio by 2:
这是我在 2020 年找到的最佳解决方案。请注意,我已将 devicePixelRatio 乘以 2:
var size = 100;
var scale = window.devicePixelRatio*2;
context.width = size * scale;
context.height = size * scale;
context.scale(scale, scale);
回答by Imran Bughio
To avoid this issue in animationI would like to share a small demo.
为了避免动画中的这个问题,我想分享一个小演示。
Basically I am checking increment values each time & jumping in a set of 1px by removing float values.
基本上,我每次都检查增量值并通过删除浮点值来跳入一组 1px。
HTML:
HTML:
<canvas id="canvas" width="600" height="600"></canvas>
CSS:
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:
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
}
}
回答by Dennis Anonymus Minecrafter
in order to get rid of the blurryness you need to set the size of the canvas in two manners:
first withcanvas.width = yourwidthhere;
and canvas.height = yourheighthere;
second by setting the css attribute either by js or a stylesheet
为了摆脱模糊,您需要以两种方式设置画布的大小:第一种方式canvas.width = yourwidthhere;
,canvas.height = yourheighthere;
第二种方式是通过 js 或样式表设置 css 属性
回答by Adam O Ceallaigh
HTML:
HTML:
<canvas class="canvas_hangman"></canvas>
JS:
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();
This perfectly sets up your HTML canvas to draw on, in a responsive manner too:)
这也可以以响应方式完美地设置您的 HTML 画布以进行绘制:)