preface

In my recent work, I need to use canvas to draw graphics. At the beginning, the effect is very good when I develop the computer, but the page becomes blurred when I put it on the mobile phone 😓. Why is this? 🧐

Problem of repetition

The two circles above are drawn by canvas on the left and CSS on the right. It is obvious that the circles drawn by Canvas are particularly fuzzy

CODE

const canvas = document.getElementById('canvas')
ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.fillStyle = 'darkcyan'
ctx.arc(80.80.80.0.Math.PI * 2)
ctx.stroke()
Copy the code

Cause analysis

First I need to understand a property devicePixelRatio screen pixel ratio

Before the hd display, if the screen was 1000 pixels wide, the physical pixels would be 1000 pixels wide. After the HD display, if the screen was 1000 pixels wide, the physical pixels would be 2000 pixels or more

To make it easier to query the ratio of physical pixels to screen pixels, a property devicePixelRatio is added to the Window object to represent the ratio.

For example, on devices with a devicePixelRatio of 2, when we draw a 1px line using CSS, the physical pixels will actually draw the line using 2px to ensure the size of the drawing, and this conversion is handled automatically by the browser, so it’s not too much of a hassle for developers

So since the above mentioned browser will automatically deal with the pixel ratio problem during rendering, the CSS drawn image will not appear blurred after conversion, but why does it appear on canvas?

Since the width and height values defined on the Canvas tag are not converted, 100px will be rendered as 100px physical pixels, but the device requires 200px, so the browser can only intelligently fill the space between the pixels to fit the required size. This is why canvas images are blurry

The solution

  • Step 1: Get the pixel ratio
  • Step 2: Set the width and height property on the Canvas tag to display size x pixel ratio
  • Step 3: Set canvas style width and height to display size
  • Step 4: UsescaleMethod Set ratio
  • Step 5: Draw canvas graphics
function createHDCanvas (canvas, w, h) {
  const ratio = window.devicePixelRatio || 1;
  canvas.width = w * ratio; // Actual render pixels
  canvas.height = h * ratio; // Actual render pixels
  canvas.style.width = `${w}px`; // Control the display size
  canvas.style.height = `${h}px`; // Control the display size
  const ctx = canvas.getContext('2d')
  ctx.scale(ratio, ratio)
  / / drawing canvas
  return canvas;
}
Copy the code

The final result

This is what the above example does as per the solution