top of page

<!DOCTYPE html>
<html lang="fr">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Simulateur de Coucher de Soleil</title>
   <style>
       @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@500&display=swap');

       body {
           margin: 0;
           background: linear-gradient(to top, #001f3f, #87CEEB);
           color: #F9F5FF;
           font-family: 'DM Sans', sans-serif;
           font-size: 18px;
           transition: background 1s ease;
           position: relative;
        
           height: 100vh;
           display: flex;
           justify-content: center;
           align-items: center;
       }

       .sunset-container {
           position: absolute;
           top: 20px;
           right: 200px;
           display: flex;
           flex-direction: row;
           align-items: flex-start;
       }

       .sun {
           position: relative;
           width: 50px;
           height: 50px;
           margin-right: 30px;
           transition: transform 0.4s ease;
       }

       .sun::before {
           content: '';
           position: absolute;
           top: 50%;
           left: 50%;
           width: 25px;
           height: 25px;
           background: #F9F5FF;
           border-radius: 50%;
           transform: translate(-50%, -50%);
           transition: opacity 0.4s ease;
       }

       .sun svg {
           position: absolute;
           top: 0;
           left: 0;
           width: 100%;
           height: 100%;
           fill: #F9F5FF;
           opacity: 0;
           transition: opacity 0.4s ease;
       }

       .sun.star::before {
           opacity: 0;
       }

       .sun.star svg {
           opacity: 1;
       }

       .controls {
           display: flex;
           flex-direction: column;
           align-items: flex-start;
       }

       input[type="range"] {
           width: 100px;
           margin-top: 10px;
           -webkit-appearance: none;
           appearance: none;
           background: rgba(249, 245, 255, 0.6); /* Barre de fond */
           height: 5px;
           border-radius: 4px;
           outline: none;
       }

       input[type="range"]::-webkit-slider-runnable-track {
           background: rgba(249, 245, 255, 0.6); /* Barre de fond */
           height: 5px;
           border-radius: 4px;
       }

       input[type="range"]::-webkit-slider-thumb {
           -webkit-appearance: none;
           appearance: none;
           width: 20px;
           height: 20px;
           border-radius: 50%;
           background: #7f3af5; /* Nouvelle couleur de progression */
           border: 2px solid #7f3af5;
           transition: background 0.3s ease;
       }

       input[type="range"]:active::-webkit-slider-thumb {
           background: #7f3af5; /* Couleur du curseur cliqué */
           border: 2px solid #7f3af5;
       }

       input[type="range"]::-moz-range-track {
           background: rgba(249, 245, 255, 0.6); /* Barre de fond */
           height: 5px;
           border-radius: 4px;
       }

       input[type="range"]::-moz-range-thumb {
           width: 15px;
           height: 15px;
           border-radius: 50%;
           background: #7f3af5; /* Nouvelle couleur de progression */
           border: 2px solid #7f3af5;
           transition: background 0.3s ease;
       }

       input[type="range"]:active::-moz-range-thumb {
           background: #7f3af5; /* Couleur du curseur cliqué */
           border: 2px solid #7f3af5;
       }

       input[type="range"]::-ms-track {
           background: rgba(249, 245, 255, 0.6); /* Barre de fond */
           height: 5px;
           border-radius: 4px;
           border-color: transparent;
           color: transparent;
           background-color: transparent;
           border-width: 0;
       }

       input[type="range"]::-ms-thumb {
           width: 15px;
           height: 15px;
           border-radius: 50%;
           background: #7f3af5; /* Nouvelle couleur de progression */
           border: 2px solid #7f3af5;
           transition: background 0.3s ease;
       }

       input[type="range"]:active::-ms-thumb {
           background: #7f3af5; /* Couleur du curseur cliqué */
           border: 2px solid #7f3af5;
       }

       p {
           margin: 0;
       }
   </style>
</head>
<body>
   <div class="sunset-container">
       <div id="sun" class="sun">
           <svg viewBox="0 0 200 200">
               <path d="M180 78.564L141.411 100 180 121.436l-44.137-.73 22.701 37.858-37.858-22.701.73 44.137L100 141.411 78.564 180l.73-44.137-37.858 22.701 22.701-37.858-44.137.73L58.589 100 20 78.564l44.137.73-22.701-37.858 37.858 22.701L78.564 20 100 58.589 121.436 20l-.73 44.137 37.858-22.701-22.701 37.858 44.137-.73z"></path>
           </svg>
       </div>
       <div class="controls">
           <p>Bonjour ☀️ </br> Il est <span id="timeDisplay">HH:MM</span></p>
           <input type="range" id="timeSlider" min="0" max="100" step="0.1">
       </div>
   </div>

   <script>
       const timeSlider = document.getElementById("timeSlider");
       const timeDisplay = document.getElementById("timeDisplay");
       const sun = document.getElementById("sun");

       function interpolateColor(color1, color2, factor) {
           const c1 = color1.match(/\d+/g).map(Number);
           const c2 = color2.match(/\d+/g).map(Number);
           const result = c1.map((c, i) => Math.round(c + factor * (c2[i] - c)));
           return `rgb(${result[0]}, ${result[1]}, ${result[2]})`;
       }

       function updateSunset(progress) {
           let totalMinutes = (progress / 100) * 1440;
           let hours = Math.floor(totalMinutes / 60);
           let minutes = Math.round(totalMinutes % 60);
           let formattedTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
           timeDisplay.textContent = formattedTime;

           // Ajustement de la position du soleil
           const sliderHeight = 30;  // Hauteur approximative du slider
           const textHeight = 15;    // Hauteur approximative du texte
           const sunOffset = 1;     // Un petit espace pour que le soleil soit au-dessus du texte à 100%

           // Position du soleil : à 0%, aligné avec le bas du slider
           // à 100%, juste au-dessus du texte, puis redescend en suivant le mouvement
           let sunY;
           if (progress <= 50) {
               // Montée du soleil de 0% à 50%
               sunY = (sliderHeight + sunOffset) - (progress / 50) * (sliderHeight + textHeight + sunOffset);
           } else {
               // Descente du soleil de 50% à 100%
               sunY = (sliderHeight + sunOffset) - ((100 - progress) / 50) * (sliderHeight + textHeight + sunOffset);
           }

           sun.style.top = `${sunY}px`;

           // Transition entre cercle et étoile
           const startStarProgress = (5 / 24) * 100; // 5h en pourcentage
           const endStarProgress = (22 / 24) * 100;  // 22h en pourcentage

           if (progress <= startStarProgress) {
               sun.classList.remove('star');
           } else if (progress > startStarProgress && progress < endStarProgress) {
               sun.classList.add('star');
               sun.style.setProperty('--opacity', (progress - startStarProgress) / (endStarProgress - startStarProgress));
           } else if (progress >= endStarProgress) {
               sun.classList.remove('star');
           }

           // Rotation de l'étoile
           const rotationDegrees = progress * 9; // 900° pour 100%
           sun.style.transform = `rotate(${rotationDegrees}deg)`;

           const colors = [
               "rgb(34, 32, 71)",
               "rgb(255, 151, 214)",
               "rgb(217, 123, 224)",
               "rgb(182, 98, 232)",
               "rgb(127, 58, 245)",
               "rgb(34, 32, 71)"
           ];

           let index = Math.floor((progress / 100) * (colors.length - 1));
           let blendFactor = (progress / 100) * (colors.length - 1) - index;
           let gradientColor = interpolateColor(colors[index], colors[index + 1], blendFactor);
           document.body.style.background = `linear-gradient(to bottom, ${gradientColor}, black)`;
       }

       function updateSliderBasedOnTime() {
           const now = new Date();
           const totalMinutes = now.getHours() * 60 + now.getMinutes();
           const progress = (totalMinutes / 1440) * 100;
           timeSlider.value = progress;
           updateSunset(progress);
       }

       timeSlider.addEventListener("input", (e) => {
           updateSunset(parseFloat(e.target.value));
       });

       updateSliderBasedOnTime();
   </script>
</body>
</html>

 

bottom of page