diff --git a/assets/icons/arrow-flip-hover.svg b/assets/icons/arrow-flip-hover.svg new file mode 100644 index 0000000000..01761f58a8 --- /dev/null +++ b/assets/icons/arrow-flip-hover.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/icons/arrow-flip.svg b/assets/icons/arrow-flip.svg index 923b513690..ee469c8cf2 100644 --- a/assets/icons/arrow-flip.svg +++ b/assets/icons/arrow-flip.svg @@ -1 +1,4 @@ - + + + + diff --git a/assets/icons/pause.svg b/assets/icons/pause.svg new file mode 100644 index 0000000000..bdc1f7df72 --- /dev/null +++ b/assets/icons/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/resume.svg b/assets/icons/resume.svg new file mode 100644 index 0000000000..9d1274a67e --- /dev/null +++ b/assets/icons/resume.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pages/features.html b/pages/features.html index 3dac145df7..2223e65ec7 100644 --- a/pages/features.html +++ b/pages/features.html @@ -49,6 +49,7 @@ width: 1200px; max-width: 1200px; } + @media (max-width: 1250px) { .feature-container { width: auto; @@ -56,6 +57,7 @@ padding-right: 16px; } } + @media (max-width: 900px) { .feature-container { width: auto; @@ -72,13 +74,16 @@ .feature-container.feature-container-2x { grid-template-columns: 1fr 1fr; } + .feature-container.feature-container-2x h3 { grid-column: span 2; } + @media (max-width: 1020px) { .feature-container.feature-container-2x { grid-template-columns: 1fr; } + .feature-container.feature-container-2x h3 { grid-column: span 1; } @@ -87,21 +92,26 @@ .feature-container.feature-container-3x { grid-template-columns: 1fr 1fr 1fr; } + .feature-container.feature-container-3x h3 { grid-column: span 3; } + @media (max-width: 1020px) { .feature-container.feature-container-3x { grid-template-columns: 1fr 1fr; } + .feature-container.feature-container-3x h3 { grid-column: span 2; } } + @media (max-width: 800px) { .feature-container.feature-container-3x { grid-template-columns: 1fr; } + .feature-container.feature-container-3x h3 { grid-column: span 1; } @@ -113,6 +123,7 @@ padding: 20px; transition: 0.1s filter; } + .feature-card:hover { filter: brightness(112.5%); } @@ -183,6 +194,7 @@ aspect-ratio: 16/9; margin: 100px 0 60px 0; } + @media (max-width: 540px) { .showcase-carousel { margin-top: 60px; @@ -203,7 +215,7 @@ position: absolute; top: 50%; left: 12px; - width: 20px; + width: 36px; height: 36px; transform: translateY(-50%); background-image: url('/assets/icons/arrow-flip.svg'); @@ -213,13 +225,19 @@ filter: drop-shadow(var(--more-shadow)); z-index: 5; } + .showcase-flip-left { transform: translateY(-50%) scaleX(-1.0); } + .showcase-flip-right { left: auto; right: 12px; } + .showcase-flip-left:hover, + .showcase-flip-right:hover { + background-image: url('/assets/icons/arrow-flip-hover.svg') ; + } .showcase-items { position: relative; @@ -236,6 +254,7 @@ width: 100%; height: 100%; } + .showcase-item-transition { transition: transform 0.4s ease-in-out, z-index 0.1s linear 0.4s; } @@ -248,8 +267,10 @@ position: absolute; bottom: 12px; right: 16px; - background: var(--hero-text-background-color); + background: rgba(26, 26, 26, 0.7); + border-radius: 8px; + padding: 2px 10px; } @@ -259,14 +280,56 @@ } .showcase-author { - color: #b3c1df; + color: #dde1ed; font-size: 95%; - opacity: 0.9; + opacity: 1; } .showcase-credits a { text-decoration: none; } + + .carousel-dot { + display: inline-block; + width: 10px; + height: 10px; + margin: 0 4px; + border-radius: 50%; + background-color: #8d8d8d; + cursor: pointer; + transition: background-color 0.3s ease; + } + + .carousel-dot.active { + background-color: white; + } + + .carousel-play-toggle { + position: absolute; + bottom: 12px; + left: 12px; + width: 32px; + height: 32px; + background-color: rgba(0, 0, 0, 0.6); + border: none; + border-radius: 8px; + padding: 4px; + cursor: pointer; + z-index: 6; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.3s ease; + } + + .carousel-play-toggle:hover { + background-color: rgba(255, 255, 255, 0.12); + } + + .carousel-play-toggle img { + width: 24px; + height: 24px; + }
@@ -294,8 +357,13 @@

const showcaseItems = document.querySelectorAll('.showcase-item'); let currentIndex = Math.floor(Math.random() * showcaseItems.length); - + let isAnimating = false; + const carouselDots = document.querySelectorAll('.carousel-dot'); const setItemByIndex = (itemIndex, firstTime = false) => { + if (isAnimating && !firstTime) { + return; + } + isAnimating = true; const prevIndex = wrapIndex(currentIndex - 1); const nextIndex = wrapIndex(currentIndex + 1); @@ -321,26 +389,85 @@

item.style.zIndex = '3'; item.style.transform = 'translateX(100%)'; } - else { + else { item.classList.remove('showcase-item-transition'); item.style.zIndex = '1'; item.style.transform = 'translateX(0)'; } }); + carouselDots.forEach((dot, index) => { + dot.classList.toggle('active', index === itemIndex); + }); + if (!firstTime) { + setTimeout(() => { + isAnimating = false; + }, 400); + return; + } + + isAnimating = false; } setItemByIndex(currentIndex, true); - + let autoScrollTimeout; + + const resetAutoScroll = () => { + clearInterval(autoScrollInterval); + clearTimeout(autoScrollTimeout); + autoScrollTimeout = setTimeout(() => { + startAutoScroll(); + }, 1000); + }; const prevItemButton = document.querySelector('.showcase-flip-left'); prevItemButton.addEventListener('click', () => { + if (isAnimating) { + return; + } currentIndex = wrapIndex(currentIndex - 1); setItemByIndex(currentIndex); + resetAutoScroll(); }); const nextItemButton = document.querySelector('.showcase-flip-right'); nextItemButton.addEventListener('click', () => { + if (isAnimating) { + return; + } currentIndex = wrapIndex(currentIndex + 1); setItemByIndex(currentIndex); + resetAutoScroll(); }); + let autoScrollInterval; + let isPlaying = true; + const playToggleBtn = document.getElementById('carousel-play-toggle'); + const playIcon = document.getElementById('carousel-play-icon'); + + const startAutoScroll = () => { + autoScrollInterval = setInterval(() => { + currentIndex = wrapIndex(currentIndex + 1); + setItemByIndex(currentIndex); + }, 6000); + isPlaying = true; + playIcon.src = '/assets/icons/pause.svg'; + playIcon.alt = 'Pause'; + }; + + const stopAutoScroll = () => { + clearInterval(autoScrollInterval); + isPlaying = false; + playIcon.src = '/assets/icons/resume.svg'; + playIcon.alt = 'Play'; + }; + + playToggleBtn.addEventListener('click', () => { + if (isPlaying) { + stopAutoScroll(); + return; + } + startAutoScroll(); + }); + startAutoScroll(); }); + + @@ -363,6 +491,17 @@

+ + +

+ @@ -436,7 +575,9 @@

Leverage your C# experience to feel right at home

them a performance boost, while still benefiting from close engine integration.

Note: .NET support is provided as a dedicated engine executable. -
C# support is available for desktop and mobile platforms as of Godot 4.2. + C# + support is available for desktop and mobile platforms as of Godot 4.2. Web support should be added in the future, but until then, Godot 3 remains a supported option.

@@ -616,7 +757,8 @@

Find the logic behind any system in an open source codebase

- + View a complete list of features