Черновые рисунки, похожие на линии, размыты
У меня есть <div style="border:1px solid border;" />
и холст, который рисуется с помощью:
context.lineWidth = 1;
context.strokeStyle = "gray";
Рисунок выглядит довольно размытым (lineWidth меньше, чем один создает еще худшее изображение), и ничего рядом с границей 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>
Ответы
Ответ 1
При рисовании линий в холсте вам действительно нужно оседлать пиксели. На мой взгляд, это был странный выбор в API, но с ним легко работать:
вместо этого:
context.moveTo(10, 0);
context.lineTo(10, 30);
сделайте следующее:
context.moveTo(10.5, 0);
context.lineTo(10.5, 30);
погрузиться в главу HTML5 холст говорит об этом красиво
(найдите поле "ASK PROFESSOR MARKUP" примерно на 1/4 пути вниз)
Ответ 2
Еще проще исправить это:
context = canvas.context2d;
context.translate(0.5, 0.5);
Здесь вы можете настроить координаты на 0.5 пикселя.
Ответ 3
Я обнаружил, что установка размера холста в CSS привела к тому, что мои изображения отображались размытым образом.
Попробуйте следующее:
<canvas id="preview" width="640" height="260"></canvas>
в моем сообщении: Размытые изображения холста HTML
Ответ 4
Чтобы избежать этой проблемы в анимации, я хотел бы поделиться небольшим demo.
В основном я проверяю значения инкремента каждый раз и прыгаю в наборе 1px, удаляя значения float.
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
}
}
Ответ 5
Я использую экран сетчатки, и я нашел решение, которое сработало для меня здесь.
Небольшое резюме:
Сначала вам нужно установить размер вашего холста вдвое больше, чем вы хотите, например:
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);