CSS自定义光标文本旋转偏移修复:实现元素360度自旋转
修复自定义光标文本旋转偏移问题
当鼠标悬停在.box区域时,需要隐藏默认光标,显示由三角形、圆形和环绕文本组成的自定义光标,要求三者中心对齐且文本可360度自旋转。当前文本旋转存在偏移问题,以下是修复方案:
修复后的完整代码
HTML(无需修改)
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap" rel="stylesheet"> <link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'> <div class="container"> <h1>Custom Cursor</h1> <div class="box"> </div> </div> </div> <div class="btn"> <span style="--i:1">J</span> <span style="--i:2">o</span> <span style="--i:3">u</span> <span style="--i:4">e</span> <span style="--i:5">r</span> <span style="--i:6"> </span> <span style="--i:7">l</span> <span style="--i:8">a</span> <span style="--i:9"> </span> <span style="--i:10">v</span> <span style="--i:11">i</span> <span style="--i:12">d</span> <span style="--i:13">é</span> <span style="--i:14">o</span> <span style="--i:15"> </span> <span style="--i:16">-</span> <span style="--i:17"> </span> <span style="--i:18">J</span> <span style="--i:19">o</span> <span style="--i:20">u</span> <span style="--i:21">e</span> <span style="--i:22">r</span> <span style="--i:23"> </span> <span style="--i:24">l</span> <span style="--i:25">a</span> <span style="--i:26"> </span> <span style="--i:27">v</span> <span style="--i:28">i</span> <span style="--i:29">d</span> <span style="--i:30">é</span> <span style="--i:31">o</span> <span style="--i:32"> </span> <span style="--i:33">-</span> <span style="--i:34"> </span> <span style="--i:35">J</span> <span style="--i:36">o</span> <span style="--i:37">u</span> <span style="--i:38">e</span> <span style="--i:39">r</span> <span style="--i:40"> </span> <span style="--i:41">l</span> <span style="--i:42">a</span> <span style="--i:43"> </span> <span style="--i:44">v</span> <span style="--i:45">i</span> <span style="--i:46">d</span> <span style="--i:47">é</span> <span style="--i:48">o</span> <span style="--i:49"> </span> <span style="--i:50">-</span> <span style="--i:51"> </span> </div> <div class="triangle"></div> <div class="circle"></div>
CSS(修改核心样式)
body { background: red; height: 100vh; font-family: Bebas neue; display: flex; justify-content: center; align-items: center; margin: 0; } h1 { font-family: montserrat; font-size: 40px; } .container { display: flex; justify-content: center; align-items: center; height: 100vh; background-color: white; flex-direction: column; } .box { width: 800px; height: 450px; background-color: pink; border: 2px solid red; border-radius: 10px; display: flex; justify-content: center; align-items: center; } .box:hover { cursor: none; } .block { display: block !important; opacity: 1 !important; } .btn { width: 138px; height: 138px; font-weight: bold; font-size: 30px; position: fixed; animation: loading 6s linear infinite; opacity: 0; pointer-events: none; left: 50%; top: 50%; transform: translate(-50%, -50%); } .triangle { height: 0; width: 0; border-top: 40px solid transparent; border-bottom: 40px solid transparent; border-left: 60px solid white; position: fixed; pointer-events: none; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none; } .circle { border:1px solid white; width: 138px; height: 138px; border-radius: 50%; position: fixed; pointer-events: none; left: 50%; top: 50%; transform: translate(-50%, -50%); display: none; } .btn span { position: absolute; left: 50%; top: 0; transform-origin: 50% 69px; transform: translateX(-50%) rotateZ(calc(var(--i) * (360 / 51) * 1deg)); color: white; } @keyframes loading { 0% { transform: translate(-50%, -50%) rotate(0deg); } 100% { transform: translate(-50%, -50%) rotate(-360deg); } }
JavaScript(优化定位逻辑)
const box = document.querySelector(".box"); const btn = document.querySelector(".btn"); const circle = document.querySelector(".circle"); const triangle = document.querySelector(".triangle"); document.addEventListener("mousemove", function (e) { const x = e.clientX; const y = e.clientY; const translate = `translate(${x}px, ${y}px)`; triangle.style.transform = translate; circle.style.transform = translate; btn.style.transform = `${translate} rotate(-360deg)`; }); box.addEventListener("mouseenter", () => { triangle.classList.add("block"); circle.classList.add("block"); btn.classList.add("block"); }); box.addEventListener("mouseleave", () => { triangle.classList.remove("block"); circle.classList.remove("block"); btn.classList.remove("block"); });
关键修改说明
统一中心对齐
- 将三个光标元素的定位方式统一为
fixed,通过transform: translate(-50%, -50%)实现初始中心对齐,确保三者始终以鼠标位置为基准点。 - 替换原代码中
left/top直接赋值的方式,改用transform进行偏移,提升渲染性能同时避免布局偏移。
- 将三个光标元素的定位方式统一为
修复文本旋转偏移
- 调整
.btn span的transform-origin为容器中心(50% 69px,即138px容器的一半高度),让所有字符围绕中心旋转。 - 精确计算每个字符的旋转角度:
calc(var(--i) * (360 / 51) * 1deg),51为字符总数,保证360度均匀分布。 - 修正
.btn的动画逻辑,在旋转时保留居中偏移,避免旋转过程中容器位置偏移。
- 调整
优化事件监听
- 合并三个独立的
mousemove事件为一个,减少DOM事件监听次数,提升页面运行效率。
- 合并三个独立的
内容的提问来源于stack exchange,提问作者ZeroCool
相关产品推荐
相关产品推荐

