3

I'm working on an HTML5 browser game that can be divided into 3 parts: two UI panels on the left and right of a center set of square canvases for the playing surface. The three panels need to be horizontally aligned, and the total game needs to keep an aspect ratio of 16:9. The left and right panels should be of equal widths, and all three panels must be of equal height. I have specified a minimum width and height inside a resize() function called when an onresize event is detected.

Currently, each panel is a div, and all three are contained inside a section. Right now, the section isn't necessary, but I want to keep the game separated from extra content at the bottom of the screen that I might choose to add later.

The CSS style is as follows:

* {
    vertical-align: baseline;
    font-weight: inherit;
    font-family: inherit;
    font-style: inherit;
    font-size: 100%;
    border: 0 none;
    outline: 0;
    padding: 0;
    margin: 0;
}

#gameSection {
    white-space: nowrap;
    overflow-x: hide;
    overflow-y: hide;
}


#leftPanel, #centerPanel, #rightPanel {
    display: inline-block;
}

#leftPanel {
    background-color: #6495ed;
}

#centerPanel {
    background-color: #e0ffff;
}

#rightPanel {
    background-color: #b0c4de;

Right now, I have set the background color of each div just to show me when I'm correctly setting the size of each div.

The body of my HTML document is as follows:

<body onresize="resize()">
    <section id="gameSection">
        <div id="leftPanel">Left Panel.</div>
        <div id="centerPanel">Center Panel.</div>
        <div id="rightPanel">Right Panel.</div>
    </section>
</body>

And finally, my resize() function (I created a separate function for resizing the game in case I add more elements below later):

    function resize() {
        var MIN_GAME_WIDTH = 800;
        var MIN_GAME_HEIGHT = 450;
        var GAME_ASPECT_RATIO = 16 / 9;

        var width = window.innerWidth;
        var height = window.innerHeight;

        var gWidth, gHeight;

        if(width < MIN_GAME_WIDTH || height < MIN_GAME_HEIGHT) {
            gWidth = MIN_GAME_WIDTH;
            gHeight = MIN_GAME_HEIGHT;
        }
        else if ((width / height) > GAME_ASPECT_RATIO) {
            <!-- width is too large for height -->
            gHeight = height;
            gWidth = height * GAME_ASPECT_RATIO;
        }
        else {
            <!-- height is too large for width -->
            gWidth = width;
            gHeight = width / GAME_ASPECT_RATIO;
        }

        resizeGame(gWidth, gHeight, GAME_ASPECT_RATIO);
    }

    function resizeGame(var gWidth, var gHeight, var aspectRatio) {
        var gSection = document.getElementById("gameSection");
        var lPanel = document.getElementById("leftPanel");
        var cPanel = document.getElementById("centerPanel");
        var rPanel = document.getElementById("rightPanel");

        gSection.height = gHeight;
        gSection.width = gWidth;

        <!-- should the below be taken care of in the CSS? -->
        lPanel.height = gHeight;
        cPanel.height = gHeight;
        rPanel.height = gHeight;

        cPanel.width = cPanel.height;
        lPanel.width = (gWidth - cPanel.width) / 2;
        rPanel.width = lPanel.width;
    }

I've tried a number of different commands to resize the divs, but it just isn't working for me. When I try adding test canvases, color appears, but the boxes still aren't the correct size. I have also considered loading an invisible background image to each div and scaling it to the desired size; however, I was able to resize my canvas using the above method before and it seemed to work just fine.

Additional Notes
While I've already had pretty good success resizing a single canvas, I don't want to use just one canvas for the game because not all parts of the UI need to be drawn at the same time.

I'm trying to keep this solely in Javascript.

I suspect that I could just use CSS to handle resizing by fixing the aspect ratio to 16:9 and using width:56.25% for the center panel and width:21.875% for the side panels, but that limits me to one aspect ratio and doesn't explain why my above script isn't working.

I can provide the entire HTML file if needed. This is what it's supposed to look like: End Goal (without right panel)

Thank you!

UDPATE:
jsfiddle

tstevens
  • 63
  • 8
  • Can you provide a codepen.io or a jsfiddle? – James G. Apr 28 '15 at 19:13
  • added the jsfiddle. which I saved, but I'm not sure if it will disappear if I close the browser. This is my first time using it. – tstevens Apr 28 '15 at 19:18
  • 2
    what browser support do you need? this is pretty easy to do with just css using flex box – Brian Glaz Apr 28 '15 at 19:21
  • @tstevens: if you saved, it will not disappear. Fiddle is incredibly useful to anyone trying to help you, highly recommended to always include it in your question. – bardzusny Apr 28 '15 at 19:21
  • 1
    @tstevens, [Read the wiki page](http://stackoverflow.com/tags/javascript/info) to learn how to debug JS. You have several syntax errors in your jsfiddle, for starters – James G. Apr 28 '15 at 19:25
  • IMHO if you're building a web-based game you shouldn't have to say you support something pre-IE11. Flexbox is the way to go: http://caniuse.com/#feat=flexbox. See also: http://stackoverflow.com/questions/29852531/css-bootstrap-how-to-dynamically-stretch-subdiv-width-to-fit-container-with/29853031#29853031 – redbmk Apr 28 '15 at 19:34
  • @BrianGlaz this is going to be an internal tool, so I can require whatever I want :) – tstevens Apr 28 '15 at 19:40

1 Answers1

1

I got it kind of working here. I made a lot of changes/minor fixes to the code before finding what was wrong (other than various syntax errors):

You were using .width and .height instead of .style.width and .style.height, and you were applying integers to these instead of strings with "px" appended to them. Both of these things are completely understandable to miss.

I also moved the onresize from the body tag into the JS, don't know why it wasn't working on jsfiddle, but this is good practice anyways.

In the future: learn how to debug JS using the console and when you ask questions, use small examples, not your entire codebase. This question could have been simplified to "How do I resize a div?" with one line of JS and one div. You also should consider not doing this specific thing in JS, and using flexbox as redbmk said.

Sinister Beard
  • 3,570
  • 12
  • 59
  • 95
James G.
  • 2,852
  • 3
  • 28
  • 52
  • Is there a specific reason for settings the class name of gSection? – tstevens Apr 28 '15 at 21:27
  • @tstevens, nope. I meant to take that out, it was just for testing purposes. – James G. Apr 28 '15 at 21:43
  • Ok, thank you. Why did you include the resize() function call after defining the method? I'm trying to copy over your changes into my HTML file to no avail. – tstevens Apr 28 '15 at 21:49
  • I included that so that it would call on page load. It is probably not working right off on local as the JS is running before the DOM is loaded. – James G. Apr 28 '15 at 21:51
  • Yeah, I've heard of that being an issue -- that's why I attached it to the onresize in the body, but apparently that's not working either... – tstevens Apr 28 '15 at 21:52
  • Have you added `window.onresize = resize;` to the bottom of your JS file? – James G. Apr 28 '15 at 22:00
  • This is probably not good, but all of my CSS, JS, and HTML is in one file. I have the `window.onresize = resize` at the end of a ` – tstevens Apr 28 '15 at 22:02
  • Can you try putting the ` – James G. Apr 28 '15 at 22:03
  • No change. I moved the entire script over to the body, and still nothing. I also validated my HTML and CSS just to be sure, with no errors. Do you mind taking a look at my source file? – tstevens Apr 28 '15 at 22:06
  • Yeah sure, upload it somewhere. gist.github.com works – James G. Apr 28 '15 at 22:08
  • Amateur question, but can I check those through Chrome's Devtools? – tstevens Apr 28 '15 at 22:14
  • [Read the wiki page](http://stackoverflow.com/tags/javascript/info) to learn how to debug JS. – James G. Apr 28 '15 at 22:15