VSPAN commited on
Commit
9cd9b33
·
verified ·
1 Parent(s): 216bc8b

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +413 -518
index.html CHANGED
@@ -2,568 +2,463 @@
2
  <html lang="ru">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>V-SPAN | VSteam Ultimate</title>
 
6
  <style>
7
- /* Глобальные стили */
8
  body {
9
- background: linear-gradient(135deg, #1b2838, #0e1a27);
10
- color: #c6d4df;
11
- font-family: 'Arial', sans-serif;
12
  margin: 0;
13
- min-height: 100vh;
14
- line-height: 1.6;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
-
17
- .container {
18
- max-width: 1200px;
19
- margin: 0 auto;
20
- padding: 20px;
 
 
 
 
 
 
 
 
 
 
21
  }
22
-
23
- /* Навигация */
24
- .nav {
25
- background: rgba(23, 26, 33, 0.9);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  padding: 15px;
27
- margin-bottom: 30px;
28
- display: flex;
29
- gap: 20px;
30
- border-bottom: 2px solid #67c1f5;
31
- backdrop-filter: blur(10px);
32
  border-radius: 10px;
33
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
34
- }
35
-
36
- .nav-button {
37
- background: none;
38
- border: none;
39
- color: #c6d4df;
40
- cursor: pointer;
41
- padding: 10px 20px;
42
- transition: all 0.3s ease;
43
- font-size: 16px;
44
- border-radius: 5px;
45
- }
46
-
47
- .nav-button:hover {
48
- color: #67c1f5;
49
- background: rgba(103, 193, 245, 0.1);
50
- transform: translateY(-2px);
51
  }
52
-
53
- /* Страница входа */
54
- .login-box {
55
- max-width: 400px;
56
- margin: 100px auto;
57
- padding: 40px;
58
- background: rgba(23, 26, 33, 0.9);
59
- border-radius: 15px;
60
- text-align: center;
61
- backdrop-filter: blur(10px);
62
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
63
- border: 1px solid rgba(103, 193, 245, 0.2);
64
  }
65
-
66
- .login-input {
67
- width: 100%;
68
- padding: 12px;
69
- margin: 10px 0;
70
- background: rgba(42, 71, 94, 0.5);
71
- border: 1px solid rgba(103, 193, 245, 0.3);
72
- color: white;
73
- border-radius: 5px;
74
  font-size: 16px;
75
- transition: all 0.3s ease;
76
- }
77
-
78
- .login-input:focus {
79
- border-color: #67c1f5;
80
- box-shadow: 0 0 8px rgba(103, 193, 245, 0.4);
81
- outline: none;
82
- }
83
-
84
- .error-message {
85
- color: #ff4444;
86
- margin: 10px 0;
87
- display: none;
88
- font-size: 14px;
89
- }
90
-
91
- /* Карточки игр */
92
- .store-grid {
93
- display: grid;
94
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
95
- gap: 20px;
96
- margin-top: 30px;
97
- }
98
-
99
- .game-card {
100
- background: rgba(42, 71, 94, 0.7);
101
- border-radius: 10px;
102
- overflow: hidden;
103
- transition: all 0.3s ease;
104
- border: 1px solid transparent;
105
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
106
- }
107
-
108
- .game-card:hover {
109
- border-color: #67c1f5;
110
- transform: translateY(-5px);
111
- box-shadow: 0 8px 25px rgba(103, 193, 245, 0.3);
112
- }
113
-
114
- .game-image {
115
- width: 100%;
116
- height: 150px;
117
- object-fit: cover;
118
- border-bottom: 2px solid rgba(103, 193, 245, 0.2);
119
- }
120
-
121
- .game-card h3 {
122
- margin: 15px;
123
- font-size: 18px;
124
- color: #67c1f5;
125
- }
126
-
127
- .game-card p {
128
- margin: 0 15px 15px;
129
- font-size: 14px;
130
- color: #a8b5c0;
131
  }
132
-
133
- /* Кнопки */
134
- .steam-button {
135
- background: linear-gradient(135deg, #67c1f5, #4da8d3);
136
- color: #1b2838;
137
  border: none;
138
- padding: 12px 25px;
139
- cursor: pointer;
140
- font-weight: bold;
141
  border-radius: 5px;
142
- transition: all 0.3s ease;
143
- margin: 15px;
144
- width: calc(100% - 30px);
145
- box-shadow: 0 4px 15px rgba(103, 193, 245, 0.3);
146
- }
147
-
148
- .steam-button:hover {
149
- transform: translateY(-2px);
150
- box-shadow: 0 6px 20px rgba(103, 193, 245, 0.4);
151
  }
152
-
153
- .steam-button:disabled {
154
- background: #2a475e;
155
- color: #677a8a;
156
- cursor: not-allowed;
157
- box-shadow: none;
158
  }
159
-
160
- /* Профиль */
161
- .profile-header {
162
- display: flex;
163
- align-items: center;
164
- gap: 20px;
165
- margin-bottom: 30px;
166
- background: rgba(23, 26, 33, 0.9);
167
- padding: 20px;
168
- border-radius: 10px;
169
- backdrop-filter: blur(10px);
170
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
171
  }
172
-
173
- .profile-avatar {
174
- width: 150px;
175
- height: 150px;
176
  border-radius: 50%;
177
- border: 3px solid #67c1f5;
178
- box-shadow: 0 4px 15px rgba(103, 193, 245, 0.3);
179
  }
180
-
181
- .profile-name {
182
- font-size: 24px;
183
- font-weight: bold;
184
- color: #67c1f5;
185
- }
186
-
187
- .profile-level {
188
- background: rgba(42, 71, 94, 0.7);
189
- padding: 5px 10px;
190
- border-radius: 5px;
191
- display: inline-block;
192
- margin-top: 5px;
193
- font-size: 14px;
194
- }
195
-
196
- .profile-progress {
197
- background: rgba(23, 26, 33, 0.7);
198
- height: 10px;
199
- border-radius: 5px;
200
- margin: 10px 0;
201
- overflow: hidden;
202
- }
203
-
204
- .profile-progress-bar {
205
- background: linear-gradient(135deg, #67c1f5, #4da8d3);
206
- height: 100%;
207
- width: 30%;
208
- border-radius: 5px;
209
- }
210
-
211
- /* Друзья */
212
- .friends-grid {
213
- display: grid;
214
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
215
- gap: 15px;
216
- margin-top: 20px;
217
- }
218
-
219
- .friend-card {
220
- background: rgba(42, 71, 94, 0.7);
221
  padding: 15px;
222
  border-radius: 10px;
223
- text-align: center;
224
- transition: all 0.3s ease;
225
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
226
- }
227
-
228
- .friend-card:hover {
229
- transform: translateY(-3px);
230
- box-shadow: 0 6px 20px rgba(103, 193, 245, 0.3);
231
- }
232
-
233
- .friend-avatar {
234
- width: 50px;
235
- height: 50px;
236
- border-radius: 50%;
237
- margin-bottom: 10px;
238
- border: 2px solid #67c1f5;
239
- }
240
-
241
- /* Анимации */
242
- @keyframes fadeIn {
243
- from { opacity: 0; transform: translateY(20px); }
244
- to { opacity: 1; transform: translateY(0); }
245
- }
246
-
247
- .fade-in {
248
- animation: fadeIn 0.5s ease-out;
249
  }
250
  </style>
251
  </head>
252
  <body>
253
- <!-- Страница входа -->
254
- <div id="loginPage">
255
- <div class="login-box">
256
- <h2>Вход в VSteam</h2>
257
- <input type="text" id="loginInput" class="login-input" placeholder="Имя">
258
- <input type="password" id="passwordInput" class="login-input" placeholder="Пароль">
259
- <div class="error-message" id="loginError">Неверные данные!</div>
260
- <button class="steam-button" id="loginButton" style="width: 100%">Войти</button>
 
 
 
 
 
261
  </div>
262
- </div>
263
-
264
- <!-- Основной интерфейс -->
265
- <div id="mainPage" style="display: none">
266
- <div class="container">
267
- <!-- Навигация -->
268
- <div class="nav">
269
- <button class="nav-button" onclick="showSection('profile')">Профиль</button>
270
- <button class="nav-button" onclick="showSection('store')">Магазин</button>
271
- <button class="nav-button" onclick="showSection('payment')">Пополнить баланс</button>
272
- <div style="margin-left: auto; display: flex; align-items: center; gap: 10px">
273
- Баланс: <span id="balance">0</span> ₴
274
- </div>
275
- </div>
276
-
277
- <!-- Профиль -->
278
- <div id="profileSection">
279
- <div class="profile-header">
280
- <img src="https://avatars.fastly.steamstatic.com/f5b6269689db341d0d3a7f9574fcc4714b47b055_full.jpg"
281
- alt="Аватар" class="profile-avatar">
282
- <div class="profile-info">
283
- <div class="profile-name">V-SPAN</div>
284
- <div>United States</div>
285
- <div class="profile-level">Уровень 19</div>
286
- <div class="profile-progress">
287
- <div class="profile-progress-bar" style="width: 30%"></div>
288
- </div>
289
- <div>Rookie Miner</div>
290
- <div>100 ед. опыта</div>
291
- <button class="steam-button">Редактировать профиль</button>
292
- </div>
293
- </div>
294
-
295
- <div class="profile-section">
296
- <h2>О себе</h2>
297
- <p>Для знакомых я просто Джонни. 24 Года Не женатый.<br>
298
- Пиши желательно по делу или для обычного приятного разговора.<br>
299
- 𝐃𝐢𝐬𝐜𝐨𝐫𝐝: johnny_raspberry<br>
300
- уʙᴧᴇчᴇния: ᴩиᴄоʙᴀниᴇ, чᴛᴇниᴇ ᴋниᴦ, ᴄоздᴀниᴇ и ᴨᴩодᴀжᴀ ᴋниᴦ<br>
301
- инᴛᴇᴩᴇᴄы ʙ иᴦᴩᴀх: нᴀᴄᴛоᴧьныᴇ ᴩоᴧᴇʙыᴇ иᴦᴩы, оᴄобᴇнно ᴅᴜɴɢᴇᴏɴs ᴀɴᴅ ᴅʀᴀɢᴏɴs (ᴅɴᴅ)</p>
302
- <p>Соси письку, братан. - zakat</p>
303
- </div>
304
-
305
- <div class="profile-section">
306
- <h2>Друзья</h2>
307
- <div class="friends-grid" id="friendsGrid"></div>
308
- </div>
309
-
310
- <div class="profile-section">
311
- <h2>Библиотека игр</h2>
312
- <div id="userGames"></div>
313
- </div>
314
- </div>
315
-
316
- <!-- Магазин -->
317
- <div id="storeSection" style="display: none">
318
- <h2>Магазин ВSteam</h2>
319
- <div class="store-grid" id="storeGrid"></div>
320
- </div>
321
-
322
- <!-- Пополнение баланса -->
323
- <div id="paymentSection" style="display: none">
324
- <div class="payment-box">
325
- <h2 style="text-align: center">Пополнение баланса</h2>
326
- <input type="number" class="payment-input" id="amount" placeholder="Сумма в гривнах">
327
- <button class="steam-button" style="width: 100%" id="addFundsButton">
328
- Мгновенное пополнение ✨
329
- </button>
330
- <div style="text-align: center; margin-top: 15px; color: #888">
331
- (Функция в бета-тесте — деньги не списываются)
332
- </div>
333
- </div>
334
- </div>
335
  </div>
336
  </div>
337
 
338
  <script>
339
- // Данные аккаунта
340
- const account = {
341
- login: 'V-SPAN',
342
- password: '11.08.2024 1:53',
343
- balance: 305,
344
- library: [],
345
- level: 19,
346
- experience: 301,
347
- friends: [
348
- { name: 'Aristople', status: сети: 7 ч., 9 мин. назад' },
349
- { name: 'Rock MeN', status: 'В сети: 14 дн. назад' },
350
- { name: 'Zakati', status: 'В сети' }
351
- ]
352
- }
353
-
354
- // Игры в магазине
355
- const games = [
356
- { id: 1, title: 'Dota 3', price: 499, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/570/header.jpg' },
357
- { id: 2, title: 'CS:GO Ultimate', price: 799, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/730/header.jpg' },
358
- { id: 3, title: 'The Witcher 4: Wild Dream', price: 1299, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/292030/header.jpg' },
359
- { id: 4, title: 'Cyberpunk 2078', price: 1599, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/header.jpg' },
360
- { id: 5, title: 'Elden Ring: Shadow of the Moon', price: 1799, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/header.jpg' },
361
- { id: 6, title: 'Starfield: Galactic Empire', price: 1999, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/1716740/header.jpg' },
362
- { id: 7, title: 'Baldur\'s Gate 4', price: 1499, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/1086940/header.jpg' },
363
- { id: 8, title: 'Half-Life 3', price: 999, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/220/header.jpg' },
364
- { id: 9, title: 'Portal 3', price: 899, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/400/header.jpg' },
365
- { id: 10, title: 'GTA VI', price: 2499, image: 'https://cdn.cloudflare.steamstatic.com/steam/apps/271590/header.jpg' }
366
- ]
367
-
368
- // Инициализация приложения
369
- function init() {
370
- document.getElementById('loginButton').addEventListener('click', login)
371
- document.getElementById('addFundsButton').addEventListener('click', addFunds)
372
- }
373
-
374
- // Система входа
375
- function login() {
376
- const login = document.getElementById('loginInput').value
377
- const password = document.getElementById('passwordInput').value
378
-
379
- if(login === account.login && password === account.password) {
380
- document.getElementById('loginPage').style.display = 'none'
381
- document.getElementById('mainPage').style.display = 'block'
382
- initApp()
383
- } else {
384
- document.getElementById('loginError').style.display = 'block'
385
  }
386
- }
387
-
388
- // Инициализация приложения после входа
389
- function initApp() {
390
- updateBalance()
391
- renderStore()
392
- renderLibrary()
393
- renderFriends()
394
- document.getElementById('amount').value = 500
395
- showSection('profile')
396
- }
397
-
398
- // Обновление баланса
399
- function updateBalance() {
400
- const balanceElement = document.getElementById('balance')
401
- if(balanceElement) {
402
- balanceElement.textContent = account.balance
403
  }
404
  }
405
 
406
- // Отрисовка магазина
407
- function renderStore() {
408
- const storeGrid = document.getElementById('storeGrid')
409
- if(storeGrid) {
410
- storeGrid.innerHTML = games.map(game => `
411
- <div class="game-card" ${account.library.some(g => g.id === game.id) ? 'data-owned="true"' : ''}>
412
- <img src="${game.image}" class="game-image">
413
- <div style="padding: 15px">
414
- <h3>${game.title}</h3>
415
- <div style="margin: 15px 0; color: #67c1f5">${game.price} ₴</div>
416
- <button class="steam-button"
417
- onclick="buyGame(${game.id})"
418
- ${account.library.some(g => g.id === game.id) ? 'disabled' : ''}>
419
- ${account.library.some(g => g.id === game.id) ? 'В библиотеке' : 'Купить'}
420
- </button>
421
- </div>
422
- </div>
423
- `).join('')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
  }
425
- }
426
-
427
- // Отрисовка библиотеки
428
- function renderLibrary() {
429
- const library = document.getElementById('userGames')
430
- if(library) {
431
- library.innerHTML = account.library.length ?
432
- account.library.map(game => `
433
- <div class="game-card">
434
- <img src="${game.image}" class="game-image">
435
- <div style="padding: 15px">
436
- <h3>${game.title}</h3>
437
- <button class="steam-button" disabled>Установить</button>
438
- </div>
439
- </div>
440
- `).join('') :
441
- '<p>Ваша библиотека пуста. Купите игры в магазине!</p>'
442
  }
443
- }
444
-
445
- // Отрисовка друзей
446
- function renderFriends() {
447
- const friendsGrid = document.getElementById('friendsGrid')
448
- if(friendsGrid) {
449
- friendsGrid.innerHTML = account.friends.map(friend => `
450
- <div class="friend-card">
451
- <div>${friend.name}</div>
452
- <div class="friend-status">${friend.status}</div>
453
- </div>
454
- `).join('')
455
  }
456
- }
457
-
458
- // Покупка игры
459
- function buyGame(gameId) {
460
- const game = games.find(g => g.id === gameId)
461
- if(!game) return alert('Игра не найдена!')
462
-
463
- if(account.balance >= game.price) {
464
- account.balance -= game.price
465
- account.library.push(game)
466
- updateBalance()
467
- renderStore()
468
- renderLibrary()
469
- alert(`🎉 Вы купили "${game.title}"!`)
470
- } else {
471
- alert('🚫 Недостаточно средств!')
472
  }
473
- }
474
-
475
- // Пополнение баланса
476
- function addFunds() {
477
- const amount = Number(document.getElementById('amount').value)
478
- if(amount > 0 && amount <= 10000) {
479
- account.balance += amount
480
- updateBalance()
481
- alert(`✅ Баланс пополнен на ${amount} ₴!`)
482
- } else {
483
- alert('⚠ Введите сумму от 1 до 10 000 гривен')
484
  }
485
- }
486
-
487
- // Переключение разделов
488
- function showSection(section) {
489
- document.querySelectorAll('[id$="Section"]').forEach(el => el.style.display = 'none')
490
- const sectionElement = document.getElementById(section + 'Section')
491
- if(sectionElement) {
492
- sectionElement.style.display = 'block'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  }
494
- if(section === 'store') renderStore()
495
- if(section === 'profile') renderLibrary()
496
- }
497
-
498
- // Инициализация при загрузке страницы
499
- window.addEventListener('load', init)
500
- </script>
501
- <script>
502
- // Функция для "игры" — открывает видео в новой вкладке
503
- function playGame(gameId) {
504
- window.open('https://www.youtube.com/watch?v=dQw4w9WgXcQ', '_blank');
505
- }
506
-
507
- // Функция для "установки" игры с улучшениями
508
- function installGame(gameId) {
509
- try {
510
- const game = games.find(g => g.id === gameId);
511
- if (!game) throw new Error('Игра не найдена');
512
-
513
- const installButton = document.querySelector(`.install-button[data-game-id="${gameId}"]`);
514
- const progressBar = document.querySelector(`.install-progress[data-game-id="${gameId}"] .install-progress-bar`);
515
- const message = document.querySelector(`.install-message[data-game-id="${gameId}"]`);
516
-
517
- if (installButton && progressBar && message) {
518
- installButton.disabled = true;
519
- installButton.textContent = 'Установка...';
520
- progressBar.parentElement.style.display = 'block';
521
- message.style.display = 'block';
522
- progressBar.style.transition = 'width 0.3s ease';
523
-
524
- let progress = 0;
525
- function updateProgress() {
526
- progress += 5;
527
- progressBar.style.width = `${progress}%`;
528
- if (progress < 100) {
529
- requestAnimationFrame(updateProgress);
530
  } else {
531
- installButton.textContent = 'Играть';
532
- installButton.onclick = () => playGame(gameId);
533
- message.textContent = 'Игра успешно установлена!';
534
- installButton.disabled = false;
535
  }
 
 
 
 
536
  }
537
- requestAnimationFrame(updateProgress);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
  }
539
- } catch (error) {
540
- console.error('Ошибка установки:', error.message);
541
  }
542
- }
543
-
544
- // Отрисовка библиотеки с кнопкой установки или игры
545
- function renderLibrary() {
546
- const library = document.getElementById('userGames');
547
- if (library) {
548
- library.innerHTML = account.library.length ?
549
- account.library.map(game => `
550
- <div class="game-card">
551
- <img src="${game.image}" class="game-image">
552
- <div style="padding: 15px">
553
- <h3>${game.title}</h3>
554
- <button class="steam-button install-button" data-game-id="${game.id}" onclick="${game.installed ? `playGame(${game.id})` : `installGame(${game.id})`}">
555
- ${game.installed ? 'Играть' : 'Установить'}
556
- </button>
557
- <div class="install-progress" data-game-id="${game.id}">
558
- <div class="install-progress-bar"></div>
559
- </div>
560
- <div class="install-message" data-game-id="${game.id}"></div>
561
- </div>
562
- </div>
563
- `).join('') :
564
- '<p>Ваша библиотека пуста. Купите игры в магазине!</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  }
566
- }
567
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  </body>
569
  </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>Изменение времени по голосу</title>
7
  <style>
 
8
  body {
 
 
 
9
  margin: 0;
10
+ overflow: hidden;
11
+ font-family: Arial, sans-serif;
12
+ }
13
+ #game-container {
14
+ position: relative;
15
+ width: 100vw;
16
+ height: 100vh;
17
+ transition: background-color 0.5s ease;
18
+ }
19
+ #sky {
20
+ position: absolute;
21
+ top: 0;
22
+ left: 0;
23
+ width: 100%;
24
+ height: 70%;
25
+ transition: background-color 0.5s ease;
26
  }
27
+ #ground {
28
+ position: absolute;
29
+ bottom: 0;
30
+ left: 0;
31
+ width: 100%;
32
+ height: 30%;
33
+ background-color: #4a7c59;
34
+ transition: background-color 0.5s ease;
35
+ }
36
+ #sun-moon {
37
+ position: absolute;
38
+ width: 80px;
39
+ height: 80px;
40
+ border-radius: 50%;
41
+ transition: all 0.5s ease;
42
  }
43
+ #buildings {
44
+ position: absolute;
45
+ bottom: 30%;
46
+ left: 0;
47
+ width: 100%;
48
+ height: 20%;
49
+ }
50
+ .building {
51
+ position: absolute;
52
+ bottom: 0;
53
+ background-color: #555;
54
+ transition: background-color 0.5s ease;
55
+ }
56
+ .window {
57
+ position: absolute;
58
+ background-color: #333;
59
+ transition: background-color 0.5s ease;
60
+ }
61
+ #controls {
62
+ position: absolute;
63
+ top: 20px;
64
+ left: 20px;
65
+ background-color: rgba(255, 255, 255, 0.8);
66
  padding: 15px;
 
 
 
 
 
67
  border-radius: 10px;
68
+ z-index: 100;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
+ #time-display {
71
+ font-size: 24px;
72
+ font-weight: bold;
73
+ margin-bottom: 10px;
 
 
 
 
 
 
 
 
74
  }
75
+ #pitch-display, #volume-display {
 
 
 
 
 
 
 
 
76
  font-size: 16px;
77
+ margin-bottom: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
+ button {
80
+ padding: 10px 15px;
81
+ margin-right: 5px;
82
+ background-color: #4CAF50;
83
+ color: white;
84
  border: none;
 
 
 
85
  border-radius: 5px;
86
+ cursor: pointer;
 
 
 
 
 
 
 
 
87
  }
88
+ button:hover {
89
+ background-color: #45a049;
 
 
 
 
90
  }
91
+ #stars {
92
+ position: absolute;
93
+ top: 0;
94
+ left: 0;
95
+ width: 100%;
96
+ height: 70%;
97
+ transition: opacity 0.5s ease;
98
+ opacity: 0;
 
 
 
 
99
  }
100
+ .star {
101
+ position: absolute;
102
+ background-color: white;
 
103
  border-radius: 50%;
 
 
104
  }
105
+ #instructions {
106
+ position: absolute;
107
+ bottom: 20px;
108
+ left: 20px;
109
+ background-color: rgba(255, 255, 255, 0.8);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  padding: 15px;
111
  border-radius: 10px;
112
+ max-width: 300px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
  </style>
115
  </head>
116
  <body>
117
+ <div id="game-container">
118
+ <div id="sky"></div>
119
+ <div id="stars"></div>
120
+ <div id="sun-moon"></div>
121
+ <div id="buildings"></div>
122
+ <div id="ground"></div>
123
+
124
+ <div id="controls">
125
+ <div id="time-display">12:00</div>
126
+ <div id="pitch-display">Тембр: 0</div>
127
+ <div id="volume-display">Громкость: 0</div>
128
+ <button id="start-btn">Начать запись голоса</button>
129
+ <button id="stop-btn" disabled>Остановить</button>
130
  </div>
131
+
132
+ <div id="instructions">
133
+ <h3>Инструкция:</h3>
134
+ <p>1. Нажмите "Начать запись голоса" и разрешите доступ к микрофону</p>
135
+ <p>2. Говорите с разным тембром голоса:</p>
136
+ <p>- Низкий тембр = ночь/раннее утро</p>
137
+ <p>- Средний тембр = день</p>
138
+ <p>- Высокий тембр = вечер/закат</p>
139
+ <p>3. Громкость голоса влияет на яркость сцены</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  </div>
141
  </div>
142
 
143
  <script>
144
+ // Создаем элементы сцены
145
+ function setupScene() {
146
+ // Создаем здания
147
+ const buildingsContainer = document.getElementById('buildings');
148
+ const buildingCount = 8;
149
+ for (let i = 0; i < buildingCount; i++) {
150
+ const building = document.createElement('div');
151
+ building.classList.add('building');
152
+ const height = 50 + Math.random() * 100;
153
+ const width = 40 + Math.random() * 60;
154
+ building.style.height = height + 'px';
155
+ building.style.width = width + 'px';
156
+ building.style.left = (i * (100 / buildingCount)) + '%';
157
+
158
+ // Добавляем окна
159
+ const windowRows = Math.floor(height / 20);
160
+ const windowCols = Math.floor(width / 15);
161
+ for (let r = 0; r < windowRows; r++) {
162
+ for (let c = 0; c < windowCols; c++) {
163
+ const windowEl = document.createElement('div');
164
+ windowEl.classList.add('window');
165
+ windowEl.style.width = '10px';
166
+ windowEl.style.height = '15px';
167
+ windowEl.style.left = (c * 15 + 5) + 'px';
168
+ windowEl.style.top = (r * 20 + 5) + 'px';
169
+ building.appendChild(windowEl);
170
+ }
171
+ }
172
+
173
+ buildingsContainer.appendChild(building);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
+
176
+ // Создаем звезды
177
+ const starsContainer = document.getElementById('stars');
178
+ for (let i = 0; i < 100; i++) {
179
+ const star = document.createElement('div');
180
+ star.classList.add('star');
181
+ const size = 1 + Math.random() * 2;
182
+ star.style.width = size + 'px';
183
+ star.style.height = size + 'px';
184
+ star.style.left = Math.random() * 100 + '%';
185
+ star.style.top = Math.random() * 100 + '%';
186
+ starsContainer.appendChild(star);
 
 
 
 
 
187
  }
188
  }
189
 
190
+ // Изменение времени суток
191
+ function updateTimeOfDay(hour, minute, pitch, volume) {
192
+ const gameContainer = document.getElementById('game-container');
193
+ const sky = document.getElementById('sky');
194
+ const ground = document.getElementById('ground');
195
+ const sunMoon = document.getElementById('sun-moon');
196
+ const buildings = document.querySelectorAll('.building');
197
+ const windows = document.querySelectorAll('.window');
198
+ const stars = document.getElementById('stars');
199
+
200
+ // Нормализуем время (0-24)
201
+ const time = hour + minute / 60;
202
+
203
+ // Положение солнца/луны
204
+ const angle = (time / 24) * 2 * Math.PI - Math.PI / 2;
205
+ const radius = Math.min(window.innerWidth, window.innerHeight) * 0.4;
206
+ const centerX = window.innerWidth / 2;
207
+ const centerY = window.innerHeight * 0.7;
208
+ const x = centerX + radius * Math.cos(angle);
209
+ const y = centerY + radius * Math.sin(angle);
210
+
211
+ sunMoon.style.left = (x - 40) + 'px';
212
+ sunMoon.style.top = (y - 40) + 'px';
213
+
214
+ // Цвета в зависимости от времени суток
215
+ let skyColor, groundColor, sunMoonColor, buildingColor, windowColor;
216
+ let starsOpacity = 0;
217
+
218
+ // Раннее утро (5-7)
219
+ if (time >= 5 && time < 7) {
220
+ skyColor = `rgb(${Math.floor(59 + (158-59) * (time-5)/2)}, ${Math.floor(88 + (206-88) * (time-5)/2)}, ${Math.floor(128 + (235-128) * (time-5)/2)})`;
221
+ groundColor = '#385c46';
222
+ sunMoonColor = '#ff9e4f';
223
+ buildingColor = '#555';
224
+ windowColor = '#333';
225
  }
226
+ // День (7-17)
227
+ else if (time >= 7 && time < 17) {
228
+ skyColor = '#9eceff';
229
+ groundColor = '#4a7c59';
230
+ sunMoonColor = '#ffee00';
231
+ buildingColor = '#666';
232
+ windowColor = '#444';
 
 
 
 
 
 
 
 
 
 
233
  }
234
+ // Закат (17-19)
235
+ else if (time >= 17 && time < 19) {
236
+ const factor = (time - 17) / 2;
237
+ skyColor = `rgb(${Math.floor(158 + (255-158) * factor)}, ${Math.floor(206 + (107-206) * factor)}, ${Math.floor(235 + (62-235) * factor)})`;
238
+ groundColor = '#3d5d49';
239
+ sunMoonColor = '#ff6700';
240
+ buildingColor = '#555';
241
+ windowColor = '#b3721f';
 
 
 
 
242
  }
243
+ // Вечер (19-21)
244
+ else if (time >= 19 && time < 21) {
245
+ const factor = (time - 19) / 2;
246
+ skyColor = `rgb(${Math.floor(255 - (255-20) * factor)}, ${Math.floor(107 - (107-42) * factor)}, ${Math.floor(62 - (62-87) * factor)})`;
247
+ groundColor = '#2e463a';
248
+ sunMoonColor = `rgb(${Math.floor(255 - 200 * factor)}, ${Math.floor(103 - 43 * factor)}, ${Math.floor(0 + 230 * factor)})`;
249
+ buildingColor = '#444';
250
+ windowColor = '#ffdb70';
251
+ starsOpacity = factor;
 
 
 
 
 
 
 
252
  }
253
+ // Ночь (21-5)
254
+ else {
255
+ skyColor = '#14283b';
256
+ groundColor = '#1e2e26';
257
+ sunMoonColor = '#e0e0e0';
258
+ buildingColor = '#333';
259
+ windowColor = '#ffdb70';
260
+ starsOpacity = 1;
 
 
 
261
  }
262
+
263
+ // Применяем цвета с учетом громкости (яркости)
264
+ const brightnessMultiplier = 0.7 + volume * 0.3;
265
+
266
+ // Функция для увеличения яркости цвета
267
+ function adjustBrightness(hexOrRgb, multiplier) {
268
+ // Для RGB формата
269
+ if (hexOrRgb.startsWith('rgb')) {
270
+ const rgbValues = hexOrRgb.match(/\d+/g).map(Number);
271
+ return `rgb(${Math.min(255, Math.floor(rgbValues[0] * multiplier))}, ${Math.min(255, Math.floor(rgbValues[1] * multiplier))}, ${Math.min(255, Math.floor(rgbValues[2] * multiplier))})`;
272
+ }
273
+
274
+ // Для HEX формата
275
+ const hex = hexOrRgb.replace('#', '');
276
+ let r = parseInt(hex.substring(0, 2), 16);
277
+ let g = parseInt(hex.substring(2, 4), 16);
278
+ let b = parseInt(hex.substring(4, 6), 16);
279
+
280
+ r = Math.min(255, Math.floor(r * multiplier));
281
+ g = Math.min(255, Math.floor(g * multiplier));
282
+ b = Math.min(255, Math.floor(b * multiplier));
283
+
284
+ return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
285
  }
286
+
287
+ // Применяем подстроенные цвета
288
+ sky.style.backgroundColor = skyColor;
289
+ ground.style.backgroundColor = adjustBrightness(groundColor, brightnessMultiplier);
290
+ sunMoon.style.backgroundColor = adjustBrightness(sunMoonColor, brightnessMultiplier);
291
+
292
+ buildings.forEach(building => {
293
+ building.style.backgroundColor = adjustBrightness(buildingColor, brightnessMultiplier);
294
+ });
295
+
296
+ windows.forEach(window => {
297
+ // Ночью окна горят
298
+ if (time >= 19 || time < 7) {
299
+ // Случайно определяем, горит ли окно
300
+ if (window.dataset.lit === undefined) {
301
+ window.dataset.lit = Math.random() > 0.3 ? 'true' : 'false';
302
+ }
303
+ if (window.dataset.lit === 'true') {
304
+ window.style.backgroundColor = adjustBrightness(windowColor, brightnessMultiplier);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  } else {
306
+ window.style.backgroundColor = '#333';
 
 
 
307
  }
308
+ } else {
309
+ // Днем окна темные
310
+ window.style.backgroundColor = '#444';
311
+ delete window.dataset.lit;
312
  }
313
+ });
314
+
315
+ stars.style.opacity = starsOpacity;
316
+ }
317
+
318
+ // Обработка аудио
319
+ let audioContext;
320
+ let analyser;
321
+ let microphone;
322
+ let javascriptNode;
323
+ let hours = 12;
324
+ let minutes = 0;
325
+ let lastPitch = 0;
326
+ let lastVolume = 0;
327
+
328
+ function startAudioProcessing() {
329
+ const startBtn = document.getElementById('start-btn');
330
+ const stopBtn = document.getElementById('stop-btn');
331
+
332
+ startBtn.disabled = true;
333
+ stopBtn.disabled = false;
334
+
335
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
336
+ analyser = audioContext.createAnalyser();
337
+ analyser.fftSize = 2048;
338
+
339
+ // Запрашиваем доступ к микрофону
340
+ navigator.mediaDevices.getUserMedia({ audio: true })
341
+ .then(function(stream) {
342
+ microphone = audioContext.createMediaStreamSource(stream);
343
+ microphone.connect(analyser);
344
+
345
+ // Создаем обработчик для анализа звука
346
+ javascriptNode = audioContext.createScriptProcessor(2048, 1, 1);
347
+ analyser.connect(javascriptNode);
348
+ javascriptNode.connect(audioContext.destination);
349
+
350
+ // Устанавливаем обработчик для анализа звука
351
+ javascriptNode.onaudioprocess = processAudio;
352
+ })
353
+ .catch(function(err) {
354
+ console.error('Ошибка доступа к микрофону:', err);
355
+ alert('Не удалось получить доступ к микрофону. Проверьте настройки браузера.');
356
+ startBtn.disabled = false;
357
+ stopBtn.disabled = true;
358
+ });
359
+ }
360
+
361
+ function stopAudioProcessing() {
362
+ const startBtn = document.getElementById('start-btn');
363
+ const stopBtn = document.getElementById('stop-btn');
364
+
365
+ startBtn.disabled = false;
366
+ stopBtn.disabled = true;
367
+
368
+ if (javascriptNode) {
369
+ javascriptNode.onaudioprocess = null;
370
+ javascriptNode.disconnect();
371
+ }
372
+
373
+ if (microphone) {
374
+ microphone.disconnect();
375
+ }
376
+
377
+ if (analyser) {
378
+ analyser.disconnect();
379
+ }
380
+
381
+ if (audioContext) {
382
+ audioContext.close();
383
  }
 
 
384
  }
385
+
386
+ function processAudio(event) {
387
+ const bufferLength = analyser.frequencyBinCount;
388
+ const dataArray = new Uint8Array(bufferLength);
389
+ analyser.getByteFrequencyData(dataArray);
390
+
391
+ // Вычисляем среднюю частоту (тембр)
392
+ let sum = 0;
393
+ let count = 0;
394
+
395
+ // Используем только значимую часть спектра
396
+ for (let i = 5; i < bufferLength / 4; i++) {
397
+ if (dataArray[i] > 10) { // Игнорируем шум
398
+ sum += i * dataArray[i];
399
+ count += dataArray[i];
400
+ }
401
+ }
402
+
403
+ // Вычисляем среднюю громкость
404
+ let volumeSum = 0;
405
+ for (let i = 0; i < bufferLength; i++) {
406
+ volumeSum += dataArray[i];
407
+ }
408
+ let volumeAvg = volumeSum / bufferLength / 255;
409
+
410
+ if (count > 0) {
411
+ const normalizedPitch = sum / count / (bufferLength / 8);
412
+
413
+ // Сглаживаем значения для более плавного перехода
414
+ lastPitch = lastPitch * 0.7 + normalizedPitch * 0.3;
415
+ lastVolume = lastVolume * 0.7 + volumeAvg * 0.3;
416
+
417
+ // Обновляем отображение текущих значений
418
+ document.getElementById('pitch-display').textContent = `Тембр: ${lastPitch.toFixed(2)}`;
419
+ document.getElementById('volume-display').textContent = `Громкость: ${lastVolume.toFixed(2)}`;
420
+
421
+ // Меняем время суток в зависимости от тембра
422
+ hours = Math.floor(lastPitch * 24);
423
+ minutes = Math.floor((lastPitch * 24 - hours) * 60);
424
+
425
+ // Обновляем отображение времени
426
+ document.getElementById('time-display').textContent =
427
+ `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
428
+
429
+ // Обновляем сцену
430
+ updateTimeOfDay(hours, minutes, lastPitch, lastVolume);
431
+ }
432
  }
433
+
434
+ // Инициализация
435
+ window.onload = function() {
436
+ setupScene();
437
+ updateTimeOfDay(hours, minutes, 0.5, 0.5);
438
+
439
+ // Устанавливаем обработчики событий для кнопок
440
+ document.getElementById('start-btn').addEventListener('click', startAudioProcessing);
441
+ document.getElementById('stop-btn').addEventListener('click', stopAudioProcessing);
442
+
443
+ // Устанавливаем интервал для обновления времени даже без звука
444
+ setInterval(function() {
445
+ if (!audioContext) {
446
+ minutes++;
447
+ if (minutes >= 60) {
448
+ minutes = 0;
449
+ hours++;
450
+ if (hours >= 24) {
451
+ hours = 0;
452
+ }
453
+ }
454
+
455
+ document.getElementById('time-display').textContent =
456
+ `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
457
+
458
+ updateTimeOfDay(hours, minutes, hours / 24, 0.5);
459
+ }
460
+ }, 1000);
461
+ };
462
+ </script>
463
  </body>
464
  </html>