Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

352
Views
¿Cómo reducir correctamente el muestreo de HTML Canvas para obtener imágenes atractivas?

Introducción

Estoy tratando de lidiar con imágenes borrosas en mi animación de lienzo. La borrosidad es especialmente frecuente en dispositivos móviles, retina y pantallas de alto dpi (puntos por pulgada).

Estoy buscando una manera de garantizar que los píxeles que se dibujan con el lienzo se vean lo mejor posible en pantallas de dpi baja y pantallas de dpi alta. Como solución a este problema, redacté varios artículos sobre la reducción de escala del lienzo y seguí este tutorial:

https://www.kirupa.com/canvas/canvas_high_dpi_retina.htm

Integración de la reducción de escala en el proyecto

El proyecto en el que quiero implementar la reducción de escala se puede encontrar a continuación y consta de algunas características importantes:

  • Hay un lienzo principal (grande). (Optimización del rendimiento)
  • Hay varios lienzos más pequeños (prerenderizados) que se utilizan para dibujar y cargar una imagen. (Optimización del rendimiento)
  • El lienzo está animado. (En el fragmento de código, no hay animación visible, pero la función de animación está integrada).

Pregunta

Lo que estoy tratando de lograr: el problema al que me enfrento parece bastante simple. Cuando el sitio web (con el lienzo) se abre en un dispositivo móvil (por ejemplo, un Iphone, con más píxeles por pulgada que una computadora de escritorio normal). Las imágenes aparecen más borrosas. Lo que realmente estoy tratando de lograr es eliminar este desenfoque de las imágenes. Redacté esto y decía que la borrosidad se puede eliminar mediante la reducción de resolución. Traté de incorporar esta técnica en el código proporcionado, pero no funcionó por completo. Las imágenes se hicieron más grandes y no pude escalar las imágenes al tamaño original. fragmento no está implementado correctamente, la salida sigue siendo borrosa. ¿Qué hice mal y cómo puedo solucionar este problema?

Explicación del fragmento de código

La variable devicePixelRatio se establece en 2 para simular una pantalla de teléfono de alto dpi, las pantallas de bajo dpi tienen un devicePixelRatio de 1. Múltiples lienzos prerenderizados generados son la función de spawn es el fragmento hay 5 lienzos diferentes, pero en el entorno de producción hay de 10

Si falta alguna información o preguntas sobre esta publicación, hágamelo saber. ¡Muchas gracias!

Fragmento de código

 var canvas = document.querySelector('canvas'); var c = canvas.getContext('2d' ); var circles = []; //Simulate Retina screen = 2, Normal screen = 1 let devicePixelRatio = 2 function mainCanvasPixelRatio() { // get current size of the canvas let rect = canvas.getBoundingClientRect(); // increase the actual size of our canvas canvas.width = rect.width * devicePixelRatio; canvas.height = rect.height * devicePixelRatio; // ensure all drawing operations are scaled c.scale(devicePixelRatio, devicePixelRatio); // scale everything down using CSS canvas.style.width = rect.width + 'px'; canvas.style.height = rect.height + 'px'; } // Initial Spawn function spawn() { for (let i = 0; i < 2; i++) { //Set Radius let radius = parseInt(i*30); //Give position let x = Math.round((canvas.width/devicePixelRatio) / 2); let y = Math.round((canvas.height /devicePixelRatio) / 2); //Begin Prerender canvas let PreRenderCanvas = document.createElement('canvas'); const tmp = PreRenderCanvas.getContext("2d"); //Set PreRenderCanvas width and height let PreRenderCanvasWidth = ((radius*2)*1.5)+1; let PreRenderCanvasHeight = ((radius*2)*1.5)+1; //Increase the actual size of PreRenderCanvas PreRenderCanvas.width = PreRenderCanvasWidth * devicePixelRatio; PreRenderCanvas.height = PreRenderCanvasHeight * devicePixelRatio; //Scale PreRenderCanvas down using CSS PreRenderCanvas.style.width = PreRenderCanvasWidth + 'px'; PreRenderCanvas.style.height = PreRenderCanvasHeight + 'px'; //Ensure PreRenderCanvas drawing operations are scaled tmp.scale(devicePixelRatio, devicePixelRatio); //Init image const image= new Image(); //Get center of PreRenderCanvas let m_canvasCenterX = (PreRenderCanvas.width/devicePixelRatio) * .5; let m_canvasCenterY = (PreRenderCanvas.height/devicePixelRatio) * .5; //Draw red circle on PreRenderCanvas tmp.strokeStyle = "red"; tmp.beginPath(); tmp.arc((m_canvasCenterX), (m_canvasCenterY), ((PreRenderCanvas.width/devicePixelRatio)/3) , 0, 2 * Math.PI); tmp.lineWidth = 2; tmp.stroke(); tmp.restore(); tmp.closePath() //Set Image image .src= "https://play-lh.googleusercontent.com/IeNJWoKYx1waOhfWF6TiuSiWBLfqLb18lmZYXSgsH1fvb8v1IYiZr5aYWe0Gxu-pVZX3" //Get padding let paddingX = (PreRenderCanvas.width/devicePixelRatio)/5; let paddingY = (PreRenderCanvas.height/devicePixelRatio)/5; //Load image image.onload = function () { tmp.beginPath() tmp.drawImage(image, paddingX,paddingY, (PreRenderCanvas.width/devicePixelRatio)-(paddingX*2),(PreRenderCanvas.height/devicePixelRatio)-(paddingY*2)); tmp.closePath() } let circle = new Circle(x, y, c ,PreRenderCanvas); circles.push(circle) } } // Circle parameters function Circle(x, y, c ,m_canvas) { this.x = x; this.y = y; this.c = c; this.m_canvas = m_canvas; } //Draw circle on canvas Circle.prototype = { //Draw circle on canvas draw: function () { this.c.drawImage( this.m_canvas, (this.x - (this.m_canvas.width)/2), (this.y - this.m_canvas.height/2)); } }; // Animate function animate() { //Clear canvas each time c.clearRect(0, 0, (canvas.width /devicePixelRatio), (canvas.height /devicePixelRatio)); //Draw in reverse for info overlap circles.slice().reverse().forEach(function( circle ) { circle.draw(); }); requestAnimationFrame(animate); } mainCanvasPixelRatio() spawn() animate()
 #mainCanvas { background:blue; }
 <canvas id="mainCanvas"></canvas> <br>

over 4 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!