How to make HTML5 canvas a suitable dynamic parent / flex box container

Is there a way to create a canvas inside a dynamic container with flexible containers?

A CSS-only solution is preferred, but I think JavaScript is needed for redrawing?

I think one solution would be to listen to the recalibration event and then scale the canvas to fit the size of the parent of the flexible window and then force the redraw, but I would prefer to use as much CSS as possible or a cleaner / smaller code solution.

The current approach is based on CSS, where the canvas is modified to fit the element of the parent flex element. The graphics are blurry, redone, and crowded from the canvas in the image below.

Stretched image / Graphics overflowing canvas

CSS

html,body{ margin:0; width:100%; height:100%; } body{ display:flex; flex-direction:column; } header{ width:100%; height:40px; background-color:red; } main{ display:flex; flex: 1 1 auto; border: 1px solid blue; width:80vw; } canvas{ flex: 1 1 auto; background-color:black; } 

HTML:

 <header> </header> <main> <canvas id="stage"></canvas> </main> 

JavaScript:

 $( document ).ready(function() { var ctx = $("#stage")[0].getContext("2d"); ctx.strokeStyle="#FFFFFF"; ctx.beginPath(); ctx.arc(100,100,50,0,2*Math.PI); ctx.stroke(); }); 

JS script showing the problem: https://jsfiddle.net/h2v1w0a1/

+6
source share
1 answer

Think of the canvas as an image. If you scale it to a different size than the original, it will appear blurry at some point and possibly at an early stage depending on the interpolation algorithm chosen by the browser. For canvas, the browser tends to choose bilinear over the bi-cube, so there is a higher risk of blurring than with the actual image.

You want things in the canvas to be displayed as accurately as possible, and the only way to do this is to adapt the size to the parent using JavaScript and avoid CSS (the latter is good for things like printing or when you need "retina permissions").

To get the size of the parent container in pixels, you can use getComputedStyle() (see update below):

 var parent = canvas.parentNode, styles = getComputedStyle(parent), w = parseInt(styles.getPropertyValue("width"), 10), h = parseInt(styles.getPropertyValue("height"), 10); canvas.width = w; canvas.height = h; 

Fiddle

(Note: Chrome seems to have some problems with calculated flex at the moment)

Update

Here's a simpler way:

 var rect = canvas.parentNode.getBoundingClientRect(); canvas.width = rect.width; canvas.height = rect.height; 

Fiddle

+10
source

Source: https://habr.com/ru/post/987175/


All Articles