You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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");
});

关键修改说明

  1. 统一中心对齐

    • 将三个光标元素的定位方式统一为fixed,通过transform: translate(-50%, -50%)实现初始中心对齐,确保三者始终以鼠标位置为基准点。
    • 替换原代码中left/top直接赋值的方式,改用transform进行偏移,提升渲染性能同时避免布局偏移。
  2. 修复文本旋转偏移

    • 调整.btn span的transform-origin为容器中心(50% 69px,即138px容器的一半高度),让所有字符围绕中心旋转。
    • 精确计算每个字符的旋转角度:calc(var(--i) * (360 / 51) * 1deg),51为字符总数,保证360度均匀分布。
    • 修正.btn的动画逻辑,在旋转时保留居中偏移,避免旋转过程中容器位置偏移。
  3. 优化事件监听

    • 合并三个独立的mousemove事件为一个,减少DOM事件监听次数,提升页面运行效率。

内容的提问来源于stack exchange,提问作者ZeroCool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:25:24