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

如何使用jQuery实现鼠标悬停时连接Div的Stroke从0到100%的绘制动画

实现Div连接线条的悬停绘制动画

要实现鼠标悬停元素时,连接线条从0%逐步绘制到100%的效果,我们可以通过两种方案来实现:一种基于你现有的div线条结构调整,另一种是改用SVG线条(更适合任意方向的线条动画)。


方案1:基于现有Div线条的动画实现

如果希望保留当前的div线条结构,可以通过伪元素和CSS过渡来模拟绘制效果:

1. 调整CSS样式

先给线条设置基础样式,用伪元素作为动画载体:

.line {
  position: absolute;
  background: transparent; /* 移除原有背景,用伪元素实现线条 */
  overflow: hidden;
}

/* 水平线条动画 */
.line::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 100%;
  background: #000; /* 线条颜色 */
  transition: width 0.6s ease; /* 动画时长和缓动效果 */
}

/* 垂直线条动画 */
.line.vertical::before {
  width: 100%;
  height: 0;
  transition: height 0.6s ease;
}

/* 悬停触发动画 */
.line.hovered::before {
  width: 100%;
}
.line.vertical.hovered::before {
  height: 100%;
}

2. 完善JS逻辑

在adjustLine函数中,判断线条方向并添加对应类,同时绑定悬停事件:

function adjustLine(from, to, line) {
  if (from.length === 0 || to.length === 0 || line.length === 0) {
    return;
  }
  
  const fromRect = from[0].getBoundingClientRect();
  const toRect = to[0].getBoundingClientRect();
  
  // 计算线条位置、尺寸,判断方向
  let top, left, width, height, isVertical = false;
  if (Math.abs(toRect.left - fromRect.left) > Math.abs(toRect.top - fromRect.top)) {
    // 水平线条
    left = fromRect.right;
    width = toRect.left - fromRect.right;
    top = fromRect.top + fromRect.height / 2;
    height = 2;
    line.removeClass('vertical');
  } else {
    // 垂直线条
    top = fromRect.bottom;
    height = toRect.top - fromRect.bottom;
    left = fromRect.left + fromRect.width / 2;
    width = 2;
    line.addClass('vertical');
    isVertical = true;
  }
  
  line.css({
    top: `${top}px`,
    left: `${left}px`,
    width: `${width}px`,
    height: `${height}px`
  });
}

// 绑定悬停事件
$('.mydiv').hover(function() {
  const lineId = $(this).find('.indeximg').data('line');
  $('#' + lineId).addClass('hovered');
}, function() {
  const lineId = $(this).find('.indeximg').data('line');
  $('#' + lineId).removeClass('hovered');
});

// 初始化线条
function loop() {
  adjustLine($('#div1'), $('.canvas-box'), $('#line1'));
  adjustLine($('#div2'), $('.canvas-box'), $('#line2'));
  adjustLine($('#div3'), $('.canvas-box'), $('#line3'));
  adjustLine($('#div4'), $('.canvas-box'), $('#line4'));
  adjustLine($('#div5'), $('.canvas-box'), $('#line5'));
  adjustLine($('#div6'), $('.canvas-box'), $('#line6'));
}
loop();
window.addEventListener('resize', loop);

方案2:改用SVG线条(推荐,支持任意方向)

SVG的stroke-dasharray和stroke-dashoffset属性是实现路径绘制动画的标准方案,能完美支持斜向线条:

1. 替换HTML中的Div线条为SVG

<div id="content">
  <!-- 保留你的div1-div6结构不变 -->
</div>
<svg class="lines-container" viewBox="0 0 1200 800" preserveAspectRatio="none">
  <line id="lineArticle08" stroke="#000" stroke-width="2" />
  <line id="lineArticle02" stroke="#000" stroke-width="2" />
  <line id="lineArticle03" stroke="#000" stroke-width="2" />
  <line id="lineArticle09" stroke="#000" stroke-width="2" />
  <line id="lineArticle10" stroke="#000" stroke-width="2" />
  <line id="lineArticle01" stroke="#000" stroke-width="2" />
</svg>

2. 设置SVG动画CSS

.lines-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none; /* 不干扰下方元素的交互 */
}

.lines-container line {
  fill: none;
  stroke-dasharray: 0;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.6s ease;
}

.lines-container line.hovered {
  stroke-dashoffset: 0;
}

3. 调整JS逻辑计算线条路径

function adjustLine(from, to, line) {
  if (from.length === 0 || to.length === 0 || line.length === 0) {
    return;
  }
  
  const fromRect = from[0].getBoundingClientRect();
  const svgRect = document.querySelector('.lines-container').getBoundingClientRect();
  
  // 转换坐标到SVG坐标系
  const x1 = fromRect.left - svgRect.left + fromRect.width / 2;
  const y1 = fromRect.top - svgRect.top + fromRect.height / 2;
  const x2 = to[0].getBoundingClientRect().left - svgRect.left + to[0].getBoundingClientRect().width / 2;
  const y2 = to[0].getBoundingClientRect().top - svgRect.top + to[0].getBoundingClientRect().height / 2;
  
  // 设置线条端点
  line.attr({
    x1: x1,
    y1: y1,
    x2: x2,
    y2: y2
  });
  
  // 计算线条长度,设置dash参数
  const lineLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
  line.attr({
    'stroke-dasharray': lineLength,
    'stroke-dashoffset': lineLength
  });
}

// 绑定悬停事件
$('.mydiv').hover(function() {
  const lineId = $(this).find('.indeximg').data('line');
  $('#' + lineId).addClass('hovered');
}, function() {
  const lineId = $(this).find('.indeximg').data('line');
  $('#' + lineId).removeClass('hovered');
});

// 初始化和窗口resize时更新线条
function loop() {
  adjustLine($('#div1'), $('.canvas-box'), $('#lineArticle08'));
  adjustLine($('#div2'), $('.canvas-box'), $('#lineArticle02'));
  adjustLine($('#div3'), $('.canvas-box'), $('#lineArticle03'));
  adjustLine($('#div4'), $('.canvas-box'), $('#lineArticle09'));
  adjustLine($('#div5'), $('.canvas-box'), $('#lineArticle10'));
  adjustLine($('#div6'), $('.canvas-box'), $('#lineArticle01'));
}
loop();
window.addEventListener('resize', loop);

关键提示

  • 方案2的SVG方式更灵活,支持任意角度的线条动画,推荐使用;方案1适合仅水平/垂直线条的场景。
  • 可以通过修改CSS中的0.6s调整动画时长,ease可以换成linear实现匀速动画。
  • 确保SVG或div线条的z-index设置正确,避免被其他元素遮挡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:08:12