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..