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

如何用CSS或JavaScript实现3×3盒子间的波浪线连接?

用CSS或JavaScript生成波浪线连接3×3盒子

一、CSS统一样式波浪线方案

如果只需要固定样式的波浪线,用CSS就能快速实现,无需额外资源。核心思路是利用背景渐变或遮罩生成重复波浪图案,定位在盒子之间的间隙处。

1. 基础横向/纵向波浪线实现

先完成3×3盒子的网格布局,再通过绝对定位的元素生成波浪线条:

<div class="grid-container">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="box">5</div>
  <div class="box">6</div>
  <div class="box">7</div>
  <div class="box">8</div>
  <div class="box">9</div>
  <!-- 横向连接线 -->
  <div class="wave-line horizontal" style="top: 33.33%; width: 100%"></div>
  <div class="wave-line horizontal" style="top: 66.66%; width: 100%"></div>
  <!-- 纵向连接线 -->
  <div class="wave-line vertical" style="left: 33.33%; height: 100%"></div>
  <div class="wave-line vertical" style="left: 66.66%; height: 100%"></div>
</div>
.grid-container {
  position: relative;
  width: 300px;
  height: 300px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 0;
}

.box {
  border: 1px solid #333;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  z-index: 1;
}

.wave-line {
  position: absolute;
  background-size: 20px 8px;
  z-index: 0;
}

.wave-line.horizontal {
  height: 8px;
  background-image: linear-gradient(45deg, transparent 33%, #333 33%, #333 66%, transparent 66%);
}

.wave-line.vertical {
  width: 8px;
  background-image: linear-gradient(135deg, transparent 33%, #333 33%, #333 66%, transparent 66%);
}

2. 圆润波浪线(CSS遮罩实现)

如果想要更自然的圆润波浪,可配合CSS遮罩调整:

.wave-line.horizontal {
  height: 10px;
  background: #333;
  -webkit-mask: repeating-linear-gradient(90deg, 
    transparent 0 10px, 
    white 10px 12px, 
    transparent 12px 22px);
  mask: repeating-linear-gradient(90deg, 
    transparent 0 10px, 
    white 10px 12px, 
    transparent 12px 22px);
}

修改遮罩里的数值就能调整波浪的疏密和高度。

二、JavaScript随机波浪线方案

如果需要每次刷新都生成不同样式的波浪,用JS结合Canvas动态绘制是最优解:

<div class="grid-container" id="grid">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="box">5</div>
  <div class="box">6</div>
  <div class="box">7</div>
  <div class="box">8</div>
  <div class="box">9</div>
  <canvas id="waveCanvas"></canvas>
</div>
.grid-container {
  position: relative;
  width: 300px;
  height: 300px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 0;
}

.box {
  border: 1px solid #333;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  z-index: 1;
}

#waveCanvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
const canvas = document.getElementById('waveCanvas');
const ctx = canvas.getContext('2d');
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;

// 获取每个盒子的中心坐标
const boxes = document.querySelectorAll('.box');
const boxPositions = Array.from(boxes).map(box => {
  const rect = box.getBoundingClientRect();
  const gridRect = document.getElementById('grid').getBoundingClientRect();
  return {
    x: rect.left - gridRect.left + rect.width/2,
    y: rect.top - gridRect.top + rect.height/2
  };
});

// 绘制随机波浪线的函数
function drawRandomWave(startX, startY, endX, endY) {
  ctx.beginPath();
  ctx.strokeStyle = '#333';
  ctx.lineWidth = 2;
  
  const dx = endX - startX;
  const dy = endY - startY;
  const length = Math.sqrt(dx*dx + dy*dy);
  const segments = Math.floor(length / 20);
  const amplitude = Math.random() * 8 + 4; // 随机振幅4-12px
  
  ctx.moveTo(startX, startY);
  for(let i = 1; i <= segments; i++) {
    const t = i / segments;
    const x = startX + dx * t;
    // 随机波浪方向和频率
    const y = startY + dy * t + Math.sin(t * Math.PI * 2 * (Math.random()*2+1)) * amplitude * (Math.random() > 0.5 ? 1 : -1);
    ctx.lineTo(x, y);
  }
  ctx.lineTo(endX, endY);
  ctx.stroke();
}

// 绘制纵向连接线(列与列之间)
for(let col = 0; col < 2; col++) {
  for(let row = 0; row < 3; row++) {
    const startIdx = row*3 + col;
    const endIdx = row*3 + col + 1;
    drawRandomWave(boxPositions[startIdx].x, boxPositions[startIdx].y, boxPositions[endIdx].x, boxPositions[endIdx].y);
  }
}

// 绘制横向连接线(行与行之间)
for(let row = 0; row < 2; row++) {
  for(let col = 0; col < 3; col++) {
    const startIdx = row*3 + col;
    const endIdx = (row+1)*3 + col;
    drawRandomWave(boxPositions[startIdx].x, boxPositions[startIdx].y, boxPositions[endIdx].x, boxPositions[endIdx].y);
  }
}

每次刷新页面,波浪的振幅、频率和方向都会随机变化,实现动态效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:35:19