2

Requirement: So I am using a html5 canvas to perform drawings on an iPad(2732 * 2048) and store the pixels drawn so I can reuse them.

Now I need to show the same drawing on a website as a downscaled version (615 * 460) by redrawing it per pixel.

Implementation

I am using fabric.js for all rendering of canvases.

To downscale :

  1. multiple the height and width of the canvas by the resize ratio so the drawing is scaled to the original size.
  2. Force the height and width of the container to be fixed as the dimensions I need for the drawing to be shown.
  3. Fill the container to 100% of its dimensions using CSS.

Issues On rendering in Chrome the drawing is aliased but it renders properly in Safari on Non retina displays.

Have tested with pure canvas also and it's the same behavior.

On Chrome

Drawing on Chrome 85

on Safari

Drawing on Safari 14

Pseudo Code: (Showing only the required settings and styles to avoid complication)

// resizeRatio = 4.45 (2732 / 615);

   canvas = new fabric.Canvas('someId');
   canvas.enableRetinaScaling = false;
   canvas.freeDrawingBrush.color = '#000000';
   
   canvas.setWidth(460 * resizeRatio);
   canvas.setHeight(615 * resizeRatio);
   
   container = document.getElementbyId('container');

   container.style.width = (this.width) + 'px';
   container.style.height = (this.height) + 'px';
   
   brush = new fabric.PencilBrush(canvas);

   brush.width = 2.5;

  // Loop over each of the coordinates using mouse events on the brush to render the 
  // canvas.

HTML

<div id=container style=" width: 100% !important;height: 100% !important;">
   <canvas style=" width: 100% !important; height: 100% !important;" id="canvas"></canvas>. 
</div>

Thank you

abhijitsinha89
  • 58
  • 1
  • 10

1 Answers1

0

You do not need to resize the canvas.width & canvas.height as these are different from canvas.style.height & canvas.style.width. To keep the crispiness you should not decrease resolution of a canvas.

Example use-case is that i use 4k display, and i can use window.devicePixelRatio to know that device to pixel ratio is then 2. Then i repaint what i want to paint on a canvas, where i multiply the size with this ratio. canvas.width += canvas.width * deviceToPixelRatio, which makes for crisp images and also zoom-in-friendly.

Gabriel Petersson
  • 8,434
  • 4
  • 32
  • 41