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

如何在HTML/CSS/JS中用对象作为遮罩实现标题颜色反转?

实现气泡过标题时颜色反转的效果

核心思路验证

你提到的三层结构思路完全可行,核心逻辑就是通过分层显示实现局部颜色反转:

  • 底层:深色标题(如黑色文字),z-index最低
  • 中间层:紫色气泡,作为视觉遮罩的参照
  • 顶层:浅色标题(如白色文字),仅在气泡覆盖区域显示,形成“反转”视觉效果

具体实现方案

1. 三层结构+动态遮罩实现(精准匹配需求)

HTML结构

<div class="title-wrapper">
  <!-- 底层深色标题 -->
  <h1 class="title title-dark">Bubble Reveal</h1>
  <!-- 气泡容器 -->
  <div class="bubble-container">
    <div class="bubble"></div>
    <div class="bubble"></div>
  </div>
  <!-- 顶层浅色标题 -->
  <h1 class="title title-light">Bubble Reveal</h1>
</div>

CSS基础样式

.title-wrapper {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
}

.title {
  position: absolute;
  font-size: 5rem;
  margin: 0;
  font-weight: bold;
}

.title-dark {
  color: #000;
  z-index: 1;
}

.title-light {
  color: #fff;
  z-index: 3;
  /* 初始遮罩为空,不显示 */
  mask: none;
  -webkit-mask: none;
}

.bubble-container {
  position: absolute;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none; /* 避免气泡阻挡页面交互 */
}

.bubble {
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: #9333ea; /* 紫色气泡 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

JavaScript动态控制遮罩

实时跟踪气泡位置,更新顶层标题的遮罩范围,只显示气泡覆盖区域:

const lightTitle = document.querySelector('.title-light');
const bubbles = document.querySelectorAll('.bubble');
const container = document.querySelector('.title-wrapper');

function updateTitleMask() {
  let maskPaths = [];
  bubbles.forEach(bubble => {
    const bubbleRect = bubble.getBoundingClientRect();
    const containerRect = container.getBoundingClientRect();
    // 计算气泡相对于容器的中心坐标和半径
    const centerX = bubbleRect.left - containerRect.left + bubbleRect.width / 2;
    const centerY = bubbleRect.top - containerRect.top + bubbleRect.height / 2;
    const radius = bubbleRect.width / 2;
    // 生成圆形遮罩路径
    maskPaths.push(`circle(${radius}px at ${centerX}px ${centerY}px)`);
  });
  // 合并所有气泡的遮罩路径
  const maskValue = maskPaths.join(', ');
  lightTitle.style.mask = maskValue;
  lightTitle.style.webkitMask = maskValue;
}

// 气泡移动动画
function animateBubbles() {
  bubbles.forEach(bubble => {
    // 随机移动速度和方向
    const speedX = (Math.random() - 0.5) * 3;
    const speedY = (Math.random() - 0.5) * 3;
    setInterval(() => {
      let currentTop = parseFloat(bubble.style.top) || 50;
      let currentLeft = parseFloat(bubble.style.left) || 50;
      
      currentTop += speedY;
      currentLeft += speedX;
      
      // 边界检测,防止气泡移出屏幕
      currentTop = Math.max(0, Math.min(100, currentTop));
      currentLeft = Math.max(0, Math.min(100, currentLeft));
      
      bubble.style.top = `${currentTop}%`;
      bubble.style.left = `${currentLeft}%`;
      
      // 实时更新遮罩
      updateTitleMask();
    }, 16); // 维持60fps动画流畅度
  });
}

// 启动动画
animateBubbles();

2. 混合模式简化方案(代码更简洁)

如果不需要极致精准的颜色控制,可以用mix-blend-mode: difference直接实现颜色反转,省去遮罩逻辑:

<div class="container">
  <h1 class="title">Bubble Reveal</h1>
  <div class="bubble-container">
    <div class="bubble"></div>
    <div class="bubble"></div>
  </div>
</div>
.container {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}

.title {
  font-size: 5rem;
  color: #fff;
  z-index: 1;
}

.bubble-container {
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

.bubble {
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: #9333ea;
  mix-blend-mode: difference; /* 核心混合模式 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

这种方式利用混合模式的颜色计算自动实现反转,代码更简洁,但颜色效果由混合规则决定,需要根据需求调整基础色值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:33:29