Drawing a canvas over HTML and saving aspect when resizing a screen

Background

This is a rather complicated problem that I struggled with for several days. I am trying to display the lessons in a slide show format. So, the lesson consists of different slides. Now overlaying on each slide is a canvas element that matches the size of the screen.

canvas.width = document.body.clientWidth; canvas.height = document.body.clientHeight; 

This allows the teacher to draw notes and highlight parts of the lesson on the canvas.

Problem

The content of the slide is made up of HTML, it looks like when the slide is loading.

When resizing a page ...

enter image description here

So the problem is that the canvas image changes according to the aspect ratio of the page with CSS.

 #theCanvas { position:fixed; top:0; right:0; bottom:0; left:0; } 

But the actual HTML remains the same size, but re-arranges the output points of the line. Bad.

What i tried

First, I make all my HTML elements according to the width and height of the window using CSS:

 h1 { font-family: 'Open Sans Condensed', sans-serif; color: #222222; font-weight: 200; font-size: 5.9vw; } h2 { font-family: 'Open Sans Condensed', sans-serif; color: #222222; font-weight: 200; font-size: 3.0vh; } h4 { font-family: 'Open Sans Condensed', sans-serif; color: #444444; font-weight: 200; font-size: 2vmin; } p { font-family: 'Open Sans Condensed'; font-size: 2vmin; font-weight: 200; } 

Next, I save and resize the canvas image using:

 window.onresize = function(event) { var data = canvas.toDataURL(); // resize the canvas canvas.width = document.body.clientWidth; canvas.height = document.body.clientHeight; //alert($(container).width()); // scale and redraw the canvas content var img=new Image(); img.width = document.body.clientWidth; img.height = document.body.clientHeight; img.onload=function(){ context.drawImage(img,0,0,img.width,img.height); } img.src=data; }; 

Full screen result (1920 pixels wide)

enter image description here

When the window button is resized (1200 pixels)

enter image description here

This is pretty close.

Problem

Now, when I drag the corner of the window to resize, this happens:

enter image description here

Question

1 - Why does the window.onresize function not start when I manually resize the corner of the window?

(bonus question) Am I going to do it right, or will it be more trouble than putting canvas on HTML elements for interactive lessons?

+6
source share
2 answers

I think I misunderstood your problem.

If you want the drawn elements to match the html elements, you need to make sure that the HTML elements never change layout and always keep the same relative sizes. In your example, this is NOT the case. You have “🕑25m” in the upper left corner and a “Greeting” in the middle, and when you drag the page above, these two elements are separated by a value not proportional to the other sizes of the elements, so you are already asking for what is almost impossible.

Perhaps you can use SVG for all text, so it can be scaled to arbitrary sizes, where plain HTML text cannot. In other words, if you make the page very tall and thin with SVG, you will get tall and thin text, and all positions and sizes will be proportional to their original positions and size, where, as in the case of HTML, the text does not stretch, you set the size to various vh settings, but this means that the browser will choose the size, and not scale the text proportionally.

Example: Original Desired Display

enter image description here

Change the window to tall and thin ( font-size: 10vh; )

enter image description here

Please note that the font does not stretch, so the relative sizes and the distance between the “25 m” and the “greeting” no longer correspond

Do the same with SVG with preserveAspectRatio="none"

enter image description here

Please note that both “25 m” and “Welcome” are also tall and thin. This means that if you draw a square around both on your canvas, both windows will still match after scaling. Without this, something would not fit.

Here is the HTML version above

 body { margin: 0; } .center { position: absolute; left: 0; top: 0; width: 100vw; height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 20vh; } 
 <div id="time">25m</div> <div class="center"> <div>Welcome</div> </div> 

And the SVG version

 body { margin: 0; } #foo { width: 100vw; height: 100vh; display: block; } 
 <svg id="foo" width="100%" height="100%" viewBox="0 0 640 480" version="1.1" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"> <text x="187px" y="240px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:64px;">W<tspan x="246px 282px " y="240px 240.084px ">el</tspan>come</text> <text x="19px" y="35px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:16px;">25m</text> </svg> 
+7
source

You can make your canvas responsive without any resizing. When you need to draw something on the canvas, you need to convert the point from the window coordinate to the canvas coordinates.

 #theCanvas { max-width: 100%; height: auto; } 

or

 #theCanvas { max-height: 100%; width: auto; } 

==================================================== ===========================

  var actualCanvasSize = canvas.getBoundingClientRect(); var initialCanvasSize = {width:canvas.width, height:canvas.height}; 

What do you think about this?

But if you want to do this with resizing events. There is one library for sizing HTML elements. This lib uses some css3 tips and tricks. And it works fine, and it is more useful and can solve your window resizing problem. But you need to put your canvas in a div, and then attach the resize listener to the div. github.com/sdecima/javascript-detect-element-resize

+1
source

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


All Articles