From bfe2bf8bf1bd5784c89941959e85bdb16dfcfbe8 Mon Sep 17 00:00:00 2001 From: Matt Batchelder Date: Fri, 20 Feb 2026 23:20:52 -0500 Subject: [PATCH] Add orbit circles animation to hero section for enhanced visual effects --- theme/assets/css/main.css | 129 +++++++++++++++++++++++++++++++++----- theme/blocks/index.php | 17 +++++ 2 files changed, 132 insertions(+), 14 deletions(-) diff --git a/theme/assets/css/main.css b/theme/assets/css/main.css index 416d36e..12b2859 100644 --- a/theme/assets/css/main.css +++ b/theme/assets/css/main.css @@ -2011,12 +2011,55 @@ p:last-child { margin-bottom: 0; } 100% { transform: translateY(var(--p-ty, -100vh)) translateX(var(--p-tx, 40px)) scale(var(--p-scale-end, 0.3)); opacity: 0; } } +/* Horizontal sway layered onto particle float */ +@keyframes particle-sway { + 0%, 100% { margin-left: 0; } + 25% { margin-left: var(--p-sway, 20px); } + 75% { margin-left: calc(var(--p-sway, 20px) * -1); } +} + @keyframes glow-drift { 0% { transform: translate(-50%, -50%) scale(1); opacity: 0.3; } 50% { transform: translate(-40%, -60%) scale(1.2); opacity: 0.5; } 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.3; } } +/* Orbit / wander keyframes for decorative circles */ +@keyframes circle-orbit-1 { + 0% { transform: translate(0, 0) scale(1); } + 25% { transform: translate(80px, -60px) scale(1.1); } + 50% { transform: translate(-40px, -120px) scale(0.95); } + 75% { transform: translate(-100px, -30px) scale(1.05); } + 100% { transform: translate(0, 0) scale(1); } +} +@keyframes circle-orbit-2 { + 0% { transform: translate(0, 0) scale(1); } + 25% { transform: translate(-70px, 50px) scale(1.08); } + 50% { transform: translate(60px, 90px) scale(0.9); } + 75% { transform: translate(100px, -40px) scale(1.12); } + 100% { transform: translate(0, 0) scale(1); } +} +@keyframes circle-orbit-3 { + 0% { transform: translate(0, 0) scale(1); } + 33% { transform: translate(120px, 30px) scale(1.15); } + 66% { transform: translate(-60px, -80px) scale(0.85); } + 100% { transform: translate(0, 0) scale(1); } +} +@keyframes circle-orbit-4 { + 0% { transform: translate(0, 0) scale(1); } + 20% { transform: translate(-50px, -90px) scale(1.1); } + 40% { transform: translate(90px, -50px) scale(0.92); } + 60% { transform: translate(40px, 70px) scale(1.08); } + 80% { transform: translate(-80px, 40px) scale(0.95); } + 100% { transform: translate(0, 0) scale(1); } +} +@keyframes circle-orbit-5 { + 0% { transform: translate(0, 0) scale(1); } + 30% { transform: translate(60px, 80px) scale(1.05); } + 60% { transform: translate(-90px, 20px) scale(1.1); } + 100% { transform: translate(0, 0) scale(1); } +} + /* Particle container */ .hero-particles { position: absolute; @@ -2031,23 +2074,71 @@ p:last-child { margin-bottom: 0; } position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.12); - animation: particle-float var(--p-dur, 18s) var(--p-delay, 0s) linear infinite; + animation: + particle-float var(--p-dur, 18s) var(--p-delay, 0s) linear infinite, + particle-sway var(--p-sway-dur, 6s) var(--p-delay, 0s) ease-in-out infinite; will-change: transform, opacity; } /* 12 particles with unique positions, sizes, speeds, and trajectories */ -.hero-particle--1 { --p-dur: 22s; --p-delay: 0s; --p-tx: 60px; --p-ty: -110vh; --p-opacity: 0.35; --p-scale-end: 0.2; width: 8px; height: 8px; bottom: -10px; left: 8%; } -.hero-particle--2 { --p-dur: 28s; --p-delay: 3s; --p-tx: -40px; --p-ty: -105vh; --p-opacity: 0.25; --p-scale-end: 0.4; width: 14px; height: 14px; bottom: -20px; left: 20%; } -.hero-particle--3 { --p-dur: 20s; --p-delay: 1s; --p-tx: 80px; --p-ty: -115vh; --p-opacity: 0.3; --p-scale-end: 0.3; width: 6px; height: 6px; bottom: -8px; left: 35%; } -.hero-particle--4 { --p-dur: 26s; --p-delay: 5s; --p-tx: -60px; --p-ty: -100vh; --p-opacity: 0.4; --p-scale-end: 0.2; width: 10px; height: 10px; bottom: -12px; left: 50%; } -.hero-particle--5 { --p-dur: 24s; --p-delay: 2s; --p-tx: 30px; --p-ty: -108vh; --p-opacity: 0.2; --p-scale-end: 0.5; width: 20px; height: 20px; bottom: -25px; left: 65%; background: rgba(var(--color-primary-rgb),0.12); } -.hero-particle--6 { --p-dur: 30s; --p-delay: 7s; --p-tx: -20px; --p-ty: -112vh; --p-opacity: 0.35; --p-scale-end: 0.3; width: 12px; height: 12px; bottom: -15px; left: 78%; } -.hero-particle--7 { --p-dur: 19s; --p-delay: 4s; --p-tx: 50px; --p-ty: -106vh; --p-opacity: 0.2; --p-scale-end: 0.4; width: 16px; height: 16px; bottom: -20px; left: 90%; background: rgba(var(--color-primary-rgb),0.08); } -.hero-particle--8 { --p-dur: 25s; --p-delay: 6s; --p-tx: -70px; --p-ty: -102vh; --p-opacity: 0.3; --p-scale-end: 0.2; width: 7px; height: 7px; bottom: -10px; left: 15%; } -.hero-particle--9 { --p-dur: 32s; --p-delay: 8s; --p-tx: 45px; --p-ty: -110vh; --p-opacity: 0.15; --p-scale-end: 0.6; width: 24px; height: 24px; bottom: -30px; left: 42%; background: rgba(var(--color-primary-rgb),0.08); } -.hero-particle--10 { --p-dur: 21s; --p-delay: 10s; --p-tx: -35px; --p-ty: -108vh; --p-opacity: 0.3; --p-scale-end: 0.3; width: 9px; height: 9px; bottom: -12px; left: 58%; } -.hero-particle--11 { --p-dur: 27s; --p-delay: 12s; --p-tx: 25px; --p-ty: -104vh; --p-opacity: 0.2; --p-scale-end: 0.4; width: 18px; height: 18px; bottom: -22px; left: 72%; background: rgba(var(--color-primary-rgb),0.06); } -.hero-particle--12 { --p-dur: 23s; --p-delay: 9s; --p-tx: -55px; --p-ty: -106vh; --p-opacity: 0.25; --p-scale-end: 0.3; width: 11px; height: 11px; bottom: -14px; left: 5%; } +.hero-particle--1 { --p-dur: 22s; --p-delay: 0s; --p-tx: 60px; --p-ty: -110vh; --p-opacity: 0.35; --p-scale-end: 0.2; --p-sway: 15px; --p-sway-dur: 5s; width: 8px; height: 8px; bottom: -10px; left: 8%; } +.hero-particle--2 { --p-dur: 28s; --p-delay: 3s; --p-tx: -40px; --p-ty: -105vh; --p-opacity: 0.25; --p-scale-end: 0.4; --p-sway: 25px; --p-sway-dur: 7s; width: 14px; height: 14px; bottom: -20px; left: 20%; } +.hero-particle--3 { --p-dur: 20s; --p-delay: 1s; --p-tx: 80px; --p-ty: -115vh; --p-opacity: 0.3; --p-scale-end: 0.3; --p-sway: 12px; --p-sway-dur: 4s; width: 6px; height: 6px; bottom: -8px; left: 35%; } +.hero-particle--4 { --p-dur: 26s; --p-delay: 5s; --p-tx: -60px; --p-ty: -100vh; --p-opacity: 0.4; --p-scale-end: 0.2; --p-sway: 30px; --p-sway-dur: 8s; width: 10px; height: 10px; bottom: -12px; left: 50%; } +.hero-particle--5 { --p-dur: 24s; --p-delay: 2s; --p-tx: 30px; --p-ty: -108vh; --p-opacity: 0.2; --p-scale-end: 0.5; --p-sway: 20px; --p-sway-dur: 6s; width: 20px; height: 20px; bottom: -25px; left: 65%; background: rgba(var(--color-primary-rgb),0.12); } +.hero-particle--6 { --p-dur: 30s; --p-delay: 7s; --p-tx: -20px; --p-ty: -112vh; --p-opacity: 0.35; --p-scale-end: 0.3; --p-sway: 18px; --p-sway-dur: 5.5s; width: 12px; height: 12px; bottom: -15px; left: 78%; } +.hero-particle--7 { --p-dur: 19s; --p-delay: 4s; --p-tx: 50px; --p-ty: -106vh; --p-opacity: 0.2; --p-scale-end: 0.4; --p-sway: 22px; --p-sway-dur: 7.5s; width: 16px; height: 16px; bottom: -20px; left: 90%; background: rgba(var(--color-primary-rgb),0.08); } +.hero-particle--8 { --p-dur: 25s; --p-delay: 6s; --p-tx: -70px; --p-ty: -102vh; --p-opacity: 0.3; --p-scale-end: 0.2; --p-sway: 10px; --p-sway-dur: 4.5s; width: 7px; height: 7px; bottom: -10px; left: 15%; } +.hero-particle--9 { --p-dur: 32s; --p-delay: 8s; --p-tx: 45px; --p-ty: -110vh; --p-opacity: 0.15; --p-scale-end: 0.6; --p-sway: 35px; --p-sway-dur: 9s; width: 24px; height: 24px; bottom: -30px; left: 42%; background: rgba(var(--color-primary-rgb),0.08); } +.hero-particle--10 { --p-dur: 21s; --p-delay: 10s; --p-tx: -35px; --p-ty: -108vh; --p-opacity: 0.3; --p-scale-end: 0.3; --p-sway: 16px; --p-sway-dur: 6.5s; width: 9px; height: 9px; bottom: -12px; left: 58%; } +.hero-particle--11 { --p-dur: 27s; --p-delay: 12s; --p-tx: 25px; --p-ty: -104vh; --p-opacity: 0.2; --p-scale-end: 0.4; --p-sway: 28px; --p-sway-dur: 8.5s; width: 18px; height: 18px; bottom: -22px; left: 72%; background: rgba(var(--color-primary-rgb),0.06); } +.hero-particle--12 { --p-dur: 23s; --p-delay: 9s; --p-tx: -55px; --p-ty: -106vh; --p-opacity: 0.25; --p-scale-end: 0.3; --p-sway: 14px; --p-sway-dur: 5s; width: 11px; height: 11px; bottom: -14px; left: 5%; } + +/* Orbit circle container */ +.hero-orbit-circles { + position: absolute; + inset: 0; + overflow: hidden; + z-index: 0; + pointer-events: none; +} + +/* Individual orbit circles */ +.hero-orbit-circle { + position: absolute; + border-radius: 50%; + background: rgba(var(--color-primary-rgb), 0.05); + will-change: transform; +} + +.hero-orbit-circle--1 { + width: 300px; height: 300px; + top: -5%; left: -5%; + animation: circle-orbit-1 25s ease-in-out infinite; +} +.hero-orbit-circle--2 { + width: 200px; height: 200px; + top: 60%; right: -3%; + background: rgba(var(--color-accent-rgb), 0.04); + animation: circle-orbit-2 30s ease-in-out infinite; +} +.hero-orbit-circle--3 { + width: 160px; height: 160px; + top: 20%; left: 55%; + animation: circle-orbit-3 22s ease-in-out infinite; +} +.hero-orbit-circle--4 { + width: 240px; height: 240px; + bottom: -8%; left: 30%; + background: rgba(var(--color-primary-rgb), 0.035); + animation: circle-orbit-4 28s ease-in-out infinite; +} +.hero-orbit-circle--5 { + width: 120px; height: 120px; + top: 10%; right: 20%; + background: rgba(var(--color-accent-rgb), 0.04); + animation: circle-orbit-5 20s ease-in-out infinite; +} /* Ambient glow effect behind content */ .hero-animated__glow { @@ -2060,6 +2151,7 @@ p:last-child { margin-bottom: 0; } background: rgba(var(--color-primary-rgb), 0.06); z-index: 1; pointer-events: none; + animation: glow-drift 12s ease-in-out infinite; } /* Animated hero layout - centered single-column content */ @@ -2106,6 +2198,7 @@ p:last-child { margin-bottom: 0; } position: relative; } .page-hero-animated .hero-particles { z-index: 0; } +.page-hero-animated .hero-orbit-circles { z-index: 0; } .page-hero-animated .hero-animated__glow { z-index: 0; } .page-hero-animated .hero-overlay { z-index: 1; } .page-hero-animated .container { position: relative; z-index: 2; } @@ -2113,7 +2206,8 @@ p:last-child { margin-bottom: 0; } /* Reduce motion for accessibility */ @media (prefers-reduced-motion: reduce) { .hero-particle, - .hero-animated__glow { + .hero-animated__glow, + .hero-orbit-circle { animation: none; opacity: var(--p-opacity, 0.2); } @@ -2576,6 +2670,13 @@ p:last-child { margin-bottom: 0; } [data-theme="dark"] .hero-animated__glow { background: rgba(var(--color-primary-rgb), 0.08); } +[data-theme="dark"] .hero-orbit-circle { + background: rgba(var(--color-primary-rgb), 0.06); +} +[data-theme="dark"] .hero-orbit-circle--2, +[data-theme="dark"] .hero-orbit-circle--5 { + background: rgba(var(--color-accent-rgb), 0.05); +} [data-theme="dark"] .site-footer { background: #0D0D0D; } diff --git a/theme/blocks/index.php b/theme/blocks/index.php index 26ffcd3..3c23eab 100644 --- a/theme/blocks/index.php +++ b/theme/blocks/index.php @@ -1492,12 +1492,28 @@ function oribi_render_particles( $count = 12 ) { return $html; } +/** + * Render decorative orbit circles that drift around the hero. + * + * @param int $count Number of circles (default 5). + * @return string Rendered HTML. + */ +function oribi_render_orbit_circles( $count = 5 ) { + $html = ''; + return $html; +} + /* ── Animated Hero (homepage) ──────────────────────────────────────────────── */ function oribi_render_hero_animated( $a ) { ob_start(); ?>
+
@@ -1538,6 +1554,7 @@ function oribi_render_page_hero_animated( $a ) { ob_start(); ?>
+