求助:实现环绕球体旋转的文字3D形变效果
实现球面3D旋转文字导航栏
问题
我正在制作一个圆形导航栏,鼠标悬浮时显示对应文字。目前布局已初步完成,但无法实现文字像刻在旋转球体上的3D形变效果——希望文字在远离视角时产生弯曲收缩,靠近视角时保持平整。
解决方案
要实现球面文字的3D形变,核心是利用CSS 3D变换的perspective(透视)、transform-style: preserve-3d(保留3D空间),并将文字拆分为单个字符,为每个字符设置对应的球面位置变换,配合父元素的旋转动画,模拟文字附着在球体表面的效果。
关键调整步骤:
- 为父容器添加透视和3D空间,让子元素的3D变换生效;
- 将导航文本拆成独立字符标签,方便单独控制每个字符的3D位置;
- 为单个字符设置球面变换,通过
rotateY和translateZ让字符分布在虚拟球面上; - 让包含字符的容器整体旋转,带动字符完成球面环绕效果。
修改后的完整代码
HTML
<div class="top-bar visible"> <div class="circle-container"> <div class="color-circle" style="background-color: rgb(227, 197, 103); width: 60px; height: 60px;"> <div class="orbit"> <div class="text-sphere"> <span class="char">H</span> <span class="char">O</span> <span class="char">M</span> <span class="char">E</span> </div> </div> </div> <div class="color-circle" style="background-color: rgb(200, 150, 62); width: 50px; height: 50px;"> <div class="orbit"> <div class="text-sphere"> <span class="char">D</span> <span class="char">E</span> <span class="char">V</span> <span class="char"> </span> <span class="char">&</span> <span class="char"> </span> <span class="char">D</span> <span class="char">E</span> <span class="char">S</span> <span class="char">I</span> <span class="char">G</span> <span class="char">N</span> </div> </div> </div> <div class="color-circle" style="background-color: rgb(87, 61, 28); width: 45px; height: 45px;"> <div class="orbit"> <div class="text-sphere"> <span class="char">A</span> <span class="char">C</span> <span class="char">T</span> <span class="char">I</span> <span class="char">N</span> <span class="char">G</span> </div> </div> </div> <div class="color-circle" style="background-color: rgb(217, 174, 97); width: 40px; height: 40px;"> <div class="orbit"> <div class="text-sphere"> <span class="char">F</span> <span class="char">I</span> <span class="char">L</span> <span class="char">M</span> <span class="char">M</span> <span class="char">A</span> <span class="char">K</span> <span class="char">I</span> <span class="char">N</span> <span class="char">G</span> </div> </div> </div> <div class="color-circle" style="background-color: rgb(209, 70, 47); width: 35px; height: 35px;"> <div class="orbit"> <div class="text-sphere"> <span class="char">G</span> <span class="char">A</span> <span class="char">L</span> <span class="char">L</span> <span class="char">E</span> <span class="char">R</span> <span class="char">Y</span> </div> </div> </div> </div> </div>
CSS
.color-circle { position: relative; border-radius: 50%; cursor: pointer; transition: transform 0.3s ease; /* 添加透视和3D空间 */ perspective: 200px; transform-style: preserve-3d; margin: 0 8px; display: inline-block; } .color-circle:hover { transform: scale(1.2); } .orbit { position: absolute; width: 100%; height: 100%; opacity: 0; transition: opacity 0.3s ease; transform-style: preserve-3d; } .color-circle:hover .orbit { opacity: 1; } .text-sphere { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); transform-style: preserve-3d; /* 容器整体旋转,带动字符环绕 */ animation: rotateSphere 4s linear infinite; } .char { position: absolute; color: white; font-size: 8px; font-weight: bold; text-shadow: 0 0 2px rgba(0, 0, 0, 0.5); transform-origin: center; } /* 根据字符数量自动计算每个字符的角度 */ .text-sphere .char:nth-child(1) { transform: rotateY(0deg) translateZ(25px); } .text-sphere .char:nth-child(2) { transform: rotateY(30deg) translateZ(25px); } .text-sphere .char:nth-child(3) { transform: rotateY(60deg) translateZ(25px); } .text-sphere .char:nth-child(4) { transform: rotateY(90deg) translateZ(25px); } .text-sphere .char:nth-child(5) { transform: rotateY(120deg) translateZ(25px); } .text-sphere .char:nth-child(6) { transform: rotateY(150deg) translateZ(25px); } .text-sphere .char:nth-child(7) { transform: rotateY(180deg) translateZ(25px); } .text-sphere .char:nth-child(8) { transform: rotateY(210deg) translateZ(25px); } .text-sphere .char:nth-child(9) { transform: rotateY(240deg) translateZ(25px); } .text-sphere .char:nth-child(10) { transform: rotateY(270deg) translateZ(25px); } .text-sphere .char:nth-child(11) { transform: rotateY(300deg) translateZ(25px); } .text-sphere .char:nth-child(12) { transform: rotateY(330deg) translateZ(25px); } @keyframes rotateSphere { from { transform: translate(-50%, -50%) rotateY(0deg); } to { transform: translate(-50%, -50%) rotateY(360deg); } }
JavaScript
document.querySelectorAll('.color-circle').forEach((circle, index) => { circle.addEventListener('click', () => { const text = Array.from(circle.querySelectorAll('.char')) .map(char => char.textContent) .join('') .replace(/\s+/g, ' '); alert(`Navigate to: ${text.trim()}`); }); });
效果说明
- 每个字符被放置在虚拟球面的不同角度,通过
rotateY和translateZ模拟球面位置; - 父容器
text-sphere旋转时,字符会沿着球面环绕,远离视角的字符会自然收缩(透视效果),靠近视角的字符保持清晰平整; - 可以根据文字长度调整
translateZ的数值和字符的角度间隔,适配不同大小的圆形导航。
内容的提问来源于stack exchange,提问作者mmkranz7
相关产品推荐
相关产品推荐

