|
|
@@ -0,0 +1,291 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="ru">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>PhotoPlaces - Добро пожаловать</title>
|
|
|
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
|
+ <style>
|
|
|
+ * {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ body {
|
|
|
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #000;
|
|
|
+ }
|
|
|
+
|
|
|
+ #map-container {
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .welcome-overlay {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ z-index: 1000;
|
|
|
+ background: radial-gradient(circle at center, transparent 0%, rgba(0, 0, 0, 0.4) 100%);
|
|
|
+ pointer-events: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .welcome-content {
|
|
|
+ text-align: center;
|
|
|
+ color: white;
|
|
|
+ z-index: 1001;
|
|
|
+ pointer-events: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ h1 {
|
|
|
+ font-size: 3.5rem;
|
|
|
+ margin-bottom: 1rem;
|
|
|
+ text-shadow: 0 0 20px rgba(255, 255, 255, 0.5),
|
|
|
+ 0 0 40px rgba(255, 255, 255, 0.3),
|
|
|
+ 2px 2px 4px rgba(0, 0, 0, 0.8);
|
|
|
+ font-weight: 300;
|
|
|
+ letter-spacing: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .subtitle {
|
|
|
+ font-size: 1.2rem;
|
|
|
+ margin-bottom: 3rem;
|
|
|
+ opacity: 0.9;
|
|
|
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button {
|
|
|
+ padding: 18px 50px;
|
|
|
+ font-size: 1.3rem;
|
|
|
+ font-weight: 600;
|
|
|
+ color: white;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border: none;
|
|
|
+ border-radius: 50px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4),
|
|
|
+ 0 0 20px rgba(102, 126, 234, 0.2);
|
|
|
+ text-transform: uppercase;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: rgba(255, 255, 255, 0.3);
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ transition: width 0.6s, height 0.6s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button:hover::before {
|
|
|
+ width: 300px;
|
|
|
+ height: 300px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button:hover {
|
|
|
+ transform: translateY(-3px);
|
|
|
+ box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6),
|
|
|
+ 0 0 30px rgba(102, 126, 234, 0.3);
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button:active {
|
|
|
+ transform: translateY(-1px);
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button span {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Стили для точек на карте - не нужны, используем CircleMarker */
|
|
|
+
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ h1 {
|
|
|
+ font-size: 2.5rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .subtitle {
|
|
|
+ font-size: 1rem;
|
|
|
+ margin-bottom: 2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-button {
|
|
|
+ padding: 15px 40px;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <div id="map-container"></div>
|
|
|
+
|
|
|
+ <div class="welcome-overlay">
|
|
|
+ <div class="welcome-content">
|
|
|
+ <h1>PhotoPlaces</h1>
|
|
|
+ <p class="subtitle">Откройте мир через объектив</p>
|
|
|
+ <button class="login-button" onclick="handleLogin()">
|
|
|
+ <span>Войти</span>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
|
+ <script>
|
|
|
+ // Инициализация карты
|
|
|
+ const map = L.map('map-container', {
|
|
|
+ zoomControl: false,
|
|
|
+ attributionControl: false
|
|
|
+ }).setView([20, 0], 2);
|
|
|
+
|
|
|
+ // Добавляем темную тему карты (CartoDB Dark Matter)
|
|
|
+ L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
|
|
|
+ attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
|
|
+ subdomains: 'abcd',
|
|
|
+ maxZoom: 19
|
|
|
+ }).addTo(map);
|
|
|
+
|
|
|
+ // Координаты крупных городов мира
|
|
|
+ const majorCities = [
|
|
|
+ // Северная Америка
|
|
|
+ {lat: 40.7128, lon: -74.0060}, {lat: 34.0522, lon: -118.2437}, {lat: 41.8781, lon: -87.6298},
|
|
|
+ {lat: 29.7604, lon: -95.3698}, {lat: 25.7617, lon: -80.1918}, {lat: 37.7749, lon: -122.4194},
|
|
|
+ {lat: 45.5017, lon: -73.5673}, {lat: 43.6532, lon: -79.3832}, {lat: 49.2827, lon: -123.1207},
|
|
|
+ {lat: 19.4326, lon: -99.1332}, {lat: 32.7767, lon: -96.7970}, {lat: 39.9526, lon: -75.1652},
|
|
|
+ {lat: 47.6062, lon: -122.3321}, {lat: 33.4484, lon: -112.0740}, {lat: 36.1699, lon: -115.1398},
|
|
|
+
|
|
|
+ // Южная Америка
|
|
|
+ {lat: -23.5505, lon: -46.6333}, {lat: -34.6037, lon: -58.3816}, {lat: -33.4489, lon: -70.6693},
|
|
|
+ {lat: -12.0464, lon: -77.0428}, {lat: 4.7110, lon: -74.0721}, {lat: -15.7975, lon: -47.8919},
|
|
|
+ {lat: -22.9068, lon: -43.1729}, {lat: -8.0476, lon: -34.8770}, {lat: -16.2902, lon: -63.5887},
|
|
|
+
|
|
|
+ // Европа
|
|
|
+ {lat: 51.5074, lon: -0.1278}, {lat: 48.8566, lon: 2.3522}, {lat: 52.5200, lon: 13.4050},
|
|
|
+ {lat: 41.9028, lon: 12.4964}, {lat: 40.4168, lon: -3.7038}, {lat: 55.7558, lon: 37.6173},
|
|
|
+ {lat: 59.9343, lon: 10.7581}, {lat: 59.3293, lon: 18.0686}, {lat: 52.3676, lon: 4.9041},
|
|
|
+ {lat: 50.8503, lon: 4.3517}, {lat: 38.7223, lon: -9.1393}, {lat: 60.1699, lon: 24.9384},
|
|
|
+ {lat: 50.0755, lon: 14.4378}, {lat: 47.4979, lon: 19.0402}, {lat: 45.4642, lon: 9.1900},
|
|
|
+ {lat: 53.3498, lon: -6.2603}, {lat: 41.0082, lon: 28.9784}, {lat: 50.0647, lon: 19.9450},
|
|
|
+ {lat: 44.4268, lon: 26.1025}, {lat: 55.6761, lon: 12.5683},
|
|
|
+
|
|
|
+ // Азия
|
|
|
+ {lat: 35.6762, lon: 139.6503}, {lat: 31.2304, lon: 121.4737}, {lat: 39.9042, lon: 116.4074},
|
|
|
+ {lat: 22.3193, lon: 114.1694}, {lat: 1.3521, lon: 103.8198}, {lat: 13.7563, lon: 100.5018},
|
|
|
+ {lat: 19.0760, lon: 72.8777}, {lat: 28.6139, lon: 77.2090}, {lat: 12.9716, lon: 77.5946},
|
|
|
+ {lat: 23.0225, lon: 72.5714}, {lat: 18.5204, lon: 73.8567}, {lat: 37.5665, lon: 126.9780},
|
|
|
+ {lat: 25.2048, lon: 55.2708}, {lat: 24.7136, lon: 46.6753}, {lat: 31.5497, lon: 74.3436},
|
|
|
+ {lat: 33.6844, lon: 73.0479}, {lat: 6.9271, lon: 79.8612}, {lat: 14.5995, lon: 120.9842},
|
|
|
+ {lat: -6.2088, lon: 106.8456}, {lat: 3.1390, lon: 101.6869}, {lat: 24.8607, lon: 67.0011},
|
|
|
+ {lat: 17.3850, lon: 78.4867}, {lat: 13.0827, lon: 80.2707}, {lat: 26.9124, lon: 75.7873},
|
|
|
+
|
|
|
+ // Африка
|
|
|
+ {lat: -26.2041, lon: 28.0473}, {lat: -33.9249, lon: 18.4241}, {lat: 30.0444, lon: 31.2357},
|
|
|
+ {lat: -1.2921, lon: 36.8219}, {lat: 6.5244, lon: 3.3792}, {lat: -15.3875, lon: 28.3228},
|
|
|
+ {lat: -4.0435, lon: 39.6682}, {lat: 9.0765, lon: 7.3986}, {lat: -25.7479, lon: 28.2293},
|
|
|
+ {lat: -29.8587, lon: 31.0218}, {lat: 5.6037, lon: -0.1870}, {lat: 36.8065, lon: 10.1815},
|
|
|
+
|
|
|
+ // Австралия и Океания
|
|
|
+ {lat: -33.8688, lon: 151.2093}, {lat: -37.8136, lon: 144.9631}, {lat: -27.4698, lon: 153.0251},
|
|
|
+ {lat: -31.9505, lon: 115.8605}, {lat: -34.9285, lon: 138.6007}, {lat: -36.8485, lon: 174.7633},
|
|
|
+ {lat: -41.2865, lon: 174.7762},
|
|
|
+ ];
|
|
|
+
|
|
|
+ // Генерируем много дополнительных городов
|
|
|
+ function generateCities() {
|
|
|
+ const cities = [];
|
|
|
+
|
|
|
+ // Северная Америка
|
|
|
+ for (let i = 0; i < 200; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: 25 + Math.random() * 45,
|
|
|
+ lon: -130 + Math.random() * 80
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Южная Америка
|
|
|
+ for (let i = 0; i < 150; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: -55 + Math.random() * 67,
|
|
|
+ lon: -80 + Math.random() * 45
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Европа
|
|
|
+ for (let i = 0; i < 250; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: 35 + Math.random() * 37,
|
|
|
+ lon: -10 + Math.random() * 50
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Азия
|
|
|
+ for (let i = 0; i < 400; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: 0 + Math.random() * 75,
|
|
|
+ lon: 40 + Math.random() * 110
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Африка
|
|
|
+ for (let i = 0; i < 200; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: -35 + Math.random() * 72,
|
|
|
+ lon: -18 + Math.random() * 70
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Австралия
|
|
|
+ for (let i = 0; i < 100; i++) {
|
|
|
+ cities.push({
|
|
|
+ lat: -44 + Math.random() * 34,
|
|
|
+ lon: 113 + Math.random() * 41
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return cities;
|
|
|
+ }
|
|
|
+
|
|
|
+ const allCities = [...majorCities, ...generateCities()];
|
|
|
+
|
|
|
+ // Создаем группу для всех точек (оптимизация производительности)
|
|
|
+ const citiesGroup = L.featureGroup().addTo(map);
|
|
|
+
|
|
|
+ // Используем CircleMarker - встроенную функцию Leaflet для точек
|
|
|
+ allCities.forEach(city => {
|
|
|
+ L.circleMarker([city.lat, city.lon], {
|
|
|
+ radius: 2, // Маленький размер точки
|
|
|
+ fillColor: '#FFD700',
|
|
|
+ color: 'rgba(255, 215, 0, 0.8)',
|
|
|
+ weight: 1,
|
|
|
+ opacity: 1,
|
|
|
+ fillOpacity: 1
|
|
|
+ }).addTo(citiesGroup);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Обработчик кнопки входа
|
|
|
+ function handleLogin() {
|
|
|
+ alert('Функция входа будет реализована');
|
|
|
+ // window.location.href = '/login';
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|