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

如何实现文字常态渐变+鼠标悬浮单个字母显示30px圆形渐变效果?

问题描述
  • 需求场景:
    • 常态(未悬浮)下文字采用渐变色彩
    • 鼠标悬浮任意字母时,该字母区域显示30px*30px的圆形渐变,渐变规则为 linear-gradient(180deg, rgba(255, 33, 44, 0.5) 0%, rgba(25, 50, 25, 0.3) 100%)
  • 当前遇到的问题:
    1. 若将圆形的fill设为transparent,鼠标事件会失效
    2. 文字常态使用渐变后,悬浮时无法触发颜色变化
当前实现的问题分析
  1. 鼠标事件失效原因:.cursor设置了pointer-events: none,导致自定义光标元素完全无法接收鼠标事件;同时如果将圆形fill设为transparent,SVG元素会失去可交互的点击区域。
  2. 悬浮无反应原因:当前代码未给单个字母绑定hover事件,且文字使用background-clip: text后,直接修改color无法生效,自定义光标与文字的交互逻辑也未关联。
解决方案

核心思路

  • 将每个字母拆为独立<span>,实现精准的hover监听
  • 用极低透明度填充替代transparent,既保证视觉透明,又保留鼠标交互区域
  • 通过切换自定义光标的类名来触发圆形渐变效果,同时可同步调整文字渐变

修改后的完整代码

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<div class="cursor">
  <div class="cursor__ball cursor__ball--big">
    <svg height="30" width="30">
      <!-- 定义悬浮时的渐变 -->
      <defs>
        <linearGradient id="hoverGradient" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" style="stop-color:rgba(255,33,44,0.5);stop-opacity:1" />
          <stop offset="100%" style="stop-color:rgba(25,50,25,0.3);stop-opacity:1" />
        </linearGradient>
      </defs>
      <circle cx="15" cy="15" r="12" stroke-width="0"></circle>
    </svg>
  </div>
</div>

<div class="myText">
  <h1>
    <span class="color-letter">G</span>
    <span class="color-letter">e</span>
    <span class="color-letter">t</span>
    <span class="color-letter">&nbsp;</span>
    <span class="color-letter">t</span>
    <span class="color-letter">o</span>
    <span class="color-letter">&nbsp;</span>
    <span class="color-letter">k</span>
    <span class="color-letter">n</span>
    <span class="color-letter">o</span>
    <span class="color-letter">w</span>
    <span class="color-letter">&nbsp;</span>
    <span class="color-letter">m</span>
    <span class="color-letter">o</span>
    <span class="color-letter">r</span>
    <span class="color-letter">e</span>
    <span class="color-letter">&nbsp;</span>
    <span class="color-letter">a</span>
    <span class="color-letter">b</span>
    <span class="color-letter">o</span>
    <span class="color-letter">u</span>
    <span class="color-letter">t</span>
  </h1>
</div>

CSS

body {
  height: 100vh;
  background: #010101;
  cursor: none;
  margin: 0;
  display: flex;
  font-family: monospace;
  align-items: center;
  justify-content: center;
}

body .cursor {
  z-index: 999;
}

body .cursor__ball {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
}

body .cursor__ball circle {
  /* 极低透明度填充,保证鼠标事件可触发 */
  fill: rgba(0,0,0,0.01);
}

/* 悬浮字母时的光标渐变样式 */
body .cursor__ball--hover circle {
  fill: url(#hoverGradient);
}

body .myText {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1001; /* 确保文字能触发hover事件 */
}

body .myText h1 {
  font-size: 80px;
  margin: 0;
}

body .myText h1 .color-letter {
  opacity: 0.8;
  background: linear-gradient(180deg, rgba(26, 33, 44, 0.5) 0%, rgba(255, 255, 255, 0.3) 100%);
  background-clip: text;
  -webkit-background-clip: text;
  position: relative;
  color: transparent;
  transition: all 0.3s ease;
  display: inline-block; /* 确保单个字母能接收鼠标事件 */
}

JS

const bigBall = document.querySelector(".cursor__ball--big");
const letters = document.querySelectorAll(".color-letter");

// 移动光标
document.body.addEventListener("mousemove", onMouseMove);

function onMouseMove(e) {
  TweenMax.to(bigBall, 0.4, {
    x: e.pageX - 15,
    y: e.pageY - 15,
  });
}

// 绑定单个字母的hover事件
letters.forEach(letter => {
  letter.addEventListener("mouseenter", () => {
    bigBall.classList.add("cursor__ball--hover");
    // 可选:同步修改文字渐变
    letter.style.background = "linear-gradient(180deg, rgba(255,255,255,0.8) 0%, rgba(26,33,44,0.6) 100%)";
    letter.style.backgroundClip = "text";
    letter.style.webkitBackgroundClip = "text";
  });
  
  letter.addEventListener("mouseleave", () => {
    bigBall.classList.remove("cursor__ball--hover");
    // 恢复原文字渐变
    letter.style.background = "linear-gradient(180deg, rgba(26, 33, 44, 0.5) 0%, rgba(255, 255, 255, 0.3) 100%)";
    letter.style.backgroundClip = "text";
    letter.style.webkitBackgroundClip = "text";
  });
});

关键说明

  • 用rgba(0,0,0,0.01)替代transparent,既视觉透明又保留SVG的鼠标交互区域
  • 拆分字母为独立<span>,实现精准的hover触发
  • 通过SVG的<defs>定义渐变,避免重复代码;也可将光标改为div,直接用CSS背景渐变实现
  • 调整z-index确保文字能触发hover事件,同时光标显示在文字上方

内容的提问来源于stack exchange,提问作者h.m.p.frontendDeveloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:52:32