Fix blurry rendering in some browsers (#4299)
* Closes https://github.com/emilk/egui/issues/4241 I would love some more testers of this. I'm not sure if we really need the round-to-even code, but I'm hesitant to out-right revert https://github.com/emilk/egui/pull/151 when I cannot reproduce its problem. Keeping it seems quite safe though. --- # Testing Checkout the branch and run: * `./scripts/start_server.sh` * `./scripts/build_demo_web.sh` and then open `http://localhost:8888/index.html#Rendering` * `./scripts/build_demo_web.sh --wgpu` and then open `http://localhost:8888/index.html#Rendering` Check the "Rendering test" that the squares in the pixel alignment test are perfectly sharp, like this: <img width="576" alt="Screenshot 2024-04-01 at 13 27 20" src="https://github.com/emilk/egui/assets/1148717/fb6c4824-9e25-4304-bc0c-3c50fbd44a52"> If it looks something like this, something is WRONG: <img width="488" alt="Screenshot 2024-04-01 at 13 29 07" src="https://github.com/emilk/egui/assets/1148717/04bd93ff-2108-40c5-95f6-76e3bcb9cd7f"> Please try it on different zoom levels in different browsers, and if possible on different monitors with different native dpi scaling. Report back the results! ### Mac I have tested on a high-DPI Mac: * Chromium (Brave): ✅ Can reproduce problem on `master`, and it's now fixed * Firefox: ✅ Can reproduce problem on `master`, and it's now fixed * Safari: ❌ Can't get it to work; giving up for now
This commit is contained in:
parent
48ecf01e11
commit
0a40b16bd4
|
|
@ -130,51 +130,46 @@ fn resize_canvas_to_screen_size(
|
|||
) -> Option<()> {
|
||||
let parent = canvas.parent_element()?;
|
||||
|
||||
// Prefer the client width and height so that if the parent
|
||||
// element is resized that the egui canvas resizes appropriately.
|
||||
let width = parent.client_width();
|
||||
let height = parent.client_height();
|
||||
|
||||
let canvas_real_size = Vec2 {
|
||||
x: width as f32,
|
||||
y: height as f32,
|
||||
};
|
||||
|
||||
if width <= 0 || height <= 0 {
|
||||
log::error!("egui canvas parent size is {}x{}. Try adding `html, body {{ height: 100%; width: 100% }}` to your CSS!", width, height);
|
||||
}
|
||||
|
||||
// In this function we use "pixel" to mean physical pixel,
|
||||
// and "point" to mean "logical CSS pixel".
|
||||
let pixels_per_point = native_pixels_per_point();
|
||||
|
||||
let max_size_pixels = pixels_per_point * max_size_points;
|
||||
// Prefer the client width and height so that if the parent
|
||||
// element is resized that the egui canvas resizes appropriately.
|
||||
let parent_size_points = Vec2 {
|
||||
x: parent.client_width() as f32,
|
||||
y: parent.client_height() as f32,
|
||||
};
|
||||
|
||||
let canvas_size_pixels = pixels_per_point * canvas_real_size;
|
||||
let canvas_size_pixels = canvas_size_pixels.min(max_size_pixels);
|
||||
let canvas_size_points = canvas_size_pixels / pixels_per_point;
|
||||
|
||||
// Make sure that the height and width are always even numbers.
|
||||
// otherwise, the page renders blurry on some platforms.
|
||||
// See https://github.com/emilk/egui/issues/103
|
||||
fn round_to_even(v: f32) -> f32 {
|
||||
(v / 2.0).round() * 2.0
|
||||
if parent_size_points.x <= 0.0 || parent_size_points.y <= 0.0 {
|
||||
log::error!("The parent element of the egui canvas is {}x{}. Try adding `html, body {{ height: 100%; width: 100% }}` to your CSS!", parent_size_points.x, parent_size_points.y);
|
||||
}
|
||||
|
||||
// We take great care here to ensure the rendered canvas aligns
|
||||
// perfectly to the physical pixel grid, lest we get blurry text.
|
||||
// At the time of writing, we get pixel perfection on Chromium and Firefox on Mac,
|
||||
// but Desktop Safari will be blurry on most zoom levels.
|
||||
// See https://github.com/emilk/egui/issues/4241 for more.
|
||||
|
||||
let canvas_size_pixels = pixels_per_point * parent_size_points.min(max_size_points);
|
||||
|
||||
// Make sure that the size is always an even number of pixels,
|
||||
// otherwise, the page renders blurry on some platforms.
|
||||
// See https://github.com/emilk/egui/issues/103
|
||||
let canvas_size_pixels = (canvas_size_pixels / 2.0).round() * 2.0;
|
||||
|
||||
let canvas_size_points = canvas_size_pixels / pixels_per_point;
|
||||
|
||||
canvas
|
||||
.style()
|
||||
.set_property(
|
||||
"width",
|
||||
&format!("{}px", round_to_even(canvas_size_points.x)),
|
||||
)
|
||||
.set_property("width", &format!("{}px", canvas_size_points.x))
|
||||
.ok()?;
|
||||
canvas
|
||||
.style()
|
||||
.set_property(
|
||||
"height",
|
||||
&format!("{}px", round_to_even(canvas_size_points.y)),
|
||||
)
|
||||
.set_property("height", &format!("{}px", canvas_size_points.y))
|
||||
.ok()?;
|
||||
canvas.set_width(round_to_even(canvas_size_pixels.x) as u32);
|
||||
canvas.set_height(round_to_even(canvas_size_pixels.y) as u32);
|
||||
canvas.set_width(canvas_size_pixels.x as u32);
|
||||
canvas.set_height(canvas_size_pixels.y as u32);
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,12 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
/* Position canvas in center-top: */
|
||||
/* Position canvas in center-top.
|
||||
This is rather arbitrarily chosen.
|
||||
In particular, it seems like both Chromium and Firefox will still align
|
||||
the canvas on the physical pixel grid, which is required to get
|
||||
pixel-perfect (non-blurry) rendering in egui.
|
||||
See https://github.com/emilk/egui/issues/4241 for more */
|
||||
canvas {
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
|
|
|
|||
Loading…
Reference in New Issue