From 55a13e01832bc73e9433b76a8b9f3936af065b6d Mon Sep 17 00:00:00 2001 From: Dorian Date: Wed, 18 Feb 2026 10:42:38 +0000 Subject: [PATCH] Enhance SplashScreen with interactive logo visualization - Added hover effects to the tap-to-start logo, displaying an audio visualization ring on mouse enter and leave. - Introduced new CSS styles for the visualization ring and segments, including animations for a dynamic user experience. - Updated component logic to manage hover state, improving interactivity and engagement on the SplashScreen. --- neode-ui/src/components/SplashScreen.vue | 72 +++++++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/neode-ui/src/components/SplashScreen.vue b/neode-ui/src/components/SplashScreen.vue index 549f02b8..6bd912c5 100644 --- a/neode-ui/src/components/SplashScreen.vue +++ b/neode-ui/src/components/SplashScreen.vue @@ -105,7 +105,7 @@ >
Enter the Exit @@ -113,7 +113,21 @@
@@ -152,6 +166,7 @@ const BLINK_AFTER_TYPING = 1500 const showSplash = ref(true) const showTapToStart = ref(true) const tapStartTransitioning = ref(false) +const introLogoHover = ref(false) const backgroundOpacity = ref(0) const alienIntroComplete = ref(false) const fadeAlienIntro = ref(false) @@ -621,17 +636,68 @@ onBeforeUnmount(() => { position: absolute; z-index: 0; pointer-events: none; + color: rgba(0, 0, 0, 0.35); + animation: tap-to-start-text-pulse 4s ease-in-out infinite; +} +@keyframes tap-to-start-text-pulse { + 0%, 100% { color: rgba(0, 0, 0, 0.3); } + 50% { color: rgba(0, 0, 0, 0.5); } } .tap-to-start-logo { position: relative; z-index: 1; -} -.tap-to-start-logo { filter: drop-shadow(0 0 40px rgba(255, 255, 255, 0.15)); + overflow: visible; } +.intro-logo-viz-ring { + position: absolute; + left: 50%; + top: 50%; + width: 1px; + height: 1px; + transform: translate(-50%, -50%); + z-index: 0; + pointer-events: none; + opacity: 0; + transition: opacity 0.35s ease; + --viz-radius: 7rem; +} +.intro-logo-viz-ring.intro-logo-viz-visible { + opacity: 1; +} +.intro-logo-viz-segment { + position: absolute; + left: 50%; + top: 50%; + width: 4px; + height: 24px; + margin-left: -2px; + margin-top: -12px; + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.15)); + border-radius: 2px; + transform-origin: center center; + transform: rotate(var(--segment-deg)) translateY(calc(-1 * var(--viz-radius))); + animation: intro-viz-pulse 2.5s ease-in-out infinite; + animation-delay: calc(var(--segment-index, 0) * 0.02s); +} +@keyframes intro-viz-pulse { + 0%, 100% { opacity: 0.4; transform: rotate(var(--segment-deg)) translateY(calc(-1 * var(--viz-radius))) scaleY(0.5); } + 50% { opacity: 1; transform: rotate(var(--segment-deg)) translateY(calc(-1 * var(--viz-radius))) scaleY(1); } +} +@media (min-width: 640px) { + .intro-logo-viz-ring { --viz-radius: 8rem; } + .intro-logo-viz-segment { height: 26px; margin-top: -13px; } +} +@media (min-width: 768px) { + .intro-logo-viz-ring { --viz-radius: 9rem; } + .intro-logo-viz-segment { height: 28px; margin-top: -14px; } +} + .tap-to-start-logo :deep(.logo-gradient-border) { width: 12rem; height: 12rem; + position: relative; + z-index: 1; } @media (min-width: 640px) { .tap-to-start-content {