Проблем с Three.js на цял екран

Прочетох Three.js API, прочетох въпросите тук в StackOverflow, отстраних грешки в кода с помощта на firebug и програмата за отстраняване на грешки на chrome, премахнах всичко, което мога, но все още получавам тази дразнеща грешка на цял екран , където портът за преглед на рендера е по-голям от моя екран, което води до появата на ленти за превъртане. Това е видима грешка, която не засяга изобразяването или други операции, просто се опитвам да контролирам размера на порта за изглед, така че да съответства на наличната недвижима площ на екрана, без да се появяват ленти за превъртане.

Използвам Google Chrome 18 на Windows 7 и тъкмо започвам да работя с Three.js API, но в миналото съм използвал неща като OpenGL, така че графичният API не е непознат.

Когато се опитам да стартирам този код (който е примерът по подразбиране, показан на главната страница на 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 );

}

Рендира добре, виждам червената телена рамка да се върти, но забелязах, че портът за изглед на рендера е твърде голям, по-голям е от моя наличен размер на екрана, което причинява появата на ленти за превъртане. Кодът използва window.innerWidth и window.innerHeight, за да настрои съотношението на страните и ширината/височината за рендера, но изглежда, че извлича 20 до 30 допълнителни пиксела някъде и ги добавя в долната и дясната част на страницата?

Опитах да коригирам CSS за елемента body, за да премахна полето и подложката, същото за елемента canvas, който се създава, но нищо. Повторих размера на екрана на страницата и направих функции на JavaScript alert() за проверка на ширината и височината на прозореца и след това наблюдавах как те се предават на 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());

Работи, за да приведе размера на рендера в границите на прозореца, но само до точка. Ако намаля val до по-малко от 7, напр. 6 или по-малко, размерът на рендера изскача обратно и отново е по-голям с 20 px (приблизително) от екрана, което води до появата на лентите за превъртане?

Някакви мисли или идеи?


person hypervisor666    schedule 03.05.2012    source източник


Отговори (4)


Просто задайте display: block; върху елемент canvas във вашия CSS

Елементът <canvas> е според мрежата на разработчиците на mozilla официално елемент на ниво блок. Нещо средно между вграден елемент и блоков елемент. Те пишат:

Браузърите обикновено показват елемента на ниво блок с нов ред преди и след елемента.

Но изобразяването на елемента може да варира в различните браузъри, така че за да сте сигурни, че получавате правилното поведение, най-добре е изрично да зададете display: inline; или display: block; във вашия CSS.

Така че просто задайте стойността му за показване във вашия CSS файл да блокира, за да разрешите проблема.

canvas {
    display: block; /* fix necessary to remove space at bottom of canvas */
}
person Wilt    schedule 26.03.2013
comment
Това трябва да е приетият отговор - скриването на препълването само маскира проблема, но това го коригира. Много благодаря! - person ultrafez; 21.07.2014
comment
Съгласен съм с ultrafez, освен това, чрез плъзгане на мишката върху прозореца, дори ако лентата за превъртане е скрита, съдържанието все още се превърта!... - person Charles HETIER; 25.09.2014
comment
Тъй като все още получавам ударения по този въпрос 4 години по-късно, приех този отговор въз основа на съвета на ultrafez и общността гласува за този отговор, благодаря ти @Wilt за предоставянето на актуализирания отговор! - person hypervisor666; 26.07.2016

I. Точност на размера на Viewport

Препоръчвам да използвате viewportSize.js от Tyson Matanich, тъй като 'window.innerWidth' и 'window.innerHeight' не винаги са точни.

Изтегляне: https://github.com/tysonmatanich/viewportSize

Демонстрация: http://tysonmatanich.github.com/viewportSize/

Ето подробно обяснение от автора:

„Повечето хора разчитат на window.innerWidth, document.documentElement.clientWidth или $(window).width(), които не винаги отчитат точно ширината на прозореца за изглед, използвана в CSS медийни заявки. Например браузърите на WebKit променят размера на своя CSS viewport, когато лентите за превъртане са видими, докато повечето други браузъри не го правят. Тъй като window.innerWidth остава постоянен независимо от състоянието на лентата за превъртане, това не е добра опция за използване с Chrome или Safari. Освен това Internet Explorer 6, 7 и 8 не поддържат window.innerWidth. От друга страна, document.documentElement.clientWidth се променя въз основа на състоянието на лентата за превъртане и следователно не е добра опция за Internet Explorer, Firefox или Opera."

Пример:

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

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

II. Неуловими елементи

Внимавайте за елементи, създадени програмно (чрез „createElement“). Лесно се пропускат.

Използвайте инспектора на Chrome или Firebug, за да видите дали има други елементи, които може да сте пропуснали. Често виждам нещо, което напълно бях забравил, заровено дълбоко в кода от миналата седмица и се чудя как, по дяволите, съм го пропуснал преди.

III. Твърдо нулиране

И накрая, за да бъдете задълбочени, можете да опитате хардуерно нулиране. Класическото нулиране на Ерик Майер обикновено се счита за най-задълбочено (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;
    }
person David Scott Kirby    schedule 24.03.2013

В css това също трябва да свърши работа:

canvas {
    vertical-align: top;
}

Естествено се нуждае и от подложка, корекции на полето отгоре

person ovirta    schedule 15.02.2014

Този коригиран проблем за мен. винаги ще поддържа платното на цял екран.

canvas {
    width: 100vw;
    height: 100vh;
    display: block;
  }
person paraplu    schedule 14.12.2017