簡體   English   中英

Three.js 調整畫布大小

[英]Three.js Resizing Canvas

我一直在做一個 3D 項目,我們使用 Three.js 庫在 Web 瀏覽器中顯示 3D 對象。

問題是:

  • 第一個模型顯示在一個小的dom元素中或當瀏覽器窗口本身很小時。
  • 然后當窗口(或dom元素調整大小)時,模型變得像素化

以下是一些截圖:

調整大小之前:

在此處輸入圖像描述

調整大小后:

在此處輸入圖像描述

調整大小后應該如何:

在此處輸入圖像描述

這是設置模型尺寸(高度和寬度)的代碼部分,如果觸發了調整大小事件,則會調用此函數:

console.log("domChanged fired")

instance.domBoundingBox = instance.dom.getBoundingClientRect();
instance.domCenterPos.x = instance.domBoundingBox.width / 2 + instance.domBoundingBox.left;
instance.domCenterPos.y = instance.domBoundingBox.height / 2 + instance.domBoundingBox.top;

var width = instance.dom.clientWidth, height = instance.dom.clientHeight;
instance.domWidthHalf = width / 2, instance.domHeightHalf = height / 2;

// TODO: fire event to expose it to site developers

// here we should update several values regarding width,height,position
if(instance.cameraReal) {
    instance.cameraReal.aspect = instance.dom.clientWidth / instance.dom.clientHeight;
    instance.cameraReal.updateProjectionMatrix();
}

if(instance.renderer3D)
    instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);

任何人都可以給我一個提示嗎? 我已經為此工作了幾天,但到目前為止還沒有任何線索

因此,canvas 元素可以像其他所有元素一樣調整大小。 您要做的是告訴渲染器和相機也調整畫布內容的大小。

window.addEventListener( 'resize', onWindowResize, false );

function onWindowResize(){

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

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

}

最后問題解決了,實際問題來自於應用程序正在使用THREE.EffectComposer對象,在類構造函數中創建了一個 composer 對象,如下所示:

this.composer = new THREE.EffectComposer(this.renderer3D);

因此對於渲染器,作曲家需要在事件處理函數之后更新大小,如下所示:

if(instance.renderer3D)
    instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
if(instance.composer)
    instance.composer.setSize(instance.dom.clientWidth, instance.dom.clientHeight);

這完美地解決了這個問題:)

我用 React JS 應用了 Shawn Whinnery 的回答來滿足我的需求:

啟動監聽器 onMount:

componentDidMount() {
  window.addEventListener('resize', this.handleResize, false)
}

移除監聽器 onUnmount(因為我們喜歡垃圾回收):

componentWillUnmount() {
  window.removeEventListener('resize', this.handleResize, false)
}

安裝處理函數:

handleResize = () => {
  this.camera.aspect = window.innerWidth / window.innerHeight
  this.camera.updateProjectionMatrix()
  this.renderer.setSize(window.innerWidth, window.innerHeight)
}

胖箭頭語法用於避免綁定this 如果你有這個代碼將無法工作: handleResize() { ... } ,但當然,如果你將它添加到你的構造函數中它會工作:

this.handleResize = this.handleResize.bind(this)

最后說明:確認您的相機是this.camera並且您的渲染器是this.renderer 除此之外,您應該可以將其全部粘貼進去。

對於那些在谷歌上搜索的人,如果您想快速開始使用為您調整大小的幫助工具,請查看此 github: https ://github.com/jeromeetienne/threex.windowresize

你唯一需要做的就是通過bower安裝它並初始化它:

new THREEx.WindowResize(renderer, camera)

這很簡單。 即使調整瀏覽器窗口的大小,這三個.js 代碼也不會改變。

代碼:

 //Simple Cube Example var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: "rgb(255, 0, 0)" } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; var edges = new THREE.EdgesHelper( cube, "rgb(0, 0, 0)" ); edges.material.linewidth = 5; scene.add( edges ); function animate(){ requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate(); function rot(){ requestAnimationFrame( rot ); edges.rotation.x += 0.01; edges.rotation.y += 0.01; } rot(); //this will not change it's size when browser is resized, but use css and correct it.
 //this is the code. it does not work use a div and use the javascript .code{ float: left; width: 100vw; /*fullscreen*/ height: 100vh; }
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="keywords" content=""> <meta name="robots" content="index, follow" /> <link rel="canonical" href="http://" /> <meta name="author" content=""> <meta name="google-site-verification" content=""> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://fonts.googleapis.com/css?family=Hammersmith+One|Lato" rel="stylesheet"> <title></title> <link rel="stylesheet" href="style.css"> </head> <body> <script src="https://threejs.org/build/three.js"></script> </body> </html>

嘗試使用抗鋸齒屬性將像素化問題解決 50 - 70%

例如: var renderer = new THREE.WebGLRenderer({antialias:true});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM