{"id":296,"date":"2025-07-14T01:38:35","date_gmt":"2025-07-14T01:38:35","guid":{"rendered":"https:\/\/insaatsirketleri.com.tr\/en\/?p=296"},"modified":"2025-07-14T01:38:35","modified_gmt":"2025-07-14T01:38:35","slug":"worlds-most-beautiful-beaches-from-space","status":"publish","type":"post","link":"https:\/\/insaatsirketleri.com.tr\/en\/worlds-most-beautiful-beaches-from-space\/","title":{"rendered":"World&#8217;s Most Beautiful Beaches from Space"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;600;700&#038;display=swap\" rel=\"stylesheet\">\n    <style>\n        body {\n            font-family: 'Inter', sans-serif;\n            background-color: #f0f4f8; \/* Light gray background *\/\n            color: #334155; \/* Dark gray text *\/\n        }\n        .container {\n            max-width: 1200px;\n            margin: 0 auto;\n            padding: 2rem;\n        }\n        .image-card {\n            background-color: #ffffff;\n            border-radius: 1rem; \/* Rounded corners *\/\n            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n            overflow: hidden;\n            cursor: pointer;\n            transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;\n            display: flex;\n            flex-direction: column;\n        }\n        .image-card:hover {\n            transform: translateY(-5px);\n            box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);\n        }\n        .image-card img {\n            width: 100%;\n            height: 200px; \/* Fixed height *\/\n            object-fit: cover; \/* Fit image without cropping *\/\n            border-radius: 1rem 1rem 0 0;\n        }\n        .image-info {\n            padding: 1rem;\n            text-align: center;\n            flex-grow: 1; \/* Allows the info section to fill remaining space *\/\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n        }\n        .image-info p {\n            font-size: 0.9rem;\n            color: #4b5563;\n            margin-bottom: 0.25rem;\n        }\n        .image-info p:last-child {\n            margin-bottom: 0;\n        }\n        .image-info .location-name {\n            font-weight: 600;\n            color: #1f2937;\n        }\n        .loading-spinner {\n            border: 4px solid rgba(0, 0, 0, 0.1);\n            border-left-color: #3b82f6; \/* Blue color *\/\n            border-radius: 50%;\n            width: 40px;\n            height: 40px;\n            animation: spin 1s linear infinite;\n        }\n        @keyframes spin {\n            to {\n                transform: rotate(360deg);\n            }\n        }\n        .modal {\n            display: none;\n            position: fixed;\n            z-index: 1000;\n            left: 0;\n            top: 0;\n            width: 100%;\n            height: 100%;\n            overflow: auto;\n            background-color: rgba(0, 0, 0, 0.8);\n            justify-content: center;\n            align-items: center;\n        }\n        .modal-content {\n            margin: auto;\n            display: block;\n            max-width: 90%;\n            max-height: 90%;\n            border-radius: 1rem;\n        }\n        .close-button {\n            position: absolute;\n            top: 20px;\n            right: 35px;\n            color: #fff;\n            font-size: 40px;\n            font-weight: bold;\n            transition: 0.3s;\n            cursor: pointer;\n        }\n        .close-button:hover,\n        .close-button:focus {\n            color: #bbb;\n            text-decoration: none;\n            cursor: pointer;\n        }\n        .generate-button {\n            background: linear-gradient(to right, #3b82f6, #2563eb); \/* Blue gradient *\/\n            color: white;\n            padding: 0.75rem 1.5rem;\n            border-radius: 9999px; \/* Fully rounded *\/\n            font-weight: 600;\n            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n            transition: all 0.2s ease-in-out;\n            border: none;\n            cursor: pointer;\n        }\n        .generate-button:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);\n        }\n        .generate-button:active {\n            transform: translateY(0);\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n        }\n        .message-box {\n            position: fixed;\n            bottom: 20px;\n            left: 50%;\n            transform: translateX(-50%);\n            background-color: #333;\n            color: white;\n            padding: 15px 20px;\n            border-radius: 8px;\n            z-index: 1001;\n            opacity: 0;\n            transition: opacity 0.5s ease-in-out;\n        }\n        .message-box.show {\n            opacity: 1;\n        }\n    <\/style>\n<\/head>\n<body class=\"p-4\">\n    <div class=\"container\">\n        <h1 id=\"main-title\" class=\"text-4xl font-bold text-center mb-8 text-gray-800\"><\/h1>\n\n        <div id=\"image-gallery\" class=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 mb-8\">\n            <!-- Images will be loaded here -->\n        <\/div>\n\n        <div class=\"flex justify-center mb-8\">\n            <button id=\"generate-more-button\" class=\"generate-button flex items-center justify-center\">\n                <span id=\"button-text\"><\/span>\n                <div id=\"loading-spinner\" class=\"loading-spinner ml-3 hidden\"><\/div>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <!-- Modal for full-size image -->\n    <div id=\"image-modal\" class=\"modal\">\n        <span class=\"close-button\" id=\"close-modal\">&times;<\/span>\n        <img class=\"modal-content\" id=\"modal-image\">\n    <\/div>\n\n    <!-- Custom Message Box -->\n    <div id=\"message-box\" class=\"message-box\"><\/div>\n\n    <script>\n        \/\/ Global variables for Firebase (will be provided by the environment)\n        \/\/ These are typically used for backend services like Firestore or Auth,\n        \/\/ but for this client-side only app, they are not strictly necessary\n        \/\/ unless data persistence is added later.\n        const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';\n        const firebaseConfig = typeof __firebase_config !== 'undefined' ? JSON.parse(__firebase_config) : {};\n        const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null;\n\n        const imageGallery = document.getElementById('image-gallery');\n        const generateMoreButton = document.getElementById('generate-more-button');\n        const loadingSpinner = document.getElementById('loading-spinner');\n        const buttonText = document.getElementById('button-text');\n        const imageModal = document.getElementById('image-modal');\n        const modalImage = document.getElementById('modal-image');\n        const closeModalButton = document.getElementById('close-modal');\n        const messageBox = document.getElementById('message-box');\n        const mainTitle = document.getElementById('main-title');\n        const appTitle = document.getElementById('app-title');\n\n        \/\/ Language specific texts\n        const texts = {\n            en: {\n                mainTitle: \"World's Most Beautiful Beaches from Space\",\n                appTitle: \"World's Most Beautiful Beaches from Space\",\n                generateButton: \"Generate More Images\",\n                generating: \"Generating...\",\n                country: \"Country\",\n                city: \"City\",\n                location: \"Location\",\n                unknown: \"Unknown\",\n                imageLoadError: \"Some images failed to load. Please try again.\",\n                imageGenError: \"Image generation error:\",\n                imageGenInvalidResponse: \"Image could not be generated. Invalid response structure.\",\n                imageGenNetworkError: \"A network error occurred while generating the image.\",\n                locationGenError: \"Location information generation error:\",\n                locationGenInvalidResponse: \"Location information could not be generated. Invalid response structure.\",\n                locationGenNetworkError: \"A network error occurred while generating location information.\"\n            },\n            tr: {\n                mainTitle: \"D\u00fcnyan\u0131n En G\u00fczel Sahilleri Uzaydan\",\n                appTitle: \"D\u00fcnyan\u0131n En G\u00fczel Sahilleri Uzaydan\",\n                generateButton: \"Daha Fazla Resim Olu\u015ftur\",\n                generating: \"Olu\u015fturuluyor...\",\n                country: \"\u00dclke\",\n                city: \"\u015eehir\",\n                location: \"Yer\",\n                unknown: \"Bilinmiyor\",\n                imageLoadError: \"Baz\u0131 resimler y\u00fcklenemedi. L\u00fctfen tekrar deneyin.\",\n                imageGenError: \"Resim olu\u015fturma hatas\u0131:\",\n                imageGenInvalidResponse: \"Resim olu\u015fturulamad\u0131. Ge\u00e7ersiz yan\u0131t yap\u0131s\u0131.\",\n                imageGenNetworkError: \"Resim olu\u015fturulurken bir a\u011f hatas\u0131 olu\u015ftu.\",\n                locationGenError: \"Konum bilgisi olu\u015fturma hatas\u0131:\",\n                locationGenInvalidResponse: \"Konum bilgisi olu\u015fturulamad\u0131. Ge\u00e7ersiz yan\u0131t yap\u0131s\u0131.\",\n                locationGenNetworkError: \"Konum bilgisi olu\u015fturulurken bir a\u011f hatas\u0131 olu\u015ftu.\"\n            }\n        };\n\n        \/\/ Determine language based on browser preference\n        let currentLang = 'en'; \/\/ Default to English\n        const browserLang = navigator.language || navigator.userLanguage;\n        if (browserLang.startsWith('tr')) {\n            currentLang = 'tr';\n        }\n\n        \/\/ Set initial UI texts\n        function setUITexts() {\n            mainTitle.textContent = texts[currentLang].mainTitle;\n            appTitle.textContent = texts[currentLang].appTitle;\n            buttonText.textContent = texts[currentLang].generateButton;\n        }\n\n        \/\/ Function to show custom message\n        function showMessage(message, duration = 3000) {\n            messageBox.textContent = message;\n            messageBox.classList.add('show');\n            setTimeout(() => {\n                messageBox.classList.remove('show');\n            }, duration);\n        }\n\n        \/\/ Function to toggle loading state\n        function setLoading(isLoading) {\n            if (isLoading) {\n                loadingSpinner.classList.remove('hidden');\n                buttonText.textContent = texts[currentLang].generating;\n                generateMoreButton.disabled = true;\n            } else {\n                loadingSpinner.classList.add('hidden');\n                buttonText.textContent = texts[currentLang].generateButton;\n                generateMoreButton.disabled = false;\n            }\n        }\n\n        \/\/ Function to generate image using Imagen API\n        async function generateImage(prompt) {\n            const payload = {\n                instances: { prompt: prompt },\n                parameters: { \"sampleCount\": 1 }\n            };\n            const apiKey = \"\"; \/\/ API key will be provided by the environment\n            const apiUrl = `https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/imagen-3.0-generate-002:predict?key=${apiKey}`;\n\n            try {\n                const response = await fetch(apiUrl, {\n                    method: 'POST',\n                    headers: { 'Content-Type': 'application\/json' },\n                    body: JSON.stringify(payload)\n                });\n\n                if (!response.ok) {\n                    const errorData = await response.json();\n                    console.error('API Error (Image Generation):', errorData);\n                    showMessage(`${texts[currentLang].imageGenError} ${errorData.error.message || texts[currentLang].unknown}`);\n                    return null;\n                }\n\n                const result = await response.json();\n                if (result.predictions && result.predictions.length > 0 && result.predictions[0].bytesBase64Encoded) {\n                    return `data:image\/png;base64,${result.predictions[0].bytesBase64Encoded}`;\n                } else {\n                    showMessage(texts[currentLang].imageGenInvalidResponse);\n                    return null;\n                }\n            } catch (error) {\n                console.error('Fetch Error (Image Generation):', error);\n                showMessage(texts[currentLang].imageGenNetworkError);\n                return null;\n            }\n        }\n\n        \/\/ Function to generate location information using Gemini API\n        async function generateLocationInfo(imagePrompt) {\n            const chatHistory = [];\n            \/\/ Prompt is always in English for consistent results from the model\n            const prompt = `Given the description of a beach: \"${imagePrompt}\", suggest a realistic country, city, and a specific location (e.g., beach name, landmark) that matches this description. If a specific location is hard to determine, just provide a general area. Provide the answer in JSON format with keys 'country', 'city', and 'location'.`;\n            chatHistory.push({ role: \"user\", parts: [{ text: prompt }] });\n\n            const payload = {\n                contents: chatHistory,\n                generationConfig: {\n                    responseMimeType: \"application\/json\",\n                    responseSchema: {\n                        type: \"OBJECT\",\n                        properties: {\n                            \"country\": { \"type\": \"STRING\" },\n                            \"city\": { \"type\": \"STRING\" },\n                            \"location\": { \"type\": \"STRING\" }\n                        },\n                        \"propertyOrdering\": [\"country\", \"city\", \"location\"]\n                    }\n                }\n            };\n            const apiKey = \"\"; \/\/ API key will be provided by the environment\n            const apiUrl = `https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/gemini-2.0-flash:generateContent?key=${apiKey}`;\n\n            try {\n                const response = await fetch(apiUrl, {\n                    method: 'POST',\n                    headers: { 'Content-Type': 'application\/json' },\n                    body: JSON.stringify(payload)\n                });\n\n                if (!response.ok) {\n                    const errorData = await response.json();\n                    console.error('API Error (Location Generation):', errorData);\n                    showMessage(`${texts[currentLang].locationGenError} ${errorData.error.message || texts[currentLang].unknown}`);\n                    return null;\n                }\n\n                const result = await response.json();\n                if (result.candidates && result.candidates.length > 0 &&\n                    result.candidates[0].content && result.candidates[0].content.parts &&\n                    result.candidates[0].content.parts.length > 0) {\n                    const json = result.candidates[0].content.parts[0].text;\n                    const parsedJson = JSON.parse(json);\n                    return parsedJson;\n                } else {\n                    showMessage(texts[currentLang].locationGenInvalidResponse);\n                    return null;\n                }\n            } catch (error) {\n                console.error('Fetch Error (Location Generation):', error);\n                showMessage(texts[currentLang].locationGenNetworkError);\n                return null;\n            }\n        }\n\n        \/\/ Function to add an image to the gallery with location info\n        function addImageToGallery(imageUrl, locationInfo) {\n            const imageCard = document.createElement('div');\n            imageCard.className = 'image-card';\n\n            const img = document.createElement('img');\n            img.src = imageUrl;\n            img.alt = 'Space Beach Image'; \/\/ Alt text in English\n            img.loading = 'lazy'; \/\/ Lazy loading for performance\n\n            \/\/ Add error handling for image loading\n            img.onerror = () => {\n                img.src = `https:\/\/placehold.co\/200x200\/cccccc\/333333?text=${texts[currentLang].imageLoadError.replace(\/ \/g, '+')}`;\n                img.alt = texts[currentLang].imageLoadError;\n                showMessage(texts[currentLang].imageLoadError);\n            };\n\n            const infoDiv = document.createElement('div');\n            infoDiv.className = 'image-info';\n\n            const countryP = document.createElement('p');\n            countryP.textContent = `${texts[currentLang].country}: ${locationInfo?.country || texts[currentLang].unknown}`;\n            infoDiv.appendChild(countryP);\n\n            const cityP = document.createElement('p');\n            cityP.textContent = `${texts[currentLang].city}: ${locationInfo?.city || texts[currentLang].unknown}`;\n            infoDiv.appendChild(cityP);\n\n            const locationP = document.createElement('p');\n            locationP.className = 'location-name';\n            locationP.textContent = `${texts[currentLang].location}: ${locationInfo?.location || texts[currentLang].unknown}`;\n            infoDiv.appendChild(locationP);\n\n            imageCard.appendChild(img);\n            imageCard.appendChild(infoDiv);\n            imageGallery.appendChild(imageCard);\n\n            \/\/ Open modal on image click\n            imageCard.addEventListener('click', () => {\n                modalImage.src = imageUrl;\n                imageModal.style.display = 'flex'; \/\/ Use flex to center\n            });\n        }\n\n        \/\/ Function to generate and display images\n        async function generateAndDisplayImages(count = 4) {\n            setLoading(true);\n            \/\/ Prompts are always in English for the image generation model\n            const prompts = [\n                \"Tropical beach seen from space, clear turquoise water and white sands, palm trees, high-resolution satellite image, realistic, detailed\",\n                \"Hidden cove beach seen from space, rocky formations and pristine beach, turquoise lagoon, satellite view, natural light, ultra realistic\",\n                \"Beach surrounded by coral reefs seen from space, vibrant colors, underwater details, no boats, satellite perspective\",\n                \"Long, curving coastline beach seen from space, waves crashing on shore, golden sands, aerial view, sunset light\",\n                \"Panoramic view of an island beach from space, white sands, calm lagoon, lush vegetation, satellite photography\",\n                \"Volcanic black sand beach seen from space, dramatic landscape, dark colors, contrasting hues, satellite imaging\",\n                \"Icy beach seen from space, icebergs and snowy coastline, polar satellite image, cold tones, glacial lakes\",\n                \"Beach with a city skyline seen from space, mix of urban development and natural beauty, skyscrapers, satellite photo\",\n                \"River delta beach seen from space, intricate waterways and green vegetation, muddy water, satellite perspective\",\n                \"Stormy beach seen from space, powerful waves and cloudy sky, dramatic satellite image, no lightning\"\n            ];\n\n            const shuffledPrompts = prompts.sort(() => 0.5 - Math.random()); \/\/ Shuffle prompts\n            const selectedPrompts = shuffledPrompts.slice(0, count); \/\/ Select a specified number of prompts\n\n            for (const prompt of selectedPrompts) {\n                const imageUrl = await generateImage(prompt);\n                if (imageUrl) {\n                    const locationInfo = await generateLocationInfo(prompt);\n                    addImageToGallery(imageUrl, locationInfo);\n                }\n            }\n            setLoading(false);\n        }\n\n        \/\/ Event listener for \"Generate More Images\" button\n        generateMoreButton.addEventListener('click', () => generateAndDisplayImages(4)); \/\/ Generate 4 new images on each click\n\n        \/\/ Close modal when close button is clicked\n        closeModalButton.addEventListener('click', () => {\n            imageModal.style.display = 'none';\n        });\n\n        \/\/ Close modal when clicking outside the image\n        imageModal.addEventListener('click', (event) => {\n            if (event.target === imageModal) {\n                imageModal.style.display = 'none';\n            }\n        });\n\n        \/\/ Initial setup and image generation on page load\n        window.onload = () => {\n            setUITexts(); \/\/ Set initial texts based on detected language\n            generateAndDisplayImages(8); \/\/ Generate 8 images initially\n        };\n    <\/script>\n\n\n","protected":false},"excerpt":{"rendered":"<p>&times;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-296","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":1,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/296\/revisions\/297"}],"wp:attachment":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}