ui-*_*.uk 2 javascript canvas three.js responsive-design
嗨,我正在尝试让我的画布/webgl 将窗口的高度和宽度调整为 100% 我已经这样做了,但是如果我将窗口的大小从小到大调整,它不再“缩放/适合”窗口并且仍然很小想法?JSfiddle:http : //jsfiddle.net/jyr6y3fx/
代码:
var scene, renderer;
var glitchPass;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer( { alpha: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
// postprocessing
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );
glitchPass = new THREE.GlitchPass();
glitchPass.renderToScreen = true;
composer.addPass( glitchPass );
}
function animate() {
requestAnimationFrame( animate );
composer.render();
//renderer.render(scene, camera);
}
Run Code Online (Sandbox Code Playgroud)
先感谢您
这是因为,渲染器\xc2\xad \的宽度和高度始终是固定的,并且在调整浏览器窗口大小时不会改变。
\n\n要解决此问题,您需要在窗口调整大小时重置 renderer\xc2\xad \ 的宽度和高度,您可以这样做......
\n\nwindow.addEventListener(\'resize\', function() {\n renderer.setSize(window.innerWidth, window.innerHeight);\n});\nRun Code Online (Sandbox Code Playgroud)\n\n\n
其他的答案都很悲伤。他们都在与浏览器作斗争,而不是与它合作。
可以说,调整three.js 大小的最佳方法是对其进行编码,因此它只接受CSS 设置的画布大小。这样,无论您如何使用画布,您的代码都可以正常工作,无需针对不同情况进行更改。
首先在设置初始纵横比时没有理由设置它,因为我们将设置它以响应画布的大小不同,所以设置它两次只是浪费代码
// There's no reason to set the aspect here because we're going
// to set on resize anyway
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
Run Code Online (Sandbox Code Playgroud)
然后我们需要一些代码来调整画布的大小以匹配其显示大小
function resizeCanvasToDisplaySize(force) {
const canvas = renderer.domElement;
// look up the size the canvas is being displayed
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// adjust displayBuffer size to match
if (force || canvas.width !== width || canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// update any render target sizes here
}
}
Run Code Online (Sandbox Code Playgroud)
在渲染循环中调用它,并在初始化时调用一次
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);
Run Code Online (Sandbox Code Playgroud)
对于全屏,这是所有需要的 css
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
Run Code Online (Sandbox Code Playgroud)
这里有 4 个示例,示例之间的唯一区别是 CSS 以及是我们制作画布还是 Three.js 制作画布。没有其他代码更改。
示例 1:全屏,我们制作画布
// There's no reason to set the aspect here because we're going
// to set on resize anyway
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
Run Code Online (Sandbox Code Playgroud)
function resizeCanvasToDisplaySize(force) {
const canvas = renderer.domElement;
// look up the size the canvas is being displayed
const width = canvas.clientWidth;
const height = canvas.clientHeight;
// adjust displayBuffer size to match
if (force || canvas.width !== width || canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// update any render target sizes here
}
}
Run Code Online (Sandbox Code Playgroud)
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);
Run Code Online (Sandbox Code Playgroud)
示例2:全屏画布,three.js制作画布
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
Run Code Online (Sandbox Code Playgroud)
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame any
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize(force) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (force || canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);Run Code Online (Sandbox Code Playgroud)
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }Run Code Online (Sandbox Code Playgroud)
示例 3:内联画布
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>Run Code Online (Sandbox Code Playgroud)
"use strict";
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
// There's no reason to set the aspect here because we're going
// to set it every frame any
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize(force) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (force || canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);Run Code Online (Sandbox Code Playgroud)
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }Run Code Online (Sandbox Code Playgroud)
示例 4:50% 宽度的画布(如实时编辑器)
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"></script>Run Code Online (Sandbox Code Playgroud)
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector(".diagram canvas")});
// There's no reason to set the aspect here because we're going
// to set it every frame any
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
camera.position.z = 400;
const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
color: 0x555555,
specular: 0xffffff,
shininess: 50,
shading: THREE.SmoothShading
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
const light1 = new THREE.PointLight(0xff80C0, 2, 0);
light1.position.set(200, 100, 300);
scene.add(light1);
function resizeCanvasToDisplaySize(force) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (force || canvas.width !== width ||canvas.height !== height) {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
// set render target sizes here
}
}
function animate(time) {
time *= 0.001; // seconds
resizeCanvasToDisplaySize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);Run Code Online (Sandbox Code Playgroud)
body { font-size: x-large; }
.diagram { width: 150px; height: 150px; float: left; margin: 1em; }
canvas { width: 100%; height: 100%; }Run Code Online (Sandbox Code Playgroud)
注意window.innerWidth并且window.innerHeight在上面的代码中从未被引用过,但它适用于所有情况。
为什么不使用resize事件?因为在某些情况下,即使画布更改了大小,您也不会收到调整大小事件。例如,如果您正在制作一个 2 列编辑器,并且您可以在 2 列之间绘制分隔线。或者,如果您的画布根据附近的内容进行缩放。无论哪种情况,都不会resize发生事件。
| 归档时间: |
|
| 查看次数: |
5762 次 |
| 最近记录: |