Three.js Full Screen Issue
Asked Answered
K

5

29

I've read through the Three.js API, read through the questions here on StackOverflow, I've debugged the code using firebug and chrome's debugger, I've stripped out everything I can, but I am still getting this irritating full screen error, where the renderer view port is larger than my screen thus causing scroll bars to appear. It's a visible error that does not affect rendering, or other operations, I am just trying to control the size of the view port so that it matches available screen real estate without scroll bars appearing.

I am using Google Chrome 18 on Windows 7 and I am just starting to work with the Three.js API, but I have used things like OpenGL in the past so graphics API are not unfamiliar.

When I try and run this code (which is the default example shown on the github main page):

var camera, scene, renderer,
geometry, material, mesh;

init();
animate();

function init() {

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.z = 1000;
    scene.add( camera );

    geometry = new THREE.CubeGeometry( 200, 200, 200 );
    material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );

    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    renderer = new THREE.CanvasRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );

    document.body.appendChild( renderer.domElement );

}

function animate() {

    // note: three.js includes requestAnimationFrame shim
    requestAnimationFrame( animate );
    render();

}

function render() {

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;

    renderer.render( scene, camera );

}

It renders fine, I see the red wire frame box rotating around, but I've noticed that the renderer view port is too big, it is larger than my available screen size, which causes scroll bars to appear. The code uses window.innerWidth and window.innerHeight to set the aspect ratio and the width/height for the renderer, but it seems as if it picks up 20 to 30 extra pixels somewhere and adds them to the bottom and the right of the page?

I've tried adjusting the CSS for the body element to remove margin and padding, same for the canvas element that gets created, but nothing. I've echoed the screen size to the page, and made JavaScript alert() functions to check the window width and height, and then watch as they get passed to the Three.js API during runtime operations, but the error remains: the canvas rendering object is resizing itself to slightly larger than the screen size. The closest I get to correcting the problem is doing something like this:

var val = 7;
//Trims the window size by val
function get_width(){return window.innerWidth - val;}
function get_height(){return window.innerHeight - val;}

//... Code omitted for brevity

camera = new THREE.PerspectiveCamera( 75, get_width() / get_height(), 1, 10000 );

//... Code omitted for brevity 

render.setSize(get_width(), get_height());

It works to bring the renderer size within the boundaries of the window, but only to a point. If I lower val to less than 7, e.g. 6 or less, the renderer size pops back out and is again larger by 20 px (approx), than the screen, causing the scroll bars to appear?

Any thoughts or ideas?

Kandrakandy answered 3/5, 2012 at 4:50 Comment(0)
K
66

Simply set display: block; on canvas element in your CSS

The <canvas> element is according to the mozilla developers network officially a block-level element. Something in between a inline element and a block element. They write:

Browsers typically display the block-level element with a newline both before and after the element.

But rendering of the element can vary across browsers, so to be sure you get the correct behavior it is best to explicitly set display: inline; or display: block; in your CSS.

So just set its display value in your CSS file to block, to solve the issue.

canvas {
    display: block; /* fix necessary to remove space at bottom of canvas */
}
Kerrin answered 26/3, 2013 at 9:30 Comment(3)
This should be the accepted answer - hiding the overflow just masks the problem, but this fixes it. Thanks very much!Ligni
I agree with ultrafez, moreover, by click dragging the mouse on the window, even if the scrollbar is hidden, the content is still scrolling!...Adriene
As I'm still getting hits on this question 4 years later, I've accepted this answer based on the advice of ultrafez, and the community upvotes of this answer, thank you @Kerrin for providing the updated answer!Kandrakandy
P
2

I. Viewport Size Accuracy

I recommend using viewportSize.js by Tyson Matanich, since 'window.innerWidth' and 'window.innerHeight' are not always accurate.

Download : https://github.com/tysonmatanich/viewportSize

Demo : http://tysonmatanich.github.com/viewportSize/

Here's a detailed explanation from the author :

"Most people rely on window.innerWidth, document.documentElement.clientWidth, or $(window).width() which do not always accurately report the viewport width used in CSS media queries. For example, WebKit browsers change the size of their CSS viewport when scroll bars are visible, while most other browsers do not. Since window.innerWidth remains constant regardless of the scroll bar state, it is not a good option for use with Chrome or Safari. Additionally, Internet Explorer 6, 7, and 8 do not support window.innerWidth. On the other hand, document.documentElement.clientWidth changes based on the scroll bar state and therefore is not a good option for Internet Explorer, Firefox, or Opera."

Example :

var viewportWidth  = viewportSize.getWidth(),
    viewportHeight = viewportSize.getHeight(),
    viewportAspect = viewportWidth / viewportHeight;

camera = new THREE.PerspectiveCamera( 75, viewportAspect, 1, 10000 );

II. Elusive Elements

Look out for any elements created programmatically (via 'createElement'). They are easy to miss.

Use Chrome's inspector, or Firebug to see if there are any other elements that you might have missed. Often I see something that I had totally forgotten about, buried deep in last week's code and wonder how the heck I had missed it before.

III. Hard Reset

Lastly, to be thorough, you can try a hard reset. Eric Meyer's classic reset is generally considered to be the most thorough (http://meyerweb.com/eric/tools/css/reset/index.html), but I personally prefer the 'Condensed Meyer Reset' (which surfaced on the web sometime last year, author unknown) :

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, 
pre, form, fieldset, input, textarea, p, blockquote, th, td { 
    padding: 0;
    margin: 0;
    }
fieldset, img { 
    border: 0;
    }
table {
    border-collapse: collapse;
    border-spacing: 0;
    }
ol, ul {
    list-style: none;
    }
address, caption, cite, code, dfn, em, strong, th, var {
    font-weight: normal;
    font-style: normal;
    }
caption, th {
    text-align: left;
    }
h1, h2, h3, h4, h5, h6 {
    font-weight: normal;
    font-size: 100%;
    }
q:before, q:after {
    content: '';
    }
abbr, acronym { 
    border: 0;
    }
Pentateuch answered 24/3, 2013 at 3:14 Comment(0)
S
1

This fixed problem for me. it always going to keep canvas at full screen.

canvas {
    width: 100vw;
    height: 100vh;
    display: block;
  }
Saltation answered 14/12, 2017 at 14:3 Comment(1)
none of the earlier answers worked for me; but this one did. thnx much.Bahadur
H
1

I did it similarly as @paraplu, however I just added !important in my style. Since THREE.js adds inline styles.

canvas {
   display: block;
   width: 100vw !important;
   height: 100vh !important;
}

I am using:

renderer.setSize(window.innerWidth, window.innerHeight);

Also I have found a workaround without CSS:

renderer.setSize(window.innerWidth, window.innerHeight - 1);

That one pixel of height was responsible for triggering both scrollbars in my case, this fixed it, but it does not seem to be a good practice.

And of course even worse practice would be:

body {
   overflow: hidden;
}
Hankow answered 21/3, 2023 at 12:37 Comment(0)
B
0

In css this should also do the trick:

canvas {
    vertical-align: top;
}

Naturally needs also the padding, margin fixes from above

Braca answered 15/2, 2014 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.