javascript Three.js 全屏问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10425310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 09:50:13  来源:igfitidea点击:

Three.js Full Screen Issue

javascripthtmlfullscreenhtml5-canvasthree.js

提问by hypervisor666

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.

我已经阅读了 Three.js API,阅读了 StackOverflow 上的问题,我已经使用 firebug 和 chrome 的调试器调试了代码,我已经尽可能地去除了一切,但我仍然遇到这个令人恼火的全屏错误,其中渲染器视口比我的屏幕大,从而导致出现滚动条。这是一个不影响渲染或其他操作的可见错误,我只是想控制视口的大小,使其与可用的屏幕空间相匹配,而不会出现滚动条。

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.

我在 Windows 7 上使用 Google Chrome 18,我刚刚开始使用 Three.js API,但我过去使用过像 OpenGL 这样的东西,所以图形 API 并不陌生。

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

当我尝试运行此代码时(这是 github 主页上显示的默认示例):

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.innerWidthand window.innerHeightto 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?

它渲染得很好,我看到红色线框框在旋转,但我注意到渲染器视口太大,它大于我的可用屏幕尺寸,这会导致出现滚动条。代码使用window.innerWidthwindow.innerHeight来设置渲染器的纵横比和宽度/高度,但它似乎在某处拾取了 20 到 30 个额外的像素并将它们添加到页面的底部和右侧?

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:

我已经尝试调整 body 元素的 CSS 以删除边距和填充,对于创建的画布元素也是如此,但没有。我已经将屏幕大小回显到页面,并制作 JavaScriptalert()函数来检查窗口的宽度和高度,然后观察它们在运行时操作期间传递给 Three.js API 的过程,但错误仍然存​​在:画布渲染对象是将自身调整为略大于屏幕尺寸。我最接近纠正问题的是做这样的事情:

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 valto 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?

它可以将渲染器大小置于窗口边界内,但仅限于一个点。如果我降低val到小于 7,例如 6 或更小,渲染器大小会弹出并再次比屏幕大 20 像素(大约),从而导致出现滚动条?

Any thoughts or ideas?

有什么想法或想法吗?

回答by Wilt

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

只需设置显示:块;在你的 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:

<canvas>元素是根据 mozilla 开发者网络官方定义的块级元素。内联元素和块元素之间的东西。他们写:

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.

但是元素的呈现会因浏览器而异,因此为了确保获得正确的行为,最好在 CSS 中显式设置display: inline;display: block;

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

因此,只需将其在 CSS 文件中的显示值设置为阻止即可解决问题。

canvas {
    display: block; /* fix necessary to remove space at bottom of canvas */
}

回答by Juan Mellado

Remove CSS body margins and hide overflow:

删除 CSS 正文边距并隐藏溢出:

body{
  margin: 0px;
  overflow: hidden;
}

回答by David Scott Kirby

I. Viewport Size Accuracy

一、视口尺寸精度

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

我建议使用viewportSize.js泰森Matanich,因为“window.innerWidth”和“window.innerHeight”并不总是准确的。

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

下载:https: //github.com/tysonmatanich/viewportSize

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

演示: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."

“大多数人依赖 window.innerWidth、document.documentElement.clientWidth 或 $(window).width(),它们并不总是准确地报告 CSS 媒体查询中使用的视口宽度。例如,WebKit 浏览器会更改其 CSS 的大小滚动条可见时的视口,而大多数其他浏览器不可见。由于 window.innerWidth 无论滚动条状态如何都保持不变,因此它不是与 Chrome 或 Safari 一起使用的好选择。此外,Internet Explorer 6、7 和 8不支持 window.innerWidth。另一方面,document.documentElement.clientWidth 根据滚动条状态发生变化,因此对于 Internet Explorer、Firefox 或 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.

注意以编程方式创建的任何元素(通过“createElement”)。他们很容易错过。

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.

使用 Chrome 的检查器或 Firebug 查看是否有您可能遗漏的任何其他元素。我经常看到一些我完全忘记的东西,深深地埋在上周的代码中,想知道我以前怎么会错过它。

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) :

最后,为了彻底,您可以尝试硬重置。Eric Meyer 的经典重置通常被认为是最彻底的(http://meyerweb.com/eric/tools/css/reset/index.html),但我个人更喜欢“Condensed Meyer Reset”(在网络上浮出水面)去年某个时候,作者不详):

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;
    }

回答by ovirta

In css this should also do the trick:

在 css 中,这也应该可以解决问题:

canvas {
    vertical-align: top;
}

Naturally needs also the padding, margin fixes from above

自然也需要填充,从上面修复边距

回答by paraplu

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

这对我来说是固定的问题。它总是将画布保持在全屏状态。

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