¿Puede alguien explicar por qué el lienzo no obedece a la elección de color y cómo solucionarlo para que dibuje colores "verdaderos"? Sé que el lienzo usa coordenadas de 0,5 píxeles, así que intenté dibujar con incrementos de 0,5, pero aún dibuja con colores funky (usando ColorCop para acercar y verificar los colores por píxel:
Aquí hay un pequeño fragmento que se supone que dibuja líneas azules, 2 líneas una al lado de la otra y la tercera línea a 1 píxel de distancia, el resultado es que solo la primera línea tiene azul verdadero, todo lo demás es púrpura o peor, incluido el primer/último píxel de la primera línea:
const canvas = document.getElementById("line"), ctx = canvas.getContext("2d"); canvas.width = canvas.height = 100; ctx.strokeStyle = 'blue'; ctx.lineCap = "square"; ctx.imageSmoothingEnabled = false; ctx.moveTo(10.5, 40.5); ctx.lineTo(80.5, 40.5); ctx.moveTo(10.5, 41.5); ctx.lineTo(80.5, 41.5); ctx.moveTo(10.5, 43.5); ctx.lineTo(80.5, 43.5); ctx.stroke(); <canvas id="line"></canvas>La resolución de mi monitor es 2560x1440 con una escala del 100%. No se utiliza ningún sistema/navegador/software ni ningún tipo de zoom/escala. Si dibujo un píxel en MS Paint, veo un píxel en el monitor sin suavizado, sin artefactos.
establezca el ancho y la altura del lienzo en (ancho y altura deseados) * devicePixelRatio * 2
reasignarlo usando la propiedad de estilo css al ancho y alto que desee
escala contexto 2, 2
De forma predeterminada, una unidad en el lienzo es exactamente un píxel. Una transformación de escala modifica este comportamiento. Por ejemplo, un factor de escala de 0,5 da como resultado un tamaño de unidad de 0,5 píxeles; las formas se dibujan así a la mitad del tamaño normal. De manera similar, un factor de escala de 2,0 aumenta el tamaño de la unidad de modo que una unidad se convierte en dos píxeles; por lo tanto, las formas se dibujan al doble del tamaño normal.
const width = height = 100 const pixelRatio = window.devicePixelRatio * 2; const canvas = document.getElementById('line'); canvas.width = width * pixelRatio; canvas.height = height * pixelRatio; canvas.style.width = `${width}px`; canvas.style.height = `${height}px`; const ctx = canvas.getContext("2d"); ctx.scale(pixelRatio, pixelRatio); ctx.strokeStyle = 'blue'; ctx.lineCap = "square"; ctx.moveTo(10.5, 40.5); ctx.lineTo(80.5, 40.5); ctx.moveTo(10.5, 41.5); ctx.lineTo(80.5, 41.5); ctx.moveTo(10.5, 43.5); ctx.lineTo(80.5, 43.5); ctx.stroke(); <canvas id="line"></canvas>Probablemente estés en un monitor de alta resolución. CSS escalará su lienzo y creará suavizado.
Para superar esto, puede multiplicar el tamaño de su lienzo por la proporción de píxeles de su monitor y luego reducirlo al tamaño esperado usando CSS:
const canvas = document.getElementById("line"), ctx = canvas.getContext("2d"), dPR = window.devicePixelRatio; // multiply by dPR canvas.width = canvas.height = 100 * dPR; // downscale through CSS canvas.style.width = canvas.style.height = "100px"; ctx.scale(dPR, dPR); ctx.strokeStyle = 'blue'; ctx.lineCap = "square"; ctx.imageSmoothingEnabled = false; ctx.moveTo(10.5, 40.5); ctx.lineTo(80.5, 40.5); ctx.moveTo(10.5, 41.5); ctx.lineTo(80.5, 41.5); ctx.moveTo(10.5, 43.5); ctx.lineTo(80.5, 43.5); ctx.stroke(); <canvas id="line"></canvas>