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

React中实现SVG汉堡图标点击转X图标的平滑过渡求助

解决汉堡图标切换为X图标的平滑过渡问题

你的核心问题在于直接切换SVG路径的d属性实现形态变化,但浏览器对d属性的过渡支持有限,且两种路径的节点结构差异大,导致无法产生平滑动画。下面是基于CSS变换的解决方案,利用transform和opacity实现自然过渡:

修改后的React组件

import React, { useState } from 'react';
import '../Styles/BurgerIcon.css';

const BurgerIcon = () => {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const toggleMenu = () => {
    setIsMenuOpen(!isMenuOpen);
  };

  return (
    <svg 
      xmlns="http://www.w3.org/2000/svg" 
      fill="none" 
      viewBox="0 0 24 24" 
      strokeWidth="1.5" 
      stroke="currentColor"
      onClick={toggleMenu}
      className={`burger_icon ${isMenuOpen ? 'open' : ''}`}
    >
      {/* 汉堡的三条线 */}
      <line 
        className="burger_line" 
        x1="3" y1="6.75" 
        x2="21" y2="6.75" 
        strokeLinecap="round" 
      />
      <line 
        className="burger_line" 
        x1="3" y1="12" 
        x2="21" y2="12" 
        strokeLinecap="round" 
      />
      <line 
        className="burger_line" 
        x1="3" y1="17.25" 
        x2="21" y2="17.25" 
        strokeLinecap="round" 
      />
    </svg>
  );
};

export default BurgerIcon;

对应的CSS样式

.burger_icon {
  cursor: pointer;
  transition: transform 300ms ease;
}

.burger_line {
  transition: all 300ms ease;
  transform-origin: center;
}

/* 菜单打开时的变换 */
.burger_icon.open .burger_line:nth-child(1) {
  transform: translateY(5.25px) rotate(45deg);
}

.burger_icon.open .burger_line:nth-child(2) {
  opacity: 0;
}

.burger_icon.open .burger_line:nth-child(3) {
  transform: translateY(-5.25px) rotate(-45deg);
}

原理说明

  1. 把汉堡的三条线拆分为独立的<line>元素,每条线可以单独控制变换
  2. 利用transform-origin: center确保旋转以线条中心为基准
  3. 菜单打开时:
    • 第一条线向下位移并顺时针旋转45度
    • 第二条线设置opacity: 0隐藏
    • 第三条线向上位移并逆时针旋转45度
  4. 所有变换都使用浏览器完全支持的transform和opacity属性,确保平滑过渡

内容的提问来源于stack exchange,提问作者Saran Kumar S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:02:22