Canvas drawings, lines, are blurry

56 views Asked by At

I'm currently working on creating a drawing animation in which I connect various elements using lines drawn on an HTML canvas. However, I've encountered an issue where the lines I draw appear to be excessively blurry. I'm seeking assistance in resolving this problem.

Example in codepen: https://codepen.io/kilian-m/pen/QWzXmEr

const canvas = document.getElementById('line-canvas');
const ctx = canvas.getContext('2d');
const list = document.querySelector('.ressource-search__parent-terms');
const items = Array.from(list.querySelectorAll('.ressource-search__parent-term'));

canvas.width = list.offsetWidth;
canvas.height = list.offsetHeight;

const animationDuration = 500;

function getCanvasCoordinates(element) {
  const rect = element.getBoundingClientRect();
  const canvasRect = canvas.getBoundingClientRect();
  return {
    x: rect.left + rect.width / 2 - canvasRect.left,
    y: rect.top + rect.height / 2 - canvasRect.top
  };
}

let itemCoordinates = items.map(getCanvasCoordinates);

function drawLine(x1, y1, x2, y2, progress) {
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x1 + (x2 - x1) * progress, y1 + (y2 - y1) * progress);
  ctx.lineWidth = 1;
  ctx.strokeStyle = "#707070";
  ctx.stroke();
}

function animateLine(index, startTime) {

  const x1 = itemCoordinates[index].x;
  const y1 = itemCoordinates[index].y;
  const x2 = itemCoordinates[index + 1].x;
  const y2 = itemCoordinates[index + 1].y;

  return function(timestamp) {
    const elapsed = timestamp - startTime;
    const progress = Math.min(1, elapsed / animationDuration);

    drawLine(x1, y1, x2, y2, progress);

    if (progress < 1) {
      requestAnimationFrame(animateLine(index, startTime));
    } else {
      if (index + 2 < items.length) {
        animateLine(index + 1, performance.now())(performance.now());
      }
    }
  };
}

function startAnimation() {
  if (items.length > 1) {
    animateLine(0, performance.now())(performance.now());
  }
}

window.addEventListener('resize', () => {
  itemCoordinates = items.map(getCanvasCoordinates);
  startAnimation();
});

setTimeout(() => {
  startAnimation();
}, 50);
<div class="ressource-search">
  <canvas id="line-canvas" style="position: absolute; top: 0; left: 0;"></canvas>
  <ul class="ressource-search__parent-terms">
    <li class="ressource-search__parent-term">test</li>
    <li class="ressource-search__parent-term">test</li>
    <li class="ressource-search__parent-term">test</li>

  </ul>
</div>

I tried a lot of things:

  • add 0.5 to my stroke value
  • ctx.scale(dpi, dpi);
  • not set css size to canvas and more..
0

There are 0 answers