index.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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>PhotoPlaces - Добро пожаловать</title>
  7. <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. body {
  15. font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  16. overflow: hidden;
  17. background: #000;
  18. }
  19. #map-container {
  20. width: 100vw;
  21. height: 100vh;
  22. position: absolute;
  23. top: 0;
  24. left: 0;
  25. z-index: 1;
  26. }
  27. .welcome-overlay {
  28. position: absolute;
  29. top: 0;
  30. left: 0;
  31. width: 100%;
  32. height: 100%;
  33. display: flex;
  34. flex-direction: column;
  35. justify-content: center;
  36. align-items: center;
  37. z-index: 1000;
  38. background: radial-gradient(circle at center, transparent 0%, rgba(0, 0, 0, 0.4) 100%);
  39. pointer-events: none;
  40. }
  41. .welcome-content {
  42. text-align: center;
  43. color: white;
  44. z-index: 1001;
  45. pointer-events: auto;
  46. }
  47. h1 {
  48. font-size: 3.5rem;
  49. margin-bottom: 1rem;
  50. text-shadow: 0 0 20px rgba(255, 255, 255, 0.5),
  51. 0 0 40px rgba(255, 255, 255, 0.3),
  52. 2px 2px 4px rgba(0, 0, 0, 0.8);
  53. font-weight: 300;
  54. letter-spacing: 2px;
  55. }
  56. .subtitle {
  57. font-size: 1.2rem;
  58. margin-bottom: 3rem;
  59. opacity: 0.9;
  60. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
  61. }
  62. .login-button {
  63. padding: 18px 50px;
  64. font-size: 1.3rem;
  65. font-weight: 600;
  66. color: white;
  67. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  68. border: none;
  69. border-radius: 50px;
  70. cursor: pointer;
  71. transition: all 0.3s ease;
  72. box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4),
  73. 0 0 20px rgba(102, 126, 234, 0.2);
  74. text-transform: uppercase;
  75. letter-spacing: 1px;
  76. position: relative;
  77. overflow: hidden;
  78. }
  79. .login-button::before {
  80. content: '';
  81. position: absolute;
  82. top: 50%;
  83. left: 50%;
  84. width: 0;
  85. height: 0;
  86. border-radius: 50%;
  87. background: rgba(255, 255, 255, 0.3);
  88. transform: translate(-50%, -50%);
  89. transition: width 0.6s, height 0.6s;
  90. }
  91. .login-button:hover::before {
  92. width: 300px;
  93. height: 300px;
  94. }
  95. .login-button:hover {
  96. transform: translateY(-3px);
  97. box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6),
  98. 0 0 30px rgba(102, 126, 234, 0.3);
  99. }
  100. .login-button:active {
  101. transform: translateY(-1px);
  102. }
  103. .login-button span {
  104. position: relative;
  105. z-index: 1;
  106. }
  107. /* Стили для точек на карте - не нужны, используем CircleMarker */
  108. @media (max-width: 768px) {
  109. h1 {
  110. font-size: 2.5rem;
  111. }
  112. .subtitle {
  113. font-size: 1rem;
  114. margin-bottom: 2rem;
  115. }
  116. .login-button {
  117. padding: 15px 40px;
  118. font-size: 1.1rem;
  119. }
  120. }
  121. </style>
  122. </head>
  123. <body>
  124. <div id="map-container"></div>
  125. <div class="welcome-overlay">
  126. <div class="welcome-content">
  127. <h1>PhotoPlaces</h1>
  128. <p class="subtitle">Откройте мир через объектив</p>
  129. <button class="login-button" onclick="handleLogin()">
  130. <span>Войти</span>
  131. </button>
  132. </div>
  133. </div>
  134. <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
  135. <script>
  136. // Инициализация карты
  137. const map = L.map('map-container', {
  138. zoomControl: false,
  139. attributionControl: false
  140. }).setView([20, 0], 2);
  141. // Добавляем темную тему карты (CartoDB Dark Matter)
  142. L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
  143. attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
  144. subdomains: 'abcd',
  145. maxZoom: 19
  146. }).addTo(map);
  147. // Координаты крупных городов мира
  148. const majorCities = [
  149. // Северная Америка
  150. {lat: 40.7128, lon: -74.0060}, {lat: 34.0522, lon: -118.2437}, {lat: 41.8781, lon: -87.6298},
  151. {lat: 29.7604, lon: -95.3698}, {lat: 25.7617, lon: -80.1918}, {lat: 37.7749, lon: -122.4194},
  152. {lat: 45.5017, lon: -73.5673}, {lat: 43.6532, lon: -79.3832}, {lat: 49.2827, lon: -123.1207},
  153. {lat: 19.4326, lon: -99.1332}, {lat: 32.7767, lon: -96.7970}, {lat: 39.9526, lon: -75.1652},
  154. {lat: 47.6062, lon: -122.3321}, {lat: 33.4484, lon: -112.0740}, {lat: 36.1699, lon: -115.1398},
  155. // Южная Америка
  156. {lat: -23.5505, lon: -46.6333}, {lat: -34.6037, lon: -58.3816}, {lat: -33.4489, lon: -70.6693},
  157. {lat: -12.0464, lon: -77.0428}, {lat: 4.7110, lon: -74.0721}, {lat: -15.7975, lon: -47.8919},
  158. {lat: -22.9068, lon: -43.1729}, {lat: -8.0476, lon: -34.8770}, {lat: -16.2902, lon: -63.5887},
  159. // Европа
  160. {lat: 51.5074, lon: -0.1278}, {lat: 48.8566, lon: 2.3522}, {lat: 52.5200, lon: 13.4050},
  161. {lat: 41.9028, lon: 12.4964}, {lat: 40.4168, lon: -3.7038}, {lat: 55.7558, lon: 37.6173},
  162. {lat: 59.9343, lon: 10.7581}, {lat: 59.3293, lon: 18.0686}, {lat: 52.3676, lon: 4.9041},
  163. {lat: 50.8503, lon: 4.3517}, {lat: 38.7223, lon: -9.1393}, {lat: 60.1699, lon: 24.9384},
  164. {lat: 50.0755, lon: 14.4378}, {lat: 47.4979, lon: 19.0402}, {lat: 45.4642, lon: 9.1900},
  165. {lat: 53.3498, lon: -6.2603}, {lat: 41.0082, lon: 28.9784}, {lat: 50.0647, lon: 19.9450},
  166. {lat: 44.4268, lon: 26.1025}, {lat: 55.6761, lon: 12.5683},
  167. // Азия
  168. {lat: 35.6762, lon: 139.6503}, {lat: 31.2304, lon: 121.4737}, {lat: 39.9042, lon: 116.4074},
  169. {lat: 22.3193, lon: 114.1694}, {lat: 1.3521, lon: 103.8198}, {lat: 13.7563, lon: 100.5018},
  170. {lat: 19.0760, lon: 72.8777}, {lat: 28.6139, lon: 77.2090}, {lat: 12.9716, lon: 77.5946},
  171. {lat: 23.0225, lon: 72.5714}, {lat: 18.5204, lon: 73.8567}, {lat: 37.5665, lon: 126.9780},
  172. {lat: 25.2048, lon: 55.2708}, {lat: 24.7136, lon: 46.6753}, {lat: 31.5497, lon: 74.3436},
  173. {lat: 33.6844, lon: 73.0479}, {lat: 6.9271, lon: 79.8612}, {lat: 14.5995, lon: 120.9842},
  174. {lat: -6.2088, lon: 106.8456}, {lat: 3.1390, lon: 101.6869}, {lat: 24.8607, lon: 67.0011},
  175. {lat: 17.3850, lon: 78.4867}, {lat: 13.0827, lon: 80.2707}, {lat: 26.9124, lon: 75.7873},
  176. // Африка
  177. {lat: -26.2041, lon: 28.0473}, {lat: -33.9249, lon: 18.4241}, {lat: 30.0444, lon: 31.2357},
  178. {lat: -1.2921, lon: 36.8219}, {lat: 6.5244, lon: 3.3792}, {lat: -15.3875, lon: 28.3228},
  179. {lat: -4.0435, lon: 39.6682}, {lat: 9.0765, lon: 7.3986}, {lat: -25.7479, lon: 28.2293},
  180. {lat: -29.8587, lon: 31.0218}, {lat: 5.6037, lon: -0.1870}, {lat: 36.8065, lon: 10.1815},
  181. // Австралия и Океания
  182. {lat: -33.8688, lon: 151.2093}, {lat: -37.8136, lon: 144.9631}, {lat: -27.4698, lon: 153.0251},
  183. {lat: -31.9505, lon: 115.8605}, {lat: -34.9285, lon: 138.6007}, {lat: -36.8485, lon: 174.7633},
  184. {lat: -41.2865, lon: 174.7762},
  185. ];
  186. // Генерируем много дополнительных городов
  187. function generateCities() {
  188. const cities = [];
  189. // Северная Америка
  190. for (let i = 0; i < 200; i++) {
  191. cities.push({
  192. lat: 25 + Math.random() * 45,
  193. lon: -130 + Math.random() * 80
  194. });
  195. }
  196. // Южная Америка
  197. for (let i = 0; i < 150; i++) {
  198. cities.push({
  199. lat: -55 + Math.random() * 67,
  200. lon: -80 + Math.random() * 45
  201. });
  202. }
  203. // Европа
  204. for (let i = 0; i < 250; i++) {
  205. cities.push({
  206. lat: 35 + Math.random() * 37,
  207. lon: -10 + Math.random() * 50
  208. });
  209. }
  210. // Азия
  211. for (let i = 0; i < 400; i++) {
  212. cities.push({
  213. lat: 0 + Math.random() * 75,
  214. lon: 40 + Math.random() * 110
  215. });
  216. }
  217. // Африка
  218. for (let i = 0; i < 200; i++) {
  219. cities.push({
  220. lat: -35 + Math.random() * 72,
  221. lon: -18 + Math.random() * 70
  222. });
  223. }
  224. // Австралия
  225. for (let i = 0; i < 100; i++) {
  226. cities.push({
  227. lat: -44 + Math.random() * 34,
  228. lon: 113 + Math.random() * 41
  229. });
  230. }
  231. return cities;
  232. }
  233. const allCities = [...majorCities, ...generateCities()];
  234. // Создаем группу для всех точек (оптимизация производительности)
  235. const citiesGroup = L.featureGroup().addTo(map);
  236. // Используем CircleMarker - встроенную функцию Leaflet для точек
  237. allCities.forEach(city => {
  238. L.circleMarker([city.lat, city.lon], {
  239. radius: 2, // Маленький размер точки
  240. fillColor: '#FFD700',
  241. color: 'rgba(255, 215, 0, 0.8)',
  242. weight: 1,
  243. opacity: 1,
  244. fillOpacity: 1
  245. }).addTo(citiesGroup);
  246. });
  247. // Обработчик кнопки входа
  248. function handleLogin() {
  249. alert('Функция входа будет реализована');
  250. // window.location.href = '/login';
  251. }
  252. </script>
  253. </body>
  254. </html>