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

SVG齿轮悬停后减速停止动画及路径宽度单独缩放问题求助

问题解决方案

一、实现齿轮悬停旋转,离开后1秒减速停止

CSS + JavaScript 精准控制方案

这种方法能记录当前旋转角度,实现自然的减速停止效果:

#gear {
  transform-origin: center; /* 确保旋转中心在齿轮几何中心 */
}
const gear = document.getElementById('gear');
let animationId;
let currentRotation = 0;
const rotationSpeed = 6; // 每秒旋转的角度值,可按需调整

// 鼠标进入时启动匀速旋转
gear.addEventListener('mouseenter', () => {
  cancelAnimationFrame(animationId);
  const animate = () => {
    currentRotation += rotationSpeed;
    gear.style.transform = `rotate(${currentRotation}deg)`;
    animationId = requestAnimationFrame(animate);
  };
  animate();
});

// 鼠标离开时启动减速停止动画
gear.addEventListener('mouseleave', () => {
  cancelAnimationFrame(animationId);
  const startTime = performance.now();
  const startAngle = currentRotation;
  const duration = 1000; // 1秒减速时长
  const totalRotation = 90; // 减速阶段额外旋转的角度,可按需调整

  const decelerateAnimate = (currentTime) => {
    const elapsed = currentTime - startTime;
    const progress = Math.min(elapsed / duration, 1);
    // 用ease-out曲线实现自然减速
    const easedProgress = 1 - Math.pow(1 - progress, 3);
    const currentAngle = startAngle + totalRotation * easedProgress;
    
    gear.style.transform = `rotate(${currentAngle}deg)`;
    
    if (progress < 1) {
      animationId = requestAnimationFrame(decelerateAnimate);
    } else {
      currentRotation = currentAngle; // 更新最终角度,下次悬停延续旋转状态
    }
  };
  
  animationId = requestAnimationFrame(decelerateAnimate);
});

纯CSS简化方案(近似效果)

若对旋转连续性要求不高,可通过切换动画实现近似减速:

#gear {
  transform-origin: center;
  animation: spin-decelerate 1s ease-out forwards paused;
}

#gear:hover {
  animation: spin-continuous 0.5s linear infinite;
}

@keyframes spin-continuous {
  to { transform: rotate(360deg); }
}

@keyframes spin-decelerate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(90deg); }
}

注:纯CSS方案无法延续上次旋转的角度,鼠标离开后会从初始状态开始减速。

二、单独增加SVG特定path的宽度(不影响高度)

根据需求分两种场景处理:

场景1:调整路径描边宽度

如果是要增加path的轮廓(stroke)宽度,直接给目标path设置stroke-width属性即可,不会改变路径整体高度:

<svg viewBox="0 0 100 100">
  <!-- 原宽度路径 -->
  <path d="M10,20 L90,20" stroke="black" stroke-width="2" fill="none" />
  <!-- 加宽后的路径 -->
  <path d="M10,50 L90,50" stroke="black" stroke-width="4" fill="none" />
</svg>

场景2:缩放路径水平长度(保持高度不变)

如果是要拉伸路径的水平尺寸,使用transform: scaleX(),配合transform-origin避免位置偏移:

.target-path {
  transform-origin: center; /* 以中心为原点缩放,保证路径位置不变 */
  transform: scaleX(1.5); /* 水平方向放大1.5倍,高度不受影响 */
}

若需要精准修改路径形状而非缩放,可手动编辑path的d属性,将水平方向的坐标点按比例调整,这种方式更可控,但需直接修改SVG代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:00:53