#javascript #vue.js #three.js
#javascript #vue.js #three.js
Вопрос:
В настоящее время я пытаюсь научиться Three.js и я делаю это внутри Vue.js компонент, это мой код:
<script>
import * as THREE from "three";
export default {
name: "Scene",
mounted() {
this.initThree();
},
methods: {
initThree() {
this.canvas = document.getElementById("background");
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, 2, 0.1, 1000);
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
alpha: true,
antialias: true,
});
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
let geometry = new THREE.BoxGeometry(1, 1, 1);
this.light = new THREE.DirectionalLight(0xffffff, 1);
this.light.position.set(4, -2, 2);
this.scene.add(this.light);
this.camera.position.z = 2;
this.cubes = [
this.makeInstance(geometry, 0x44aa88, 0),
this.makeInstance(geometry, 0x8844aa, -2),
this.makeInstance(geometry, 0xaa8844, 2),
];
this.animate();
},
animate() {
this.cubes.forEach((cube) => {
cube.rotation.y = 0.01;
});
this.resizeCanvasToDisplaySize();
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.animate);
},
resizeCanvasToDisplaySize() {
const canvas = this.renderer.domElement;
// look up the size the canvas is being displayed
const width = canvas.clientWidth;
const height = canvas.clientHeight;
if (canvas.width !== width || canvas.height !== height) {
this.renderer.setSize(width, height, false);
this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();
}
},
makeInstance(geometry, color, x) {
const material = new THREE.MeshPhongMaterial({ color });
const cube = new THREE.Mesh(geometry, material);
this.scene.add(cube);
cube.position.x = x;
return cube;
},
},
};
</script>
<style scoped>
canvas {
display: block;
width: 100%;
}
</style>
Если я изменяю размер окна до меньшего размера, чем начальный размер (размер при загрузке страницы), в инструментах разработчика в Chrome это работает, ширина и высота холста изменяются должным образом. Если я увеличу размер больше начального, он останется прежним и вообще не масштабируется. Также масштабирование работает только в инструментах разработки, а не в реальном окне.
Комментарии:
1. Я предлагаю вам сделать это по-другому и зарегистрировать прослушиватель событий для
resize
события. Затем вы можете использовать ту же реализацию, что и в этом базовом примере: threejs.org/examples/webgl_geometry_cube
Ответ №1:
Логика в вашей функции изменения размера ошибочна. По сути, вы получаете текущую ширину: const width = canvas.clientWidth;
и затем вы по кругу присваиваете ее обратно туда, откуда вы ее получили. Вы вроде как делаете то же самое, что и это:
width = canvas.width;
canvas.width = width;
Вы должны использовать стандартный метод, используемый во всех Three.js примеры. Вместо проверки изменения размера в каждом animate()
кадре просто установите прослушиватель событий для изменения размера окна, а затем используйте размер окна для установки размеров холста:
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
Комментарии:
1. Спасибо за ответ, глядя на него сейчас, вопрос кажется довольно глупым, функция действительно не имела большого смысла ^^