Как реализовать OrbitControls и загрузку своей модели в Three.js? Uncaught SyntaxError: Cannot use import statement outside a module

Пытаюсь разобраться в three.js по документации, но не понимаю как реализовать возможность вращать модель мышкой? Т.е. Я понимаю, что для этого служит OrbitControls, но когда вместо анимации пытаюсь использовать его, копируя код прямиком из документации, то модель вообще не появляется. Вместо неё появляются ошибки:

Uncaught SyntaxError: Cannot use import statement outside a module(STLLoader.js:58)
Uncaught SyntaxError: Cannot use import statement outside a module(OrbitControls.js:10)
(index):48 Uncaught ReferenceError: OrbitControls is not defined at (index):45(помечу строчку в коде)

Да, та же проблема с STLLoader.js (хоть он пока и не нужен, но конечная цель - загрузить свою модель), я пытался делать и через импорты, и прописывать type="module" для скриптов, но проблема +- та же, либо сцены нет вообще, либо модель не появляется. Для меня это странно, т.к. three.js подключена тем же путём но она работает.

Код:

<body>
<script src="js/three.js"></script>
<script src="js/STLLoader.js"></script>
<script src="js/OrbitControls.js"></script>
<script>
    //Сцена
    const scene = new THREE.Scene();
    //Камера
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    //Рендерер, размером с область камеры, пустой canvas
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    //Фигура с геометрией и материалом
    const geometry = new THREE.TorusGeometry(10, 3, 16, 100);
    const material = new THREE.MeshNormalMaterial();
    //Сетка принимающая геометрию и применяющая материал + позиция камеры
    const sphere = new THREE.Mesh(geometry, material);
    scene.add(sphere);
    //Новая сцена для света, + цвет света, позиция.
    const spotLight = new THREE.SpotLight(0xeeeece);
    spotLight.position.set(1000, 1000, 1000);
    scene.add(spotLight);
    //Ещё один свет
    const spotLight2 = new THREE.SpotLight(0xffffff);
    spotLight2.position.set(-200, -200, -200);
    scene.add(spotLight2);

    const controls = new OrbitControls(camera, renderer.domElement); // - строка с ошибкой.
    camera.position.set( 0, 20, 100 );
    controls.update();
    //Анимация, рендеринг
    function render() {
        requestAnimationFrame(render);
        controls.update();
        renderer.render(scene, camera);
    }
    render();
</script>
</body>
</html>

Ответы (1 шт):

Автор решения: prisoner849

Если использовать ES6-модули, как во всех официальных примерах, то их нужно импортировать с помощью import. Тогда основной файл Three.js будет three.module.js, остальное берется из папки examples\jsm:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

    //Сцена
    const scene = new THREE.Scene();
    //Камера
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    //Рендерер, размером с область камеры, пустой canvas
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    //Фигура с геометрией и материалом
    const geometry = new THREE.TorusGeometry(10, 3, 16, 100);
    const material = new THREE.MeshNormalMaterial();
    //Сетка принимающая геометрию и применяющая материал + позиция камеры
    const sphere = new THREE.Mesh(geometry, material);
    scene.add(sphere);
    //Новая сцена для света, + цвет света, позиция.
    const spotLight = new THREE.SpotLight(0xeeeece);
    spotLight.position.set(1000, 1000, 1000);
    scene.add(spotLight);
    //Ещё один свет
    const spotLight2 = new THREE.SpotLight(0xffffff);
    spotLight2.position.set(-200, -200, -200);
    scene.add(spotLight2);

    const controls = new OrbitControls(camera, renderer.domElement); // - строка с ошибкой.
    camera.position.set( 0, 20, 100 );
    controls.update();
    //Анимация, рендеринг
    function render() {
        requestAnimationFrame(render);
        controls.update();
        renderer.render(scene, camera);
    }
    render();
</script>

OrbitControls используется для перемещения камеры вокруг объекта, объект при этом остается на месте.

PS Сообщают, что в ревизии 124 не будет больше скриптов в папке examples\js (и папки самой тоже не будет, наверное :) ) Поэтому лучше сразу ориентироваться на ES6-модули из examples\jsm, то есть смотреть, как оно сделано в официальных примерах.

→ Ссылка