HTML5 canvas 1 pixel gaps
When building for html5 target you can notice that a 1-pixel-width line may appear on the canvas sides - the actual side depends on the current scale of the browser window. It is visible, for example, in Pirate Pig sample app from openfl-samples haxe lib.
I tried to fix it and could do so by changing the way the width and height is rounded when calculated, basically I replaced Math.round with Math.floor in HTML5Window.hx (https://github.com/openfl/lime/blob/develop/src/lime/_internal/backend/html5/HTML5Window.hx), lines 178,179, 1319, 1320.
I had to modify openfl.display.Stage.hx in a similar way to get rid of these gaps completely though. I changed Std.int to Math.ceil where width and height are calculated in several places and in some matrix transforms that actually may be incorrect 😅 But this eliminated the gap lines on all sides.
why not create a Pull Request ?
why not create a Pull Request ?
Well... Will do. Just hoped someone could comment on this - maybe all these rounds were done like this for a reason :)
Just hoped someone could comment on this
I don't think that there's a perfect way to avoid these gaps completely. Lime's width and height values are of type Int. However, as I understand it, a web browser's view port could be resized a non-integer value (essentially like a Haxe Float). This means that you need to choose: Do you render the content so it is completely visible, but there's a small gap between it and the view port edge, or do you render the content slightly larger than the view port so that there's no gap, but technically, part of your content cannot be seen by the user.
Personally, I feel like no content should be rendered by default in such a way that it can't be seen by the user. The gap, while not ideal, seems more desirable if it means that all content is visible to the user. I believe that the gap can be made more difficult to see by changing the background color of the HTML page to more closely match the content rendered in OpenFL. But if your OpenFL content's background changes frequently, or isn't very uniform (such as a gradient or bitmap image), I understand that there might not be a good workaround for that. With that in mind, I totally understand if someone would prefer cutting off some of the content so that there's never a a gap.
That being said, our use of Math.round() might be considered kind of the worst of both worlds. It potentially means that there's sometimes a gap, and sometimes, the content is hidden outside of the view port bounds. Switching to Math.floor() or Math.ceil() might be better to commit to one or the other all of the time. Or maybe Math.round() has value in that it is most likely to make the gap, or the clipped content, as small as possible.
@joshtynjala, to be honest, I hadn’t noticed these gaps for years, until a partner asked to fix it in a game recently. And then I started to notice it in every game made with OpenFL 😅
I believe that the current situation when there is either no gap or there is a visible one pixel gap is worse when there is no gap or the content is one pixel outside of render area. Because one pixel gap is visible and one pixel crop is not. And if it combines with the pixel ratio issue that I also submitted, it becomes a disaster, because one pixel becomes several pixels….. But it’s rare hehe )
Anyway, I’m pretty sure that one pixel width line sometimes rendered outside of the render area on either (or even every) side, and thus cut, can’t do any harm while one pixel width visible line gap can actually harm the user’s experience because it looks like a visible bug.
Indeed, if you set the background color properly, the gap can be hard to see, but it’s not always possible, like the borders are not always single color.
Made clean pull requests that address the issue. @joshtynjala had reasonable doubts, but I will have to keep these changes in my branches of OpenFL and Lime if the pull request is not accepted anyway (or until it's fixed the other way) because I need it to address the third party requests to the game that is built with OpenFL.
What if you made the background extend 1 pixel farther in all directions, does that cover the gap? Not saying that's the correct solution necessarily, but it would be good to know.
What if you made the background extend 1 pixel farther in all directions, does that cover the gap? Not saying that's the correct solution necessarily, but it would be good to know.
It doesn't help - this gap line is outside the renderer's clip rect. In all of our games the backgrounds are wider than the screen rect to make it look good when the browser window is being resized and when the orientation changes (e.g. when on mobile). For example, the half-transparent background rect is larger than the screen size (like 2x on each side) and still there is a gap, same as the texture on the screen under this pop-up that stretches down.
The gap line are filled with stage.opaqueBackground color, in some cases you can set this color so that the gap is almost invisible, but it's not always possible. It's almost not seen when the game is in fullscreen mode too, but may be noticeable when in iframe.
Sorry, the screenshot above is in fact related to the other issue, but all the rest is still correct - the games have background images that go far outside the screen area and they are not rendered.
Here the gap is barely visible because the stage.opaqueBackground color is black, same as the main page background color, but in the other cases these gaps may stand out more.