三个 JS - window.onload 打开浏览器时先显示场景太小再调整大小
Three JS - window.onload first displays scene too small before resizing when opening browser
我正在学习 WebGL,我想做一些基本的事情:每当我打开 index.html
,我希望渲染的场景适合 window。但是,当我尝试 运行 我的代码(我改编自 WebGL 教程)时,一瞬间,场景在调整大小之前以较小的尺寸显示。从视觉上看,这很刺耳。我该如何防止这种情况发生?
我的两个文件:
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- <meta charset="utf-8" name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=1">-->
<meta charset="utf-8">
<title>ThreeJS Rotation</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module" src="js/script.js"></script>
</body>
</html>
js/script.js
:
// import * as THREE from './three.module.js'
//
// import {OrbitControls} from "./OrbitControls";
// See
import { OrbitControls } from 'https://unpkg.com/three@0.119.1/examples/jsm/controls/OrbitControls.js';
import * as THREE from 'https://unpkg.com/three@0.119.1/build/three.module.js';
// import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js';
const scene = new THREE.Scene();
// Add background image
// scene.background = new THREE.Color(0x19d7f8);
const loader = new THREE.TextureLoader();
scene.background = loader.load('https://assets.imgix.net/hp/snowshoe.jpg')
// Arguments:
// 1) Field of Value (degrees)
// 2) Aspect ratio
// 3) Near clipping plane
// 4) Far clipping plane
const camera = new THREE.PerspectiveCamera( 50 , window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.set(0, 0, 5 )
const renderer = new THREE.WebGLRenderer();
// // Need to set size of renderer. For performance, may want to reduce size.
// // Can also reduce resolution by passing false as third arg to .setSize
// renderer.setSize( window.innerWidth, window.innerHeight );
// Add the rendered to the HTML
document.body.appendChild( renderer.domElement );
function resizer() {
var width = window.innerWidth;
let height = window.innerHeight;
let backgroundImg = scene.background;
let bgWidth = backgroundImg.image.width;
let bgHeight = backgroundImg.image.height;
let texAspect = bgWidth / bgHeight;
let aspect = width / height;
let relAspect = aspect / texAspect;
scene.background.repeat = new THREE.Vector2( Math.max(relAspect, 1), Math.max(1/relAspect,1) );
scene.background.offset = new THREE.Vector2( -Math.max(relAspect-1, 0)/2, -Math.max(1/relAspect-1, 0)/2 );
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix()
}
window.onload = resizer
window.addEventListener('resize', resizer)
var controls = new OrbitControls(camera, renderer.domElement);
// Prevent Ctrl + Mouse from panning
controls.enablePan = false;
controls.update();
// A BoxGeometry is an object that contains all points (vertices) and fill (faces)
// of the cube
// const geometry = new THREE.BoxGeometry();
// // Allegedly, BoxBufferGeometry is faster
// const geometry = new THREE.BoxBufferGeometry();
// // Determines surface color (maybe texture?)
// const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//
// // Mesh takes a geometry and applies the material to it
// const cube = new THREE.Mesh( geometry, material );
//
// scene.add( cube );
// Add arrow variables
const arrowDirection = new THREE.Vector3();
// Center of screen
const arrowPosition = new THREE.Vector3(0, 0, 0);
//
// const arrowPosition = new THREE.Vector3(0, 1, 0);
//
// const arrowPosition = new THREE.Vector3(0, 0, 0);
arrowDirection.subVectors( scene.position, new THREE.Vector3(1, 1, 1)).normalize();
const arrow = new THREE.ArrowHelper( arrowDirection, arrowPosition, 1, 0xffff00, 0.6, 0.4);
scene.add( arrow );
// This somehow creates a loop that causes the rendered to draw the scene
// every time the screen is refreshed (typically 60fps)
function animate() {
requestAnimationFrame( animate );
// arrow.rotation.x += 0.01;
// arrow.rotation.y += 0.01;
// cube.rotation.x += 0.01;
// cube.rotation.y += 0.01;
renderer.render( scene, camera );
controls.update();
}
animate();
您可以尝试在将渲染器 canvas 添加到 dom
之前设置渲染器大小
const width = window.innerWidth;
const height = window.innerHeight;
renderer.setSize(width, height);
document.body.appendChild( renderer.domElement );
我正在学习 WebGL,我想做一些基本的事情:每当我打开 index.html
,我希望渲染的场景适合 window。但是,当我尝试 运行 我的代码(我改编自 WebGL 教程)时,一瞬间,场景在调整大小之前以较小的尺寸显示。从视觉上看,这很刺耳。我该如何防止这种情况发生?
我的两个文件:
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- <meta charset="utf-8" name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=1">-->
<meta charset="utf-8">
<title>ThreeJS Rotation</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module" src="js/script.js"></script>
</body>
</html>
js/script.js
:
// import * as THREE from './three.module.js'
//
// import {OrbitControls} from "./OrbitControls";
// See
import { OrbitControls } from 'https://unpkg.com/three@0.119.1/examples/jsm/controls/OrbitControls.js';
import * as THREE from 'https://unpkg.com/three@0.119.1/build/three.module.js';
// import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js';
const scene = new THREE.Scene();
// Add background image
// scene.background = new THREE.Color(0x19d7f8);
const loader = new THREE.TextureLoader();
scene.background = loader.load('https://assets.imgix.net/hp/snowshoe.jpg')
// Arguments:
// 1) Field of Value (degrees)
// 2) Aspect ratio
// 3) Near clipping plane
// 4) Far clipping plane
const camera = new THREE.PerspectiveCamera( 50 , window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.set(0, 0, 5 )
const renderer = new THREE.WebGLRenderer();
// // Need to set size of renderer. For performance, may want to reduce size.
// // Can also reduce resolution by passing false as third arg to .setSize
// renderer.setSize( window.innerWidth, window.innerHeight );
// Add the rendered to the HTML
document.body.appendChild( renderer.domElement );
function resizer() {
var width = window.innerWidth;
let height = window.innerHeight;
let backgroundImg = scene.background;
let bgWidth = backgroundImg.image.width;
let bgHeight = backgroundImg.image.height;
let texAspect = bgWidth / bgHeight;
let aspect = width / height;
let relAspect = aspect / texAspect;
scene.background.repeat = new THREE.Vector2( Math.max(relAspect, 1), Math.max(1/relAspect,1) );
scene.background.offset = new THREE.Vector2( -Math.max(relAspect-1, 0)/2, -Math.max(1/relAspect-1, 0)/2 );
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix()
}
window.onload = resizer
window.addEventListener('resize', resizer)
var controls = new OrbitControls(camera, renderer.domElement);
// Prevent Ctrl + Mouse from panning
controls.enablePan = false;
controls.update();
// A BoxGeometry is an object that contains all points (vertices) and fill (faces)
// of the cube
// const geometry = new THREE.BoxGeometry();
// // Allegedly, BoxBufferGeometry is faster
// const geometry = new THREE.BoxBufferGeometry();
// // Determines surface color (maybe texture?)
// const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//
// // Mesh takes a geometry and applies the material to it
// const cube = new THREE.Mesh( geometry, material );
//
// scene.add( cube );
// Add arrow variables
const arrowDirection = new THREE.Vector3();
// Center of screen
const arrowPosition = new THREE.Vector3(0, 0, 0);
//
// const arrowPosition = new THREE.Vector3(0, 1, 0);
//
// const arrowPosition = new THREE.Vector3(0, 0, 0);
arrowDirection.subVectors( scene.position, new THREE.Vector3(1, 1, 1)).normalize();
const arrow = new THREE.ArrowHelper( arrowDirection, arrowPosition, 1, 0xffff00, 0.6, 0.4);
scene.add( arrow );
// This somehow creates a loop that causes the rendered to draw the scene
// every time the screen is refreshed (typically 60fps)
function animate() {
requestAnimationFrame( animate );
// arrow.rotation.x += 0.01;
// arrow.rotation.y += 0.01;
// cube.rotation.x += 0.01;
// cube.rotation.y += 0.01;
renderer.render( scene, camera );
controls.update();
}
animate();
您可以尝试在将渲染器 canvas 添加到 dom
之前设置渲染器大小const width = window.innerWidth;
const height = window.innerHeight;
renderer.setSize(width, height);
document.body.appendChild( renderer.domElement );