UIWebView HTML5 Canvas & Retina Display

When working with HTML5 Canvas on retina displays in UIWebView, images may appear blurry due to pixel density differences. Here's how to properly handle retina displays for crisp canvas rendering.

The Retina Display Problem

Retina displays have higher pixel density (devicePixelRatio > 1), but Canvas elements default to standard resolution, causing blurry images and drawings.

Solution: Scale Canvas for Retina

The key is to scale the canvas context and adjust its internal dimensions to match the device's pixel ratio:

<canvas id="myCanvas" width="300" height="200"></canvas>

<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var width = 300;
var height = 200;

// Get device pixel ratio (1 for standard, 2+ for retina)
var devicePixelRatio = window.devicePixelRatio || 1;

// Scale canvas internal size for retina
canvas.width = width * devicePixelRatio;
canvas.height = height * devicePixelRatio;

// Keep CSS size the same
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';

// Scale the drawing context
context.scale(devicePixelRatio, devicePixelRatio);

// Now draw - this will be crisp on retina displays
context.fillStyle = 'blue';
context.fillRect(10, 10, 100, 50);
context.fillStyle = 'red';
context.font = '16px Arial';
context.fillText('Retina Ready!', 20, 80);
</script>

Drawing Images on Retina Canvas

When drawing images, the scaling is automatically handled by the context scaling:

<canvas id="imageCanvas" width="400" height="300"></canvas>
<img id="sourceImg" src="/images/sample.jpg" style="display:none;">

<script>
var canvas = document.getElementById('imageCanvas');
var context = canvas.getContext('2d');
var img = document.getElementById('sourceImg');
var width = 400;
var height = 300;

var devicePixelRatio = window.devicePixelRatio || 1;

// Setup retina canvas
canvas.width = width * devicePixelRatio;
canvas.height = height * devicePixelRatio;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
context.scale(devicePixelRatio, devicePixelRatio);

// Draw image when loaded
img.onload = function() {
    // Draw at logical coordinates - scaling is handled automatically
    context.drawImage(img, 0, 0, 200, 150);
    context.fillStyle = 'white';
    context.font = '14px Arial';
    context.fillText('Crisp on Retina!', 10, 180);
};
</script>

Complete Retina Helper Function

Here's a reusable function to setup any canvas for retina displays:

function setupRetinaCanvas(canvas, width, height) {
    var context = canvas.getContext('2d');
    var devicePixelRatio = window.devicePixelRatio || 1;
    
    // Set actual size in memory (scaled up for retina)
    canvas.width = width * devicePixelRatio;
    canvas.height = height * devicePixelRatio;
    
    // Scale it back down using CSS
    canvas.style.width = width + 'px';
    canvas.style.height = height + 'px';
    
    // Scale the drawing context so everything draws at correct size
    context.scale(devicePixelRatio, devicePixelRatio);
    
    return context;
}

// Usage
var canvas = document.getElementById('myCanvas');
var ctx = setupRetinaCanvas(canvas, 400, 300);
ctx.fillRect(10, 10, 100, 50); // Draws crisp on all displays

Key Points

  • window.devicePixelRatio returns 1 for standard displays, 2+ for retina
  • Scale canvas internal dimensions by devicePixelRatio
  • Keep CSS dimensions unchanged for proper sizing
  • Scale the context to draw at logical coordinates
  • All subsequent drawing operations will be retina-ready

Conclusion

Proper retina canvas handling requires scaling both the canvas dimensions and drawing context by devicePixelRatio. This ensures crisp rendering across all device types while maintaining logical coordinate drawing.

Updated on: 2026-03-15T23:18:59+05:30

233 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements