Trying to get my nav bar to be a series of circles where if you hover over them it displays the text that goes with them. Heres what I have so far:
document.querySelectorAll('.color-circle').forEach((circle, index) => {
circle.addEventListener('click', () => {
alert(`Navigate to: ${circle.querySelector('.orbit-text').innerText}`);
});
});
.color-circle {
position: relative;
border-radius: 50%;
cursor: pointer;
transition: transform 0.3s ease;
}
.color-circle:hover {
transform: scale(1.2);
}
.orbit {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.3s ease;
}
.color-circle:hover .orbit {
opacity: 1;
animation: orbit 2s linear infinite;
}
.orbit-text {
position: absolute;
left: 50%;
top: 50%;
transform-origin: center;
transform: translate(-50%, -50%) rotateY(0deg);
color: white;
font-size: 8px;
font-weight: bold;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
animation: orbit3D 4s linear infinite;
}
@keyframes orbit3D {
from {
transform: translate(-50%, -50%) rotateY(0deg) translateZ(15px);
}
to {
transform: translate(-50%, -50%) rotateY(360deg) translateZ(15px);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
<div class="top-bar visible">
<div class="circle-container">
<div class="color-circle" style="background-color: rgb(227, 197, 103); width: 40px; height: 40px;">
<div class="orbit">
<span class="orbit-text">HOME</span>
</div>
</div>
<div class="color-circle" style="background-color: rgb(200, 150, 62); width: 30px; height: 30px;">
<div class="orbit">
<span class="orbit-text">DEV & DESIGN</span>
</div>
</div>
<div class="color-circle" style="background-color: rgb(87, 61, 28); width: 25px; height: 25px;">
<div class="orbit">
<span class="orbit-text">ACTING</span>
</div>
</div>
<div class="color-circle" style="background-color: rgb(217, 174, 97); width: 20px; height: 20px;">
<div class="orbit">
<span class="orbit-text">FILMMAKING</span>
</div>
</div>
<div class="color-circle" style="background-color: rgb(209, 70, 47); width: 15px; height: 15px;">
<div class="orbit">
<span class="orbit-text">GALLERY</span>
</div>
</div>
</div>
</div>
Spacing and other formatting isn't done but I am hitting a wall with having the text distort as if its curving when turned away and flatter when closer as if it was actually etched onto the rotating sphere.
Thanks!
Position the desired text on the bottom a "stick" DIV that is positioned at the center of the circle. Set the "stick" transformation origin to its top. Apply the needed rotations and counter-rotations, transform-style: preserve-3d;
, and the infinite rotation animation:
body { background: #343536; }
.color-circle {
position: relative;
width: calc(var(--size) * 1em);
aspect-ratio: 1;
background-color: var(--bg);
border-radius: 50%;
margin: 1em;
perspective: 220px;
transform-style: preserve-3d;
display: flex;
.orbit {
position: absolute;
left: 50%;
top: 50%;
background: #0006;
width: 2px;
height: calc(var(--size) / 2 * 1em + 1em);
display: flex;
transform-origin: 50% 0%;
transform-style: preserve-3d;
rotate: 1 0 0 90deg;
animation: orbit 4s linear infinite;
display: flex;
.orbit-text {
translate: -50% 50%;
align-self: flex-end;
/* white-space: nowrap; */
rotate: -1 0 0 90deg;
color: white;
font-size: 1rem;
font-weight: bold;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
}
}
}
@keyframes orbit {
to {
transform: rotate3d(0, 0, 1, 360deg);
}
}
<div class="color-circle" style="--size:4; --bg:#ec6;">
<div class="orbit">
<span class="orbit-text">HOME</span>
</div>
</div>
<div class="color-circle" style="--size:3.5; --bg:#c96;">
<div class="orbit">
<span class="orbit-text">DEV & DESIGN</span>
</div>
</div>
<div class="color-circle" style="--size:3; --bg:#754;">
<div class="orbit">
<span class="orbit-text">ACTING</span>
</div>
</div>
<div class="color-circle" style="--size:2.5; --bg:#da6;">
<div class="orbit">
<span class="orbit-text">FILMMAKING</span>
</div>
</div>
<div class="color-circle" style="--size:2; --bg:#d42;">
<div class="orbit">
<span class="orbit-text">GALLERY</span>
</div>
</div>
The code is inspired by this similar answer: Create a 3D asteroid belt.
What I would also do is: use white-space: nowrap;
on the text, create (with JS) separate SPAN elements for every character, add a CSS property --index
and rotate each SPAN element by the needed index degrees to make it look like every character orbits on its own. The only downside I guess would be using monospace font.