Skip to content

fix: ensure canvas resolution scales with the parent containers to avoid blurry fonts #585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 19, 2022

Conversation

Xananax
Copy link
Contributor

@Xananax Xananax commented Jul 12, 2022

This is related to #381

Hypothesis

Because Godot uses rendered fonts, they do not resize as sharply as vector fonts. This is especially apparent if the viewport is not a multiple of the original resolution (1920x1080).

Fix

The current PR makes sure the viewport resizes to multiples of 240px. That is, 240, 480, 720, 960, etc. The hope is that pixel division on even numbers will yield sharper results.

This seems to work well enough for me, but it requires more testing.

In parallel, I asked itch to give me access to CSS editing there, so the same setup can be reproduced on the itch page.

Importantly: we cannot ensure sharpness if people have custom zoom values set up. A zoom of 72% will always look bad, no matter what. A scale of 125% will similarly result in a pixel division of 0.625, which will create aliasing on the edges.

If we wanted to go around that, we'd need:

  1. to pass the current window size to Godot through the javascript API
  2. have Godot use a different font size dependent on passed the window size
  3. have Godot lock the size in increments of 240 too (set the mode to not stretch, and handle viewport changes ourselves)

This is also what we would need to do if we want to handle blurriness on Desktops.

It's possible, but I don't know if it is worth it at the moment. Godot 4 has automatic font scaling, so the problem could potentially be less visible once we port.


Other changes

This PR also fixes a few warnings for typescript and adds some documentation to the build script for local web dev debugging. Nothing very important.

@NathanLovato NathanLovato linked an issue Jul 13, 2022 that may be closed by this pull request
@NathanLovato
Copy link
Contributor

This doesn't help, but testing in the browser, I see the issue: the resolution of the element changes with the app. The problem is that when the resolution goes down, the canvas just lacks resolution, and it's normal that the text becomes blurry.

I can get crisp text by forcing the canvas to stick to a resolution of 1080p and giving it the styles height:100% and width:100%, so it doesn't overflow from its parent frame.

image

And so, I think it's just a matter of changing the canvas-container so it doesn't lower the resolution of the child canvas too much.

I noticed this code in the JS

    const onResize = () => {
      const { width, height, ratio } = snappedAspectRation();
      canvas.width = width;
      canvas.height = height;
      console.log({ width, height, ratio });
      canvasContainer.style.setProperty(`width`, `${width}px`);
      canvasContainer.style.setProperty(`height`, `${height}px`);
      document.documentElement.style.setProperty("--scale", `${ratio}`);
    };

It seems like the cause to me.

@NathanLovato
Copy link
Contributor

NathanLovato commented Jul 17, 2022

Current (canvas-container makes the canvas render at 960x540):

image

With a fixed canvas resolution of 1080p

image

@Xananax
Copy link
Contributor Author

Xananax commented Jul 19, 2022

It used to be set at 100%, the javascript code that resizes the canvas was made specifically to answer another bug... I'll try digging to remember

@Xananax
Copy link
Contributor Author

Xananax commented Jul 19, 2022

It was that commit: ca3d17f

It fixes bug #253 (the commit also fixes #315 incidentally, but that's not important for our purposes)

So it seems we have the following options:

  • 100% width and height, but interactive areas don't align with the graphics on Firefox.

or

  • width and height set in JS, but then the canvas lacks enough pixels to display fonts properly on zoomed-in devices.

Another option is to

  • let Godot handle width and height, as it does in the default template, but we didn't want that because... Of some yet another bug. I'll go hunting.

@NathanLovato
Copy link
Contributor

Ah that was why!

@Xananax
Copy link
Contributor Author

Xananax commented Jul 19, 2022

The reason why we aren't letting Godot handle the size are:

All three were fixed in #278

To summarize the reasons for that PR:

  1. our fullscreen button in Godot could not know if the browser was set to full screen through F11, so the fullscreen icon could indicate the wrong state. So we decided to handle this in JS instead
  2. we cannot call the JS to fullscreen from Godot, for sandboxing reasons. So we overlay a button in JS over the Godot frame
  3. To overlay the button correctly, we need to input specific measurements, because some browsers (looking at you, firefox) don't allow us to query back the canvas size
  4. Therefore, we decided to set the canvas at specific sizes, so the button could always be aligned (ca3d17f)

In summary, our options:

  1. Use Godot fullscreen:
  • +: less code, interactive overlays should work in all circumstances
  • -: cannot obtain browser state to change button style; cannot know if user use browser fullscreen
  1. Use JS fullscreen + specific canvas sizes
  • +: button can be overlayed precisely, fullscreen state is tracked
  • -: font become blurry if the pixel aspect is not 1:1
  1. Use JS fullscreen + CSS 100% + query canvas size on size change
  • +: fullscreen state is tracked, fonts are not blurry
  • -: on firefox, querying is imprecise, button will not be placed correctly

I will try to set specific percentages in JS, a mix of 2 and 3, and see what happens.

Another option would be to overlay the fullscreen button at the bottom or top right, regardless of canvas size.

Xananax added 2 commits July 19, 2022 14:08
this commit also fixes the overlay on large screens
(it was constricted in the middle)
@Xananax
Copy link
Contributor Author

Xananax commented Jul 19, 2022

I allowed the canvas container (a simple div) to resize to specific sizes, but made the canvas fill the entire available space with width: 100%; height: 100%.

It's difficult for me to test (my screen is small and 1080p), but I think it's fixed? Functionally, everything works still (interactive areas, fullscreen button alignment, and functionality) on both Firefox and Chromium.

@NathanLovato
Copy link
Contributor

Just tested in firefox and brave, looking great!

@NathanLovato NathanLovato changed the title WIP: Blurry fonts fix: ensure canvas resolution scales with the parent containers to avoid blurry fonts Jul 19, 2022
@NathanLovato NathanLovato merged commit e50cbf2 into main Jul 19, 2022
@NathanLovato NathanLovato deleted the html-generation-fixes branch July 19, 2022 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Text is blurry in HTML5 exports
2 participants