2017-01-10 110 views
0

基本上我試圖將ThreeJS畫布(藍色背景與黃色文字)對齊,以便它適合緊貼在透明的綠色圖像中。到目前爲止,這對我來說效果很好,但是我注意到,當我調整瀏覽器窗口或縮放大小時,畫布的位置略微偏斜。例如,調小窗口大小會在左上方顯示畫布周圍的間隙。瀏覽器窗口調整大小時,導致ThreeJS畫布傾斜定位的原因是什麼?

理想情況下,我只想讓藍色畫布始終顯示在與窗口大小相同的相對位置。

Codepen示範問題:http://codepen.io/joeycato/pen/pRjmYP

<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <style type="text/css"> 
     .app { 
     background-color: orange 
     } 
     body { 
     color: green; 
     overflow: hidden; 
     background-color: black 
     } 
     .backgroundImage { 
      position: absolute; 
      top: 0%; 
      left: 0%; 
      width: 100%; 
      height: auto; 
      max-width: 100%; 
     } 
    </style> 
    <script src="three-r83.min.js"></script> 
    <script src="jquery-3.1.1.min.js"></script> 
    <script src="app.js"></script> 
</head> 
<body> 
    <img id="imgBackground" src="background.png" class="backgroundImage"/> 
    <div class="app" /> 
</body> 
</html> 

的Javascript:

let game, 
    BACKGROUND_IMAGE_WIDTH = 1280, 
    BACKGROUND_IMAGE_HEIGHT = 736, 
    BACKGROUND_IMAGE_ASPECT_RATIO = BACKGROUND_IMAGE_HEIGHT/BACKGROUND_IMAGE_WIDTH, 
    ctx, 
    camera, scene, renderer, geom, materialTube, textureTube, mesh, 
    canvasMain; 

function mainLoop() { 
    ctx.clearRect(0, 0, 256, 256); 
    ctx.fillStyle = 'blue'; 
    ctx.fillRect(0, 0, 256, 256); 

    ctx.font = '12pt Arial'; 
    ctx.fillStyle = 'yellow'; 
    ctx.fillText('GREEN STENCIL OVERLAYING', 0, 100); 
    ctx.fillText('BLUE THREEJS CANVAS', 20, 120); 
    ctx.fillText('RESIZING WINDOW SMALLER', 10, 180); 
    ctx.fillText('REVEALS GAPS ON SIDE', 10, 200); 

    textureTube.needsUpdate = true; 
    renderer.render(scene, camera); 

    requestAnimationFrame(mainLoop); 
} 

function initScene() { 
    var demoWidth = window.innerWidth; 
    var demoHeight = window.innerHeight; 

    // Forcing height to match aspect ratio of original iamge (1280x736) 
    demoHeight = BACKGROUND_IMAGE_ASPECT_RATIO * demoWidth; 

    if (camera) { 
    scene.remove(camera); 
    } 

    camera = new THREE.PerspectiveCamera(55, demoWidth/demoHeight, 1, 1000); 

    camera.position.x = -110; 
    camera.position.y = 30; 
    camera.position.z = 457; 

    scene.add(camera); 

    geom = new THREE.PlaneGeometry(170, 210); 
    geom.verticesNeedUpdate = true; 

    if (mesh) { 
    scene.remove(mesh); 
    } 

    mesh = new THREE.Mesh(geom, materialTube); 
    mesh.rotation.x = 0.13999999999999999; 
    mesh.rotation.y = -0.4900000999999998; 
    mesh.rotation.z = -0.04999899999999999; 

    scene.add(mesh); 

    renderer.setSize(demoWidth, demoHeight); 
} 

function makeCanvas(id, w, h) { 
    let elem = document.createElement('canvas'); 
    elem.id = id; 
    elem.width = w; 
    elem.height = h; 
    return elem; 
} 

(function($) { 
    $(function() { 
    canvasMain = makeCanvas('canvasMain', 256, 256); 
    ctx = canvasMain.getContext('2d'); 

    renderer = new THREE.WebGLRenderer(); 
    document.body.appendChild(renderer.domElement); 

    scene = new THREE.Scene(); 

    textureTube = new THREE.Texture(canvasMain); 
    materialTube = new THREE.MeshBasicMaterial({ 
     map: textureTube 
    }); 

    initScene(); 
    requestAnimationFrame(mainLoop); 
    }); 
})(jQuery); 

window.addEventListener('resize', function() { 
    initScene(); 
}); 

// requestAnimationFrame 
(function() { 
    var lastTime = 0; 
    var vendors = ['ms', 'moz', 'webkit', 'o']; 
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 
    window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; 
    window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || 
     window[vendors[x] + 'CancelRequestAnimationFrame']; 
    } 
    if (!window.requestAnimationFrame) 
    window.requestAnimationFrame = function(callback, element) { 
     var currTime = new Date().getTime(); 
     var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 
     var id = window.setTimeout(function() { 
      callback(currTime + timeToCall); 
     }, 
     timeToCall); 
     lastTime = currTime + timeToCall; 
     return id; 
    }; 

    if (!window.cancelAnimationFrame) 
    window.cancelAnimationFrame = function(id) { 
     clearTimeout(id); 
    }; 

}()); 
+0

我只能看到綠色。你爲什麼在兩個不同的地方調用'requestAnimationFrame(mainLoop);'?你爲什麼從調整大小的回調調用'initScene()'?看看[THIS小提琴](https://jsfiddle.net/2pha/ne7gjdnq/) – 2pha

+0

謝謝你,你是正確的,我沒有技術上需要兩個requestAnimationFrame()調用,我可以簡單地調用mainLoop()直。我同意,在這裏調用initScene()有點矯枉過正(之前的代碼基於一系列可調攝像頭,我可以將其更多地清理掉)。我現在更新codepen。 – joeycato

+0

我更新了CodePen,但仍然看到問題。我應該提到我在1920x1200顯示器上的Chrome中看到了這一點,並將窗口大小調整到了1280以下。現在,我通過在兩個手動調整位置之間提供攝像頭設置,設法找到了一種解決方法。 – joeycato

回答

0

貌似歪斜是人體的默認保證金設置的一個直接結果。

添加body { margin: 0 }解決了我的問題。

相關問題