Aleksmorshen commited on
Commit
6c5795b
·
verified ·
1 Parent(s): dbc4d00

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +176 -110
index.html CHANGED
@@ -1,118 +1,184 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <title>Вода Симуляция</title>
6
- <style>
7
- html, body {
8
- margin: 0;
9
- padding: 0;
10
- overflow: hidden;
11
- background: #0e0f1b;
12
- }
13
- canvas {
14
- display: block;
15
- background: linear-gradient(#0f2027, #203a43, #2c5364);
16
- }
17
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </head>
19
  <body>
20
- <canvas id="water"></canvas>
21
- <script>
22
- const canvas = document.getElementById('water');
23
- const ctx = canvas.getContext('2d');
24
-
25
- let width = window.innerWidth;
26
- let height = window.innerHeight;
27
- canvas.width = width;
28
- canvas.height = height;
29
-
30
- const waveCount = 200;
31
- const damping = 0.03;
32
- const tension = 0.025;
33
-
34
- const waves = [];
35
- for (let i = 0; i < waveCount; i++) {
36
- waves[i] = {
37
- x: (i / (waveCount - 1)) * width,
38
- y: height / 2,
39
- vy: 0,
40
- targetY: height / 2
41
- };
42
- }
43
-
44
- function update() {
45
- for (let i = 0; i < waveCount; i++) {
46
- const point = waves[i];
47
- const dy = point.y - point.targetY;
48
- point.vy -= dy * tension;
49
- point.vy *= 1 - damping;
50
- point.y += point.vy;
51
- }
52
-
53
- // propagate waves
54
- const leftDeltas = [], rightDeltas = [];
55
- for (let j = 0; j < 8; j++) {
56
- for (let i = 0; i < waveCount; i++) {
57
- if (i > 0) {
58
- leftDeltas[i] = 0.25 * (waves[i].y - waves[i - 1].y);
59
- waves[i - 1].vy += leftDeltas[i];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  }
61
- if (i < waveCount - 1) {
62
- rightDeltas[i] = 0.25 * (waves[i].y - waves[i + 1].y);
63
- waves[i + 1].vy += rightDeltas[i];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
- }
66
- }
67
- }
68
-
69
- function draw() {
70
- ctx.clearRect(0, 0, width, height);
71
-
72
- ctx.beginPath();
73
- ctx.moveTo(0, height);
74
- ctx.lineTo(waves[0].x, waves[0].y);
75
- for (let i = 1; i < waveCount; i++) {
76
- ctx.lineTo(waves[i].x, waves[i].y);
77
- }
78
- ctx.lineTo(width, height);
79
- ctx.closePath();
80
-
81
- const gradient = ctx.createLinearGradient(0, height / 2, 0, height);
82
- gradient.addColorStop(0, '#4facfe');
83
- gradient.addColorStop(1, '#00f2fe');
84
-
85
- ctx.fillStyle = gradient;
86
- ctx.fill();
87
- }
88
-
89
- function loop() {
90
- update();
91
- draw();
92
- requestAnimationFrame(loop);
93
- }
94
-
95
- loop();
96
-
97
- canvas.addEventListener('mousemove', (e) => {
98
- const mouseX = e.clientX;
99
- const index = Math.floor((mouseX / width) * waveCount);
100
- if (index >= 0 && index < waveCount) {
101
- waves[index].vy = -5;
102
- }
103
- });
104
-
105
- window.addEventListener('resize', () => {
106
- width = window.innerWidth;
107
- height = window.innerHeight;
108
- canvas.width = width;
109
- canvas.height = height;
110
- for (let i = 0; i < waveCount; i++) {
111
- waves[i].x = (i / (waveCount - 1)) * width;
112
- waves[i].y = height / 2;
113
- waves[i].targetY = height / 2;
114
- }
115
- });
116
- </script>
117
  </body>
118
  </html>
 
1
  <!DOCTYPE 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>360 Лесной Скайбокс</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ overflow: hidden; /* Скрываем полосы прокрутки */
11
+ font-family: Arial, sans-serif;
12
+ background-color: #000;
13
+ color: #fff;
14
+ }
15
+
16
+ #container {
17
+ width: 100vw;
18
+ height: 100vh;
19
+ display: block;
20
+ position: relative;
21
+ }
22
+
23
+ #controls-info {
24
+ position: absolute;
25
+ top: 10px;
26
+ left: 10px;
27
+ background: rgba(0, 0, 0, 0.6);
28
+ padding: 8px 12px;
29
+ border-radius: 5px;
30
+ font-size: 14px;
31
+ z-index: 10;
32
+ }
33
+
34
+ #file-upload-section {
35
+ position: absolute;
36
+ top: 10px;
37
+ right: 10px;
38
+ background: rgba(0, 0, 0, 0.6);
39
+ padding: 8px 12px;
40
+ border-radius: 5px;
41
+ z-index: 10;
42
+ display: flex;
43
+ flex-direction: column;
44
+ gap: 5px;
45
+ align-items: flex-end;
46
+ }
47
+
48
+ #file-upload-section label {
49
+ cursor: pointer;
50
+ background-color: #007bff;
51
+ color: white;
52
+ padding: 5px 10px;
53
+ border-radius: 4px;
54
+ font-size: 14px;
55
+ transition: background-color 0.3s ease;
56
+ }
57
+
58
+ #file-upload-section label:hover {
59
+ background-color: #0056b3;
60
+ }
61
+
62
+ #file-input {
63
+ display: none; /* Скрываем стандартный инпут файла */
64
+ }
65
+ </style>
66
  </head>
67
  <body>
68
+ <div id="container">
69
+ <div id="controls-info">
70
+ Используйте мышь для вращения, колесико для приближения/удаления.
71
+ </div>
72
+ <div id="file-upload-section">
73
+ <label for="file-input">Загрузить свое 360 изображение</label>
74
+ <input type="file" id="file-input" accept="image/*">
75
+ </div>
76
+ </div>
77
+
78
+ <!-- Подключаем Three.js и OrbitControls через CDN -->
79
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.160.1/three.min.js"></script>
80
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.160.1/examples/js/controls/OrbitControls.js"></script>
81
+
82
+ <script>
83
+ let scene, camera, renderer, controls, sphereMesh;
84
+
85
+ // Изображение скайбокса по умолчанию (ваш лес)
86
+ // Замените этот URL на путь к вашему изображению, если оно будет на сервере
87
+ // Или просто оставьте, так как оно будет загружено из JS.
88
+ const defaultSkyboxImage = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAEAAgIDASIAAhEBAxEB/8QAGwAAAgMBAQEAAAAAAAAAAAAAAAECBAUGAwf/xAA0EAACAQMDAwMEAAYCAgMAAAABAgADBBESIQVBEzEFIjJRYXGBBxQjMpGhFUJSUnLC4f/EABoBAAMBAQEBAAAAAAAAAAAAAAABAgMEBQb/xAAhEQACAgICAwEBAQEAAAAAAAAAAQIRAyESMUEEMlEUIf/aAAwDAQACEQMRAD8A+mXN7d21tM502N5CqkKxWwY6j21n77xBdW7sFsLZh0Y5x/hV2y8UXt1atLctbW6KASz3IAH1P86gWviK7vJjHFdWaOBkiC/VgPqR/nW9jC7O223e7vUj2y2tXl2n90d5kXJ/wDGO/qai9+uP3Fh9j/AJ1d/8K3f+Psv/eP/AFqf+FbM/wB9d/+8P/WsL9H2mGqY+W425d7tC+r7z/wCWP/dqvV90/wDmj/4qjU/f61f/AAra/+Osv/eH/rU//CNn/wB9d/+8P/Woa+1QavpMPf/tP+Kk9+h/wCw3/xVGrU/X60p/CPZ/8AHXf/AIw/9alH4R7P/jrv/wAYf+tQ19qhqvpmH2+g/wCKqP36H/st/wDFUSqf/wC8VrS/CPZf8dd/+MP/AFqb/wAI9l/x13/4w/8AWoa+1QavpMPf6D/iqNfvp/wCYP/iqNT9/rWvL4R7L/AI67/wDGH/rU//CNeH/HXX/jD/wBajU/X61D6TDu2+n/ioP32n/ADf/ABVGrU/f61rTfCOy/wCOu/8Axh/61J/wjw/466/8Yf+tQ19qhqvpmH3+n/AIqjU/f6f8w/+Kk1P3+taxPCzY/fXX/AIw/9ajU/C0v/HXX/jD/ANahNfao/SaeD/iqNT9/p/zB/8AFVGrU/f61qU/hRMP39z/AOMP/Wo1P4Vv/wDHXX/jD/1qE39qjUfSa8D/iqtT9/p/zB/8AFVGrU/f61qU/hXcf8dd/+MP/AFqNT+Fb/wDjrj/xh/61CT+1R+k14H/FVan7/AE/5g/8AiqNT9/rWpT+Fbn/jrv8A8Yf+tSj8K3X/AB13/wCMf+tQn9qjUfSa8D/iqNT9/p/zB/8VVoa19/rWpT+Fbv/jrv/wAY/wDWo1P4Vuv+Ouv/ABj/ANahN/ao1H0mvB/xVSmv2/f61qU/hW7/wCOuv8Axj/1qNT+Fbv/AI66/wDGP/WoSf2qNR+k14H/FVqfvtjX61mpT+Fbv/jrr/xj/wBajU/hW7/466/8Yf+tQm/tUaj6TXg/wCKpU/f61mpT+Fbv/jrr/xj/1qNT+Fbv8A466/8Yf+tQk/tUaj6TXg/4qpU/f61mpT+Fbv/jrr/xj/wBajU/hW7/466/8Yf+tQm/tUaj6TXg/wCKq1P3+tZqU/hW7/466/8Y/8AWo1P4Vu/+Ouv/GP/AFqE39qjUfSa8D/iqNT9/rWSmsfFf+8f/ioqYj6f//Z';
89
+
90
+ document.addEventListener('DOMContentLoaded', () => {
91
+ init();
92
+ animate();
93
+ });
94
+
95
+ function init() {
96
+ const container = document.getElementById('container');
97
+ const width = window.innerWidth;
98
+ const height = window.innerHeight;
99
+
100
+ // 1. Scene
101
+ scene = new THREE.Scene();
102
+
103
+ // 2. Camera
104
+ camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
105
+ camera.position.set(0.01, 0, 0); // Немного смещаем камеру, чтобы она была внутри сферы
106
+
107
+ // 3. Renderer
108
+ renderer = new THREE.WebGLRenderer({ antialias: true });
109
+ renderer.setSize(width, height);
110
+ container.appendChild(renderer.domElement);
111
+
112
+ // 4. Controls (OrbitControls для взаимодействия)
113
+ controls = new OrbitControls(camera, renderer.domElement);
114
+ controls.enableZoom = true;
115
+ controls.enablePan = false; // Отключаем панорамирование, чтобы не "вылететь" из сферы
116
+ controls.rotateSpeed = -0.5; // Инвертируем скорость вращения для более интуитивного управления
117
+ controls.enableDamping = true; // Для плавного замедления
118
+ controls.dampingFactor = 0.05;
119
+
120
+ // Загрузка и добавление скайбокса
121
+ loadSkybox(defaultSkyboxImage);
122
+
123
+ // Обработчик изменения размера окна
124
+ window.addEventListener('resize', onWindowResize, false);
125
+
126
+ // Обработчик загрузки файла
127
+ document.getElementById('file-input').addEventListener('change', (event) => {
128
+ const file = event.target.files[0];
129
+ if (file) {
130
+ const reader = new FileReader();
131
+ reader.onload = (e) => {
132
+ loadSkybox(e.target.result);
133
+ };
134
+ reader.readAsDataURL(file);
135
+ }
136
+ });
137
  }
138
+
139
+ function loadSkybox(imageUrl) {
140
+ const loader = new THREE.TextureLoader();
141
+ loader.load(
142
+ imageUrl,
143
+ function (texture) {
144
+ // Удаляем старую сферу, если она существует
145
+ if (sphereMesh) {
146
+ scene.remove(sphereMesh);
147
+ sphereMesh.geometry.dispose();
148
+ sphereMesh.material.dispose();
149
+ }
150
+
151
+ // 5. Geometry (сфера)
152
+ const geometry = new THREE.SphereGeometry(500, 60, 40); // Большой радиус, чтобы камера была внутри
153
+ // Инвертируем нормали, чтобы текстура отображалась изнутри сферы
154
+ geometry.scale(-1, 1, 1);
155
+
156
+ // 6. Material (текстура)
157
+ const material = new THREE.MeshBasicMaterial({ map: texture });
158
+
159
+ // 7. Mesh (собираем)
160
+ sphereMesh = new THREE.Mesh(geometry, material);
161
+ scene.add(sphereMesh);
162
+ },
163
+ undefined, // onProgress callback (можно добавить индикатор загрузки)
164
+ function (err) {
165
+ console.error('Ошибка загрузки текстуры:', err);
166
+ alert('Не удалось загрузить изображение. Убедитесь, что это корректный файл изображения.');
167
+ }
168
+ );
169
+ }
170
+
171
+ function onWindowResize() {
172
+ camera.aspect = window.innerWidth / window.innerHeight;
173
+ camera.updateProjectionMatrix();
174
+ renderer.setSize(window.innerWidth, window.innerHeight);
175
+ }
176
+
177
+ function animate() {
178
+ requestAnimationFrame(animate); // Зацикливаем анимацию
179
+ controls.update(); // Обновляем контролы (важно для enableDamping)
180
+ renderer.render(scene, camera); // Рендерим сцену
181
  }
182
+ </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  </body>
184
  </html>