Подтвердить что ты не робот

Черновые рисунки, похожие на линии, размыты

У меня есть <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>&nbsp;</div></td></tr>
</table>
4b9b3361

Ответ 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);