Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js.zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем, перемещайте камеру двумя пальцами и делайте зум щипком.

Вращение камеры происходит с помощью зажатой левой кнопки мыши. Панорамирование, то есть перенос камеры - с помощью зажатой правой кнопки мыши. Приближение и отдаление камеры - с помощью вращения или зажатого колёсика мыши.
Установка редактора кода и ПО для локального сервера
- Установите какой-нибудь редактор кода, например, в Notepad++ или в Sublime Text 4 (ST4): https://www.sublimetext.com/download
- Установите Node.js для запуска локального сервера: https://nodejs.org/en/download
- Примечание. После установки Node.js из консоли будет доступен менеджер пакетов NPM
- Откройте терминал (командную строку), например, на Windows 10 можно в поиске программ ввести CMD и выбрать "Run as administrator" - "Запустить от администратора"
- В консоле введите команду для установки локального сервера:
- Установите js-beautify, чтобы форматировать код из консоли:
- Примечание. О том, как использовать js-beautify можно прочитать здесь: Консольные команды для форматирования исходного кода на C, C++, C#, Java, JavaScript, HTML и CSS. Сортировка пакетов на Python
Пишем код по шагам
- Создайте пустую папку, например, с именем "orbit-controls-threejs-js"
- Откройте эту папку в редакторе кода, например, в Sublime Text 4 (ST4). Проще всего добавить ST4 в системную Path на Windows 10. Если не знаете, как добавить путь к EXE программы в Path, то спросите у ИИ, например, у Gemini: "Как добавить путь к Sublime Text 4 в Path". Тогда можно будет в CMD из созданной папки набрать:
- Создайте файл index.html и наберите "html" и нажмите Tab и будет сгенерирован код:
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
</body>
</html> |
|
- Можете отформатировать код командой:
| Bash | 1
| js-beautify -n *.html -b "collapse, preserve-inline" |
|
- После этой команды код будет отформатирован:
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
</body>
</html> |
|
- Найдём ссылки на библиотеку Three.js. Перейдите по ссылке: https://cdn.jsdelivr.net, прокрутите страницу немного вниз и наберите в поиске: three.js
- Перейдите по первой ссылке в поиске:

- Кликните по ссылке "Files":

- Кликните по папке "build":

- Найдите строку с "three.module.min.js" и эту нажмите кнопку для копирования URL:

- Добавьте следующий код с "importmap" в "index.html" и вставьте скопированный URL:
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js"
}
}
</script>
</body>
</html> |
|
- Примечание. Благодаря "importmap" мы можем в файлах .js импортировать Three.js командой:
| JavaScript | 1
| import * as THREE from "three"; |
|
- В файле "index.html" внутри тега <body> добавьте тег холста с id="renderCanvas":
| PHP/HTML | 1
2
3
4
5
6
| <body>
<canvas id="renderCanvas"></canvas>
<!-- ... -->
</body> |
|
- Добавьте подключение файла "./js/index.js", который мы добавим позже:
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js"
}
}
</script>
<script type="module" src="./js/index.js"></script>
</body>
</html> |
|
- Создайте в папку "js", а в папке "js" создайте файл "index.js"
- Протестируем запуск приложения. Добавьте в "index.js" строку вывода "Hello World!" в консоль браузера:
| JavaScript | 1
| console.log("Hello World!"); |
|
- В консоле введите команду для запуска локального сервера:
- Будет выведен список адресов для браузера, например у меня:
| Bash | 1
2
3
4
| Available on:
http://192.168.1.65:8080
http://127.0.0.1:8080
Hit CTRL-C to stop the server |
|
- Если у вас телефон подключён по Wi-Fi, то введите в браузере телефона адрес: 192.168.1.65:8080
- Перейдите в Chrome (или Edge) и нажмите "Ctrl+Shift+J" для открытия консоли браузера. Если у вас Firefox, то погуглите, как открыть консоль в Firefox
- Введите в адресной строке браузера следующий адрес и после этого нажмите Enter:
- В консоли вы увидите "Hello World!"
- Примечание. Если вы что-то меняете в проекте и хотите перезапустить приложение в браузере, то обновляйте страницу с очисткой Cache - правой кнопкой по кнопке перезагрузки и выберите: "Empty Cache and Hard Reload"
- Откройте файл "index.js" и добавьте следующий код, который импортирует библиотеки Three.js, создаёт три функции: main(), init(), animate(), создаёт рисовальщик (renderer), сцену (scene) и камеру (camera):
| JavaScript | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| import * as THREE from "three";
let renderer, scene, camera;
function main() {
init();
animate();
}
window.onload = main;
function init() {
const canvas = document.getElementById("renderCanvas");
renderer = new THREE.WebGLRenderer({ antialias: true, canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(5, 5, 10);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
} |
|
- Обновите страницу браузера и вы увидите холст тёмно-серого цвета
- Уберём полосы прокрутки со страницы и растянем холст. Для этого создайте папку "css" в корне проекта и в папке "css" добавьте файл "style.css":
| CSS | 1
2
3
4
5
6
7
8
9
10
11
12
13
| body,
html {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
} |
|
- Добавьте подключение файла "css/style.css" в файле "index.html". Для этого вы можете внутри тега <head> набрать "link" (без ковычек) и нажать Tab и написать в свойстве href="" путь к файлу "./css/style.css" следующим образом и добавьте текст "Examples" в тег <title>:
| PHP/HTML | 1
2
3
4
5
6
| <head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="./css/style.css">
<title>Example</title>
</head> |
|
- Обновите страницу браузера и теперь вы видите, что холст растянут на всю клиентскую область браузера и полос прокрутки нет. Текущий код:
index.html
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="./css/style.css">
<title>Example</title>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js"
}
}
</script>
<script type="module" src="./js/index.js"></script>
</body>
</html> |
|
js/index.js
| JavaScript | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| import * as THREE from "three";
let renderer, scene, camera;
function main() {
init();
animate();
}
window.onload = main;
function init() {
const canvas = document.getElementById("renderCanvas");
renderer = new THREE.WebGLRenderer({ antialias: true, canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(5, 5, 10);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
} |
|
css/style.css
| CSS | 1
2
3
4
5
6
7
8
9
10
11
12
13
| body,
html {
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#renderCanvas {
width: 100%;
height: 100%;
} |
|
Добавляем библиотеку OrbitControls.js и рисование кубика средствами Three.js
- Найдём ссылки на библиотеку OrbitControls.js. Перейдите по ссылке: https://cdn.jsdelivr.net, прокрутите страницу немного вниз и наберите в поиске: three.js
- Перейдите по первой ссылке в поиске:

- Кликните по ссылке "Files":

- Кликните по папке "examples":

- Кликните по папке "jsm":

- Кликните по папке "controls":

- Скопируйте URL, нажав на кнопку:

- Откройте файл "index.html" и вставьте URL, создав новую строку подключения для OrbitControls.js:
| PHP/HTML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="./css/style.css">
<title>Example</title>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js",
"orbit-controls": "https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/controls/OrbitControls.js"
}
}
</script>
<script type="module" src="./js/index.js"></script>
</body>
</html> |
|
- Откройте файл index.js и добавьте импортирование библиотеки OrbitControls.js:
| JavaScript | 1
| import { OrbitControls } from "orbit-controls"; |
|
- Добавьте глобальные переменные "controls" и "cube" к уже имеющимся:
| JavaScript | 1
| let renderer, scene, camera, controls, cube; |
|
- В функции init() после создания камеры добавьте код создания "controls", передав в конструктор OrbitControls() ссылку на камеру и ссылку на <canvas>:
| JavaScript | 1
2
| controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // Smooth movement |
|
- Далее добавьте код создания геометрии и материала куба и добавьте куб на сцену командой scene.add(cube):
| JavaScript | 1
2
3
4
| const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff88 });
cube = new THREE.Mesh(geometry, material);
scene.add(cube); |
|
- Добавьте на сцену два источника света - направленный свет, как Солнце и окружающий свет:
| JavaScript | 1
2
3
4
5
6
| const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 4, 3);
scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight); |
|
- Добавьте команду controls.update() в функцию animate():
| JavaScript | 1
2
3
4
5
| function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
} |
|
- Добавим функцию onWindowResize(), которая должна вызываться при изменении клиентской области окна браузера, чтобы при изменении соотношения сторон клиентской области окна браузера не деформировались объекты на сцене:
| JavaScript | 1
2
3
4
5
| function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
} |
|
- Добавим в main() строку настройки "window.onresize = onWindowResize", чтобы функция onWindowResize() вызывалась при изменении размера клиентской области окна браузера:
| JavaScript | 1
2
3
4
5
| function main() {
init();
window.onresize = onWindowResize;
animate();
} |
|
- Получается следующий код:
js/index.js
| JavaScript | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| import * as THREE from "three";
import { OrbitControls } from "orbit-controls";
let renderer, scene, camera, controls, cube;
function main() {
init();
window.onresize = onWindowResize;
animate();
}
window.onload = main;
function init() {
const canvas = document.getElementById("renderCanvas");
renderer = new THREE.WebGLRenderer({ antialias: true, canvas });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
scene = new THREE.Scene();
scene.background = new THREE.Color(0x222222);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(5, 5, 10);
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // Smooth movement
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff88 });
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 4, 3);
scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
} |
|
- Скопируйте проект на бесплатный хостинг, например, на GitHub Pages и он будет доступен по ссылка, например: ссылка
- Финальный проект: orbit-controls-threejs-js.zip
Подключение библиотек локально
Вы можете не зависеть от работы сайта https://www.jsdelivr.com/ в случае, если сайт по каким-то причинам будет недоступен. Вы можете скопировать файлы на свой хостинг, например, на GitHub Pages. Сейчас файл скачивают в кэш браузера по ссылкам:
| PHP/HTML | 1
2
3
4
5
6
7
8
| <script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.183.2/build/three.module.min.js",
"orbit-controls": "https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/controls/OrbitControls.js"
}
}
</script> |
|
Вы можете у себя в корне хостинга создать папку "libs", а в ней папку "three@0.183.2" и далее уже в этой новой папке "three@0.183.2" создать две папки: "build" и "examples" и т.д. То есть вы создаёте у себя на хостинге папки, где будут храниться два файла: three.module.min.js и OrbitControls.js При этом лучше сохранить туже самую иерархию папок:
| PHP/HTML | 1
2
3
4
5
6
7
8
| <script type="importmap">
{
"imports": {
"three": "/libs/three@0.183.2/build/three.module.min.js",
"orbit-controls": "/libs/three@0.183.2/examples/jsm/controls/OrbitControls.js"
}
}
</script> |
|
Важно! В папку "build" помимо файла "three.module.min.js" нужно скопировать файл "three.core.min.js", который можно найти на https://www.jsdelivr.com
У вас проекте будет три файла в папке "libs". Два файла в папке "build":

И одни файл в папке "controls":

Получился такой проект с включёнными в него библиотеками: orbit-controls-threejs-js-plus-libs.zip
Когда вы вводите в консоль команду для запуска локального сервера:
, то выводится список адресов для браузера, например у меня:
| Bash | 1
2
3
4
| Available on:
http://192.168.1.65:8080
http://127.0.0.1:8080
Hit CTRL-C to stop the server |
|
Если у вас телефон подключён по Wi-Fi, то введите в браузере телефона адрес: 192.168.1.65:8080, чтобы протестировать управление камерой в мобильном браузере. Одним пальцев - вращение камеры. Двумя пальцами - перемещение камеры, и увеличение уменьшение - щипком.
|