Aleksmorshen commited on
Commit
f48879f
·
verified ·
1 Parent(s): b5f5087

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +170 -376
index.html CHANGED
@@ -2,405 +2,199 @@
2
  <html lang="ru">
3
  <head>
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6
- <title>Менеджер Ссылок iOS</title>
7
- <!-- Подключение React и ReactDOM -->
8
- <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
9
- <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
10
- <!-- Подключение Babel для JSX -->
11
- <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
12
-
13
  <style>
14
- /* --- iOS 18 Inspired Styles --- */
15
- :root {
16
- --ios-system-blue: #007AFF;
17
- --ios-system-red: #FF3B30;
18
- --ios-system-gray: #8E8E93;
19
- --ios-system-gray-2: #AEAEB2;
20
- --ios-system-gray-3: #C7C7CC;
21
- --ios-system-gray-4: #D1D1D6;
22
- --ios-system-gray-5: #E5E5EA;
23
- --ios-system-gray-6: #F2F2F7;
24
- --ios-background-light: #FFFFFF; /* Primary Light Background */
25
- --ios-secondary-background-light: #F2F2F7; /* Secondary Grouped Background */
26
- --ios-label-light: #000000; /* Primary Text */
27
- --ios-secondary-label-light: rgba(60, 60, 67, 0.6); /* Secondary Text */
28
- --ios-separator-light: rgba(60, 60, 67, 0.29);
29
-
30
- /* Dark Mode (Optional - basic setup) */
31
- /* @media (prefers-color-scheme: dark) { ... } */
32
- }
33
-
34
- html {
35
- /* Prevent elastic scrolling glow */
36
- overscroll-behavior-y: none;
37
- }
38
-
39
- body {
40
- margin: 0;
41
- padding: 0; /* Remove default padding */
42
- font-family: -apple-system, BlinkMacSystemFont, "San Francisco", "Helvetica Neue", "Arial", sans-serif;
43
- background-color: var(--ios-secondary-background-light);
44
- color: var(--ios-label-light);
45
- -webkit-font-smoothing: antialiased;
46
- -moz-osx-font-smoothing: grayscale;
47
- font-size: 17px; /* Base iOS font size */
48
- line-height: 1.4;
49
- overscroll-behavior-y: contain; /* Prevent body scroll */
50
- height: 100%; /* Ensure body takes full height */
51
- }
52
-
53
- #root {
54
- max-width: 600px; /* Typical max width for content on larger screens */
55
- margin: 0 auto;
56
- background-color: var(--ios-secondary-background-light);
57
- min-height: 100vh; /* Full height */
58
- display: flex;
59
- flex-direction: column;
60
- }
61
-
62
- .app-container {
63
- padding: 0; /* Reset padding */
64
- display: flex;
65
- flex-direction: column;
66
- flex-grow: 1; /* Allow container to grow */
67
- }
68
-
69
- /* Navigation Bar Style Header */
70
- .app-header {
71
- background-color: rgba(249, 249, 249, 0.94); /* Slightly transparent background like iOS nav */
72
- backdrop-filter: saturate(180%) blur(20px);
73
- -webkit-backdrop-filter: saturate(180%) blur(20px);
74
- border-bottom: 0.5px solid var(--ios-separator-light);
75
- padding: 12px 16px;
76
- text-align: center;
77
- position: sticky;
78
- top: 0;
79
- z-index: 10;
80
- }
81
-
82
- .app-header h1 {
83
  margin: 0;
84
- font-size: 17px; /* iOS Nav Bar Title Size */
85
- font-weight: 600; /* Semibold */
86
- color: var(--ios-label-light);
87
- }
88
-
89
- /* Main Content Area */
90
- .content-area {
91
- padding: 20px 0; /* Vertical padding, no horizontal padding here */
92
- flex-grow: 1;
93
- }
94
-
95
- /* Section Styling (like grouped table view) */
96
- .ios-section {
97
- background-color: var(--ios-background-light);
98
- margin: 0 16px 20px 16px; /* Standard iOS horizontal margins */
99
- border-radius: 10px; /* iOS rounded corners */
100
- overflow: hidden; /* Clip children to rounded corners */
101
- box-shadow: 0 1px 3px rgba(0,0,0,0.05); /* Subtle shadow */
102
- }
103
-
104
- .ios-section-header {
105
- padding: 8px 16px;
106
- font-size: 13px; /* Smaller header text */
107
- color: var(--ios-secondary-label-light);
108
- text-transform: uppercase;
109
- font-weight: 500;
110
- background-color: var(--ios-secondary-background-light); /* Header outside the white box */
111
- margin: 0 -16px 0 -16px; /* Extend to edges if needed */
112
- padding-left: 32px; /* Indent header text */
113
- padding-right: 32px;
114
- }
115
-
116
- /* Form Styling */
117
- .add-form {
118
- padding: 16px;
119
- display: flex;
120
- flex-direction: column;
121
- gap: 12px;
122
- }
123
-
124
- .add-form input[type="url"],
125
- .add-form input[type="text"] {
126
- width: calc(100% - 24px); /* Account for padding */
127
- padding: 11px 12px; /* iOS input padding */
128
- border: 0.5px solid var(--ios-system-gray-4);
129
- border-radius: 8px; /* Slightly less rounded than section */
130
- font-size: 16px;
131
- background-color: var(--ios-background-light); /* Ensure background matches */
132
- color: var(--ios-label-light);
133
- outline: none;
134
- -webkit-appearance: none; /* Remove default iOS styling */
135
- appearance: none;
136
- transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
137
  }
138
 
139
- .add-form input[type="url"]:focus,
140
- .add-form input[type="text"]:focus {
141
- border-color: var(--ios-system-blue);
142
- box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2); /* Subtle focus ring */
 
143
  }
144
 
145
- .add-form button {
146
- background-color: var(--ios-system-blue);
147
- color: white;
148
- border: none;
149
- padding: 12px 16px;
150
- border-radius: 8px;
151
- font-size: 17px;
152
- font-weight: 500;
153
- cursor: pointer;
154
- text-align: center;
155
- transition: background-color 0.15s ease;
156
- -webkit-appearance: none;
157
- appearance: none;
158
  }
 
 
 
 
 
 
159
 
160
- .add-form button:hover,
161
- .add-form button:focus {
162
- background-color: #0056b3; /* Darker blue on hover/focus */
163
- outline: none;
164
- }
165
 
166
- /* Link List Styling */
167
- .link-list {
168
- list-style: none;
169
- padding: 0;
170
- margin: 0; /* Reset margin inside section */
171
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
 
173
- .link-item {
174
- display: flex;
175
- align-items: center;
176
- justify-content: space-between;
177
- padding: 12px 16px; /* Standard iOS cell padding */
178
- border-bottom: 0.5px solid var(--ios-separator-light);
179
- gap: 10px;
180
- }
181
 
182
- /* Remove border from last item */
183
- .link-item:last-child {
184
- border-bottom: none;
185
- }
186
 
187
- .link-content {
188
- flex-grow: 1;
189
- min-width: 0; /* Allow content to shrink */
190
- }
191
 
192
- .link-description {
193
- font-size: 16px;
194
- font-weight: 400;
195
- color: var(--ios-label-light);
196
- margin-bottom: 3px;
197
- white-space: nowrap;
198
- overflow: hidden;
199
- text-overflow: ellipsis;
200
- }
201
 
202
- .link-url {
203
- font-size: 14px;
204
- color: var(--ios-system-gray);
205
- white-space: nowrap;
206
- overflow: hidden;
207
- text-overflow: ellipsis;
208
- display: block; /* Ensure it takes block space */
209
- text-decoration: none; /* Remove default underline */
210
- }
211
 
212
- .link-url:hover {
213
- color: var(--ios-system-blue); /* Highlight on hover */
214
- text-decoration: underline;
215
- }
216
 
217
- .delete-button {
218
- background-color: var(--ios-system-red);
219
- color: white;
220
- border: none;
221
- border-radius: 50%; /* Circular button */
222
- width: 28px;
223
- height: 28px;
224
- font-size: 16px;
225
- font-weight: bold;
226
- cursor: pointer;
227
- display: flex;
228
- align-items: center;
229
- justify-content: center;
230
- flex-shrink: 0; /* Prevent shrinking */
231
- padding: 0;
232
- line-height: 1;
233
- transition: background-color 0.15s ease;
234
- -webkit-appearance: none;
235
- appearance: none;
236
- }
237
 
238
- .delete-button:hover,
239
- .delete-button:focus {
240
- background-color: #D92C2A; /* Darker red */
241
- outline: none;
242
- }
243
 
244
- /* Empty State */
245
- .empty-state {
246
- text-align: center;
247
- padding: 40px 20px;
248
- color: var(--ios-secondary-label-light);
249
- font-size: 16px;
250
- }
251
 
252
- </style>
253
- </head>
254
- <body>
255
- <div id="root"></div>
256
-
257
- <script type="text/babel">
258
- const { useState, useEffect, Fragment } = React;
259
-
260
- // --- Утилита для работы с Local Storage ---
261
- const useLocalStorage = (key, initialValue) => {
262
- // Получаем из localStorage или используем initialValue
263
- const [storedValue, setStoredValue] = useState(() => {
264
- try {
265
- const item = window.localStorage.getItem(key);
266
- return item ? JSON.parse(item) : initialValue;
267
- } catch (error) {
268
- console.error("Ошибка чтения из localStorage:", error);
269
- return initialValue;
270
- }
271
- });
272
 
273
- // Обновляем localStorage при изменении state
274
- useEffect(() => {
275
- try {
276
- window.localStorage.setItem(key, JSON.stringify(storedValue));
277
- } catch (error) {
278
- console.error("Ошибка записи в localStorage:", error);
279
- }
280
- }, [key, storedValue]);
281
 
282
- return [storedValue, setStoredValue];
283
- };
 
 
284
 
285
- // --- Основной Компонент Приложения ---
286
- function App() {
287
- const [links, setLinks] = useLocalStorage('savedLinks', []);
288
- const [newUrl, setNewUrl] = useState('');
289
- const [newDescription, setNewDescription] = useState('');
290
- const [error, setError] = useState(''); // Для отображения ошибок ввода
291
-
292
- const isValidUrl = (string) => {
293
- try {
294
- new URL(string);
295
- return true;
296
- } catch (_) {
297
- return false;
298
- }
299
- };
300
-
301
- const handleAddLink = (e) => {
302
- e.preventDefault();
303
- setError(''); // Сброс ошибки
304
-
305
- if (!newDescription.trim()) {
306
- setError('Пожалуйста, введите описание ссылки.');
307
- return;
308
- }
309
- if (!newUrl.trim()) {
310
- setError('Пожалуйста, введите URL ссылки.');
311
- return;
312
- }
313
- if (!isValidUrl(newUrl.trim())) {
314
- setError('Пожалуйста, введите корректный URL (например, https://example.com).');
315
- return;
316
- }
317
-
318
-
319
- const newLink = {
320
- id: Date.now(), // Простой уникальный ID
321
- url: newUrl.trim(),
322
- description: newDescription.trim(),
323
- };
324
-
325
- setLinks([newLink, ...links]); // Добавляем новую ссылку в начало списка
326
- setNewUrl('');
327
- setNewDescription('');
328
- };
329
-
330
- const handleDeleteLink = (idToDelete) => {
331
- setLinks(links.filter(link => link.id !== idToDelete));
332
- };
333
-
334
- return (
335
- <div className="app-container">
336
- <header className="app-header">
337
- <h1>Мои Ссылки</h1>
338
- </header>
339
-
340
- <div className="content-area">
341
- {/* --- Форма добавления --- */}
342
- <div className="ios-section">
343
- <form className="add-form" onSubmit={handleAddLink}>
344
- <input
345
- type="text"
346
- value={newDescription}
347
- onChange={(e) => setNewDescription(e.target.value)}
348
- placeholder="Описание (напр., Документация React)"
349
- aria-label="Описание ссылки"
350
- />
351
- <input
352
- type="url"
353
- value={newUrl}
354
- onChange={(e) => setNewUrl(e.target.value)}
355
- placeholder="URL (напр., https://reactjs.org)"
356
- aria-label="URL ссылки"
357
- />
358
- {error && <p style={{ color: 'var(--ios-system-red)', fontSize: '14px', margin: '-5px 0 5px 0' }}>{error}</p>}
359
- <button type="submit">Добавить ссылку</button>
360
- </form>
361
- </div>
362
-
363
- {/* --- Список ссылок --- */}
364
- <div className="ios-section">
365
- {links.length > 0 ? (
366
- <ul className="link-list">
367
- {links.map(link => (
368
- <li key={link.id} className="link-item">
369
- <div className="link-content">
370
- <div className="link-description">{link.description}</div>
371
- <a
372
- href={link.url}
373
- target="_blank"
374
- rel="noopener noreferrer"
375
- className="link-url"
376
- >
377
- {link.url}
378
- </a>
379
- </div>
380
- <button
381
- onClick={() => handleDeleteLink(link.id)}
382
- className="delete-button"
383
- aria-label={`Удалить ссылку ${link.description}`}
384
- >
385
- × {/* Крестик для удаления */}
386
- </button>
387
- </li>
388
- ))}
389
- </ul>
390
- ) : (
391
- <div className="empty-state">
392
- Нет сохраненных ссылок. Добавьте первую!
393
- </div>
394
- )}
395
- </div>
396
- </div>
397
- </div>
398
- );
399
- }
400
 
401
- // --- Рендер приложения ---
402
- const root = ReactDOM.createRoot(document.getElementById('root'));
403
- root.render(<App />);
404
  </script>
 
405
  </body>
406
  </html>
 
2
  <html lang="ru">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Флагманский Корабль - Babylon.js</title>
 
 
 
 
 
 
7
  <style>
8
+ html, body {
9
+ overflow: hidden;
10
+ width: 100%;
11
+ height: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  margin: 0;
13
+ padding: 0;
14
+ font-family: sans-serif;
15
+ background-color: #000; /* Черный фон для космоса */
16
+ color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
+ #renderCanvas {
20
+ width: 100%;
21
+ height: 100%;
22
+ touch-action: none; /* Важно для сенсорных устройств */
23
+ display: block; /* Убирает лишнее пространство под canvas */
24
  }
25
 
26
+ #info {
27
+ position: absolute;
28
+ top: 10px;
29
+ left: 10px;
30
+ background-color: rgba(0,0,0,0.5);
31
+ padding: 10px;
32
+ border-radius: 5px;
33
+ font-size: 12px;
 
 
 
 
 
34
  }
35
+ </style>
36
+ <!-- Подключаем Babylon.js -->
37
+ <script src="https://cdn.babylonjs.com/babylon.js"></script>
38
+ <!-- Дополнительные библиотеки для удобства (не обязательно, но полезно для сложных фигур) -->
39
+ <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
40
+ <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
41
 
42
+ </head>
43
+ <body>
 
 
 
44
 
45
+ <canvas id="renderCanvas"></canvas>
46
+ <div id="info">ЛКМ + Движение: Вращать камеру | Колесико: Зум</div>
47
+
48
+ <script>
49
+ // Получаем canvas элемент
50
+ const canvas = document.getElementById('renderCanvas');
51
+
52
+ // Создаем движок Babylon.js
53
+ const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
54
+
55
+ // --- Функция создания сцены ---
56
+ const createScene = function () {
57
+ // Создаем сцену
58
+ const scene = new BABYLON.Scene(engine);
59
+ scene.clearColor = new BABYLON.Color3(0.02, 0.02, 0.05); // Темно-синий космос
60
+
61
+ // Создаем камеру - ArcRotateCamera удобна для осмотра объекта
62
+ const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, BABYLON.Vector3.Zero(), scene);
63
+ camera.attachControl(canvas, true);
64
+ camera.lowerRadiusLimit = 5; // Минимальное приближение
65
+ camera.upperRadiusLimit = 50; // Максимальное отдаление
66
+ camera.wheelPrecision = 50; // Чувствительность зума колесиком
67
+
68
+ // Создаем свет
69
+ const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
70
+ light.intensity = 0.8;
71
+ const pointLight = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(5, 10, -5), scene);
72
+ pointLight.intensity = 0.5;
73
+
74
+ // --- Создание модели корабля ---
75
+
76
+ // Создаем пустой "родительский" меш для всего корабля
77
+ // Это упрощает вращение и перемещение всей модели целиком
78
+ const flagship = new BABYLON.Mesh("flagship", scene);
79
+
80
+ // 1. Основной корпус (вытянутая сфера)
81
+ const body = BABYLON.MeshBuilder.CreateSphere("body", { diameterX: 6, diameterY: 1.5, diameterZ: 2 }, scene);
82
+ body.position.y = 0;
83
+ body.parent = flagship; // Делаем корпус дочерним к основному мешу
84
+
85
+ // 2. Кабина пилота (сфера поменьше спереди)
86
+ const cockpit = BABYLON.MeshBuilder.CreateSphere("cockpit", { diameter: 1.2 }, scene);
87
+ cockpit.position.x = 2.8; // Смещаем вперед по X
88
+ cockpit.position.y = 0.2; // Немного приподнимаем
89
+ cockpit.scaling.z = 1.5; // Слегка вытягиваем
90
+ cockpit.parent = flagship;
91
+
92
+ // 3. Крылья (плоские боксы)
93
+ const wingMat = new BABYLON.StandardMaterial("wingMat", scene);
94
+ wingMat.diffuseColor = new BABYLON.Color3(0.6, 0.6, 0.7); // Серый цвет
95
+ wingMat.specularColor = new BABYLON.Color3(0.3, 0.3, 0.3); // Небольшой блик
96
+
97
+ const wingLeft = BABYLON.MeshBuilder.CreateBox("wingLeft", { width: 1.5, height: 0.15, depth: 4 }, scene);
98
+ wingLeft.position = new BABYLON.Vector3(0, 0, -2.2); // Смещаем влево (по Z)
99
+ wingLeft.rotation.y = BABYLON.Tools.ToRadians(15); // Небольшой угол
100
+ wingLeft.parent = flagship;
101
+ wingLeft.material = wingMat;
102
+
103
+ const wingRight = wingLeft.clone("wingRight"); // Клонируем левое крыло
104
+ wingRight.position.z = 2.2; // Смещаем вправо
105
+ wingRight.rotation.y = BABYLON.Tools.ToRadians(-15); // Отражаем угол
106
+ wingRight.parent = flagship;
107
+
108
+ // 4. Двигатели (цилиндры сзади)
109
+ const engineMat = new BABYLON.StandardMaterial("engineMat", scene);
110
+ engineMat.diffuseColor = new BABYLON.Color3(0.3, 0.3, 0.3);
111
+ engineMat.emissiveColor = new BABYLON.Color3(1, 0.5, 0); // Оранжевое свечение!
112
+ engineMat.specularColor = new BABYLON.Color3(0.1, 0.1, 0.1);
113
+
114
+ const engineLeft = BABYLON.MeshBuilder.CreateCylinder("engineLeft", { height: 1.5, diameter: 0.8 }, scene);
115
+ engineLeft.position = new BABYLON.Vector3(-3, 0, -1); // Сзади и слева
116
+ engineLeft.rotation.z = BABYLON.Tools.ToRadians(90); // Поворачиваем горизонтально
117
+ engineLeft.parent = flagship;
118
+ engineLeft.material = engineMat;
119
+
120
+ const engineRight = engineLeft.clone("engineRight");
121
+ engineRight.position.z = 1; // Сзади и справа
122
+ engineRight.parent = flagship;
123
+
124
+ // --- Материалы для основных частей ---
125
+ const bodyMat = new BABYLON.StandardMaterial("bodyMat", scene);
126
+ bodyMat.diffuseColor = new BABYLON.Color3(0.8, 0.85, 0.9); // Светло-серый / Белый
127
+ bodyMat.specularColor = new BABYLON.Color3(0.5, 0.5, 0.5); // Сильный блик - металл
128
+
129
+ const cockpitMat = new BABYLON.StandardMaterial("cockpitMat", scene);
130
+ cockpitMat.diffuseColor = new BABYLON.Color3(0.2, 0.5, 1); // Синий
131
+ cockpitMat.alpha = 0.7; // Полупрозрачность
132
+ cockpitMat.specularColor = new BABYLON.Color3(0.8, 0.8, 1); // Яркий блик
133
+
134
+ body.material = bodyMat;
135
+ cockpit.material = cockpitMat;
136
+
137
+ // --- Анимация ---
138
+ scene.registerBeforeRender(function () {
139
+ // Медленное вращение всего корабля вокруг оси Y
140
+ flagship.rotation.y += 0.005;
141
+
142
+ // Пульсация свечения двигателей (небольшое изменение emissiveColor)
143
+ const pulse = Math.abs(Math.sin(performance.now() * 0.002)); // Значение от 0 до 1
144
+ engineMat.emissiveColor = new BABYLON.Color3(1 * pulse, 0.5 * pulse, 0);
145
+ });
146
 
147
+ // --- Добавим немного "космической пыли" или звезд ---
148
+ const particleSystem = new BABYLON.ParticleSystem("stars", 5000, scene);
149
+ particleSystem.particleTexture = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/flare.png", scene); // Простая текстура для частиц
 
 
 
 
 
150
 
151
+ // Где создавать частицы (большая сфера вокруг)
152
+ particleSystem.emitter = new BABYLON.Vector3(0, 0, 0); // Центр
153
+ particleSystem.minEmitBox = new BABYLON.Vector3(-100, -100, -100);
154
+ particleSystem.maxEmitBox = new BABYLON.Vector3(100, 100, 100);
155
 
156
+ // Цвета частиц
157
+ particleSystem.color1 = new BABYLON.Color4(0.8, 0.8, 1.0, 1.0);
158
+ particleSystem.color2 = new BABYLON.Color4(0.9, 0.9, 1.0, 1.0);
159
+ particleSystem.colorDead = new BABYLON.Color4(0.5, 0.5, 0.5, 0.1);
160
 
161
+ // Размер частиц
162
+ particleSystem.minSize = 0.1;
163
+ particleSystem.maxSize = 0.5;
 
 
 
 
 
 
164
 
165
+ // Время жизни
166
+ particleSystem.minLifeTime = 100; // Долгоживущие, т.к. они статичны
167
+ particleSystem.maxLifeTime = 100;
 
 
 
 
 
 
168
 
169
+ // Скорость эмиссии
170
+ particleSystem.emitRate = 500; // Создаем 500 сразу
 
 
171
 
172
+ // Направление не нужно, т.к. они стоят на месте
173
+ particleSystem.minEmitPower = 0;
174
+ particleSystem.maxEmitPower = 0;
175
+ particleSystem.updateSpeed = 0.01; // Очень медленное обновление
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
+ particleSystem.start();
 
 
 
 
178
 
 
 
 
 
 
 
 
179
 
180
+ return scene;
181
+ };
182
+ // --- Конец функции создания сцены ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
+ // Создаем сцену
185
+ const scene = createScene();
 
 
 
 
 
 
186
 
187
+ // Запускаем цикл рендеринга
188
+ engine.runRenderLoop(function () {
189
+ scene.render();
190
+ });
191
 
192
+ // Обрабатываем изменение размера окна
193
+ window.addEventListener('resize', function () {
194
+ engine.resize();
195
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
 
 
 
197
  </script>
198
+
199
  </body>
200
  </html>