-
-
Notifications
You must be signed in to change notification settings - Fork 646
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
support for screen autoresize #4
Comments
This would be a great feature! |
I'm working on this! :D |
i'm thinking i could rewrite the
just tell me what you think... |
@andyveliz I set this ticket to milestone 0.9.5 as part of my wish list for the next version. A few suggestions: AutoZoom should also scale the pixel size by the same ratio that it fills the browser, of course, maintaining the same aspect ratio like you said. AutoResize = true, AutoZoom = true: The canvas should first be AutoZoomed, like above, and then the canvas resized to fill any empty space in the browser. Here are some images to help visualize. The white space in the browser is NOT part of the canvas. The black space in the browser IS part of the canvas (rendering the melonJS background color, if any). AutoResize = false, AutoZoom = false: AutoResize = true, AutoZoom = false: |
Great... thanks for the images... that really clarified a lot... i'll try to submit some code for you to see in the next few weeks... |
Parasyte's images look good and might negate the following suggestion... It would be great to be able to specify which dimensions are resized.
Example: http://www.freeimagehosting.net/6a8aj Does anyone have a fork with resizing implemented? |
This feature should have a max-width option so that you can be sure the game is never resized larger than it was designed to be. Otherwise the graphics will start to look bad on larger screens when the resolution is greater than the graphics were made at. For example, for my game, when it is viewed on a screen with a width larger than 1024px the game is going to be centered and have a box-shadow and there will be additional content on the page, e.g., about info, comments, footer, etc. Using media queries I will remove that extra content when the browser width is 1024px or below so that the game can truly expand to fit the screen when viewed on tablets and phones. It would also be nice to have a feature to force the game to appear in either portrait or landscape mode when viewed on tablets or phones. One tower defense game I play, Tower Madness is always in portrait mode, and another one, Fieldrunners, is always in landscape mode. Designing a game to look right in both modes, including maps and menus, would be very difficult on smaller screens. There are orientation media queries. You can rotate content with CSS3. |
Hey thanks for all the good ideas! currently i'm working on this issue, i have just a few non-working test ... :( but i'll commit some code to my fork of melonjs as soon as i can... i'm only working on resizing on the fly the canvas, with the option to maintain the aspect ratio, basically the images that Jason share with us... i think that this could solve the "resizing when changing orientation" issue... i'll be looking to add the other great features you guys wrote about. |
Hi guys, i've commited some code to my fork, in the canvas-resize branch, it's a hack making the autoresize and autozoom functions work, check them out... any feedback is appreciated, I hope this can be useful to the main repository. |
@greghouston A max[Height|Width] feature is fine. But there are also some other implications to consider when zooming a canvas to larger or smaller than it was designed for. When zooming the canvas smaller than its native size, you actually _lose quality_ just as much as when the canvas is enlarged. The quality loss is not as obvious when the image is scaled with interpolation, but it comes at a performance cost. In this case, it is more effective to use two (or more) copies of every image in the game, and choose the closest fit when displaying. This is a technique used in 3D rendering for many years, called MipMapping; when a texture is scaled toward 0.5 times its original size, a smaller version of the texture will be used, increasing performance and visual quality. Likewise on the other end of the spectrum, when enlarging the canvas, you may not want the image scaled with interpolation enabled, to give the game a distinct "pixelated" look. This can be done with CSS using the image-rendering property on the canvas. That affects the entire canvas, but if you also want it to affect sprites that are scaled or rotated within the canvas, you also need to use So maybe that's a third boolean to pass, whether you want image smoothing enabled (default) or disabled? @andyveliz I looked through the commit in your canvas-resize branch. The most important thing it has to offer is the math, which I haven't studied yet. It looks pretty good at first glance. And some of the new methods are also very helpful. The one piece of criticism I have is how your hack reuses variables, and also uses the One idea I want to bring up is the possibility of allowing the canvas to properly reflow with other elements in the HTML document, instead of forcing it to the size of the browser viewport. Imagine the body margins have not been set to 0 (the default is always something larger than 0) then you will stretch the browser viewport by making the canvas the same width/height without taking into account the body margin. Imagine if the canvas also had its own margin... Or if the canvas is inside a div element that sits next to a side-navigation menu. Now we hit all kind of complex situations where the canvas cannot be made the same size as the browser viewport. The ideal solution, I think, is calculating the size of the canvas's parent element content box, and performing one of three operations when autosize OR autozoom are set, where
Some special care must be taken when I know I haven't covered every edge case, but just adding some more details to take into consideration. |
@parasyte I was thinking about the "max-width" option that @greghouston suggested, it could be a problem if you have a big widescreen, in some games you don't want the player to have the advantage of seeing more map. How do you guys feel about a |
I think in the case you don't want to show too much of the map, you just want AutoResize = false? |
I think it may be better to consider this as an exception, so normal players can have a better gaming experience in all the different screen sizes, but at the same time being prepared for bigger screens and more clever players. I'll write some code, and try to keep it simple. |
If both AutoResize and AutoZoom are true the game is going to appear very similar from one screen to another varying only as much as the aspect ratio does, e.g., aspect ratio on iPhone is 1.5:1, the iPad is 1.333:1. My monitor is 1.6:1. What would be nice though is a maintain aspect ratio option so that it acts like embedded flash does. If you set the width of a flash object to 100%, it will scale to fit the width of the parent container and the height of the flash object will have the correct aspect ratio. This is really important in responsive web designs. To mimic Flash: |
Please provide some images that show how a game will render with this third boolean. You'll now have 2**3 = 8 different modes of resize, instead of just four. Keep in mind that |
Here is a perfect example. Resize the result container. |
I just see a broken image. Failed to load resource: the server responded with a status of 403 (Forbidden) http://www.gamesuncovered.com/uploads/2009/01/10/fieldrunners1-122933.png But regardless, it looks like what you want is AutoResize = false, AutoZoom = true |
Find any image on the web and put its URL in there. MaintainAspectRatio would make it so that AutoResize resized to full width and then the height was generated via the original aspect ratio ... just like when an image in HTML is set to width: 100%, height: auto. In the case of images the aspect ratio is built in. In our case the aspect ratio is defined by the original viewport size. I guess you could make MaintainAspectRatio always fit in the screen in which case sometimes it would use 100% height and sometimes 100% width or that could be an option. |
Quote: Not exactly. An image always resizes to full width. In the AutoResize = false, AutoZoom = true example above it has resized to full height. |
Actually, in the use case I am thinking, AutoResize = false, AutoZoom = true: may actually work so you may be right. I was thinking of how it would display in a column on a webpage. Since those columns don't have heights defined it would have to use the width. |
This is how |
as I was also highthing it here :
|
I agree 100%. Scaling without maintaining aspect ratio will really do some strange things. The backbuffer (when double buffering is enabled) will also need some special handling for this case. |
If I may a couple of other remarks :
@andyveliz, by the way, that's a great work you did here, thank you for working on this :) |
Great ideas! well... the autoresize was indeed tricky, but the mouse coordinates are working as far as I tested, correctly. I think the About the @parasyte The backbuffer was really tricky, but with my hack it works :D |
…ch for further integration/implementation Also added some TODO I had in mind, while copy/pasting everything :)
@andyveliz Hi ! I can see that you actually resize the viewport, I guess that you made this for a good reason, but I don't understand why ? :) The feature here being basically to scale (maintaining or nor aspect ratio) automatically the display to fit with the browser window size, why do we need this? In my point of view, the offscreen canvas and the corresponding viewport should never changed, as only the displayed canvas is scaled/resized. thanks for the feedback ! |
* enforce double buffering if scaling is used * autozoom is now enable through the scale parameter (if equal to 'auto') * viewport size is unchanged when zooming/resizing * enabled autozoom/autoresize on the dirtyRect example Todo : * more cleaning * fix mouse/touch input when scaling/resizing
…o` for better consistency also refactored some code, and rename auto_zoom to auto_scale internally, to avoid any confusion with what thisi is used for
Hey Guys! sorry for not being around for a bit. I was getting married, so i was a little busy... hehehe @obiot I've also tried changing the size of the backbuffer but that only led to zooming of the map... i guess maybe you found a better way to do the resizing :) and I think you're right about changing the name of the variable, it's more descriptive. i'll test out this new fixes... |
nooo way, you got married ? me too this weekend !!!!!! |
hahaha! congrats to you too!! |
@obiot I haven't had a chance to look at this, sadly. Have been super busy since last week, but things are starting to clear up in my schedule. (Also @andyveliz my best friend's sister got married last Friday, and I was part of their wedding! Congratulations to you!) I'm ok with renaming the variable to "maintainAspectRatio", since it is a little bit more "obvious". Good to see you also took the time to reverse the logic on it when renamed. ;) I also kind of prefer Greg's suggestion of passing an optional settings object. I'll get to some code review on this either today or tomorrow sometime. :) I encourage others to help us all with code reviews, too. They are incredibly useful! |
oh so you actually know each other, what a small world ! |
Guys, I really would like to merge this into the main branch, as it's starting to be difficult to manage as a separate branch, as the main one includes some bug fixes that are also required here (like with the floating object stuff). And I believe this could be a nice first milestone. what do you think ? we can then let this one open, or close and create a new ticket for the missing stuff (basically it's the viewport resize) |
Let me know what you do. If you close this one I'll make another ticket for zoom and another one for resize on orientation change. |
I will merge it a bit later in the main branch, will close this one and create 2 new tickets. Please have a look after, If I can ask, to ensure I did not miss anything :) |
Hi Olivier I performed some tests with the Screen Auto Resize (for auto resize the canvas, with "auto" scale) and with the hints below (for resize the game DIV): http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/ And has worked like a charm! Thanks! |
@ciangames thank you for the feedback ! |
for the orientation change, what I can do is to create a specific channel you can listen to, like how i did for the resize event or even also trigger the resize event on orientation change (so that you just to listen to the resize), but however I don't really see the benefit of the something like this should work : if Math.abs(window.orientation) === 90 then 'portrait' ! |
an even better example using the last commit :
|
bonus question to all : does anyone has an idea on how to remove/fix this "flickering" effect when the window is resizing (as a reminder, when a canvas is resized; it's content is cleared) ? I tried to defer the function call, but it does not change anything.... |
Regarding orientation, that makes sense. No need for a ticket for that one. That just leaves zoom. |
@obiot: Repainting on resize event like that will cause some performance decrease while resizing. (I know, it's not very common, but maybe it's noticeable on older hardware.) If that's a concern, you could instead do a "smart" defer, that waits some short period (like 35ms -- perfect for 30fps) and resets itself if the "smart defer" is run again before the 35ms lapse. Then the user resizes by quickly dragging the window handle; the canvas resize will take effect only after the resize handle slows down. Function.prototype.timeout = function (time /*, args */) {
var fn = this, args = Array.prototype.slice.call(arguments, 1);
if (this.delayId) {
window.clearTimeout(this.delayId);
}
this.delayId = window.setTimeout(function() {
return fn.apply(fn, args);
}, time || 0);
return this.delayId;
}; Use it: me.video.updateDisplaySize.timeout(35, scale, scale); |
@parasyte : yes, I thought about it as well, but is it really a concern ? I tried it on all my machines yesterday and did not notice any lag or issue, so..... and after all it's just re-sizing, people should not spend time resizing the window continuously ? let's keep anyway this piece of code here, in case of major complains on the feature. |
@parasyte : found this blog entry (http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) while googling our suggestion, this could be actually applied to a lots of things in melonJS (mousemove as a start, as in the bottom of the blog entry example) |
@parasyte : else i think that if I could just store the timer id returned by the defer fuction, and clear it before deferring again the next resize function call, it should be enough (for a window resizing). Keep in mind that deferred function are only executed when the stack is empty, which is once every frame. |
Well, it's not the clearTimeout that will fix the problem with performance, but the actual time passed to setTimeout. I agree it will prevent multiple defers from executing per frame. But for performance you want the delay to be longer than a single frame. |
I'm ok to spend more time on this, but do you really believe it's that critical ? |
So I did that for now (easy & cheap solution). I will give it more attention tonight once back at home, and will try this with my old mbp and several browsers (to see If there is a perfromance issue we should worry about) |
@obiot: Nope, not at all critical! Just an observation. ;) |
Update gallery.html
Implement graphics auto-resize in melonJS, and use the browser resize event, to create (full)screen size independent games.
The text was updated successfully, but these errors were encountered: