Three.js Анимация в Canvas не изменяется должным образом в приложении Vue

#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. Спасибо за ответ, глядя на него сейчас, вопрос кажется довольно глупым, функция действительно не имела большого смысла ^^