将SVG汉堡图标旋转成X形图标?

8
我使用HTML中的纯SVG代码设计了一个三栏图标。 我使用CSS3转换将顶部和底部栏旋转成X形状。 问题是它们围绕自己的中心旋转,但我需要它们围绕图标的中心旋转。 为了解决这个问题,我调整了它们的X / Y坐标。

这会导致Internet Explorer,Firefox和Safari出现很多错误问题。 Chrome似乎没问题,但显然我想以“正确”的方式编写代码,以便在所有浏览器中都可以正常工作。

这是我的实时CodePen链接

HTML

<svg id="burgericon" xmlns="http://www.w3.org/2000/svg" width="90" height="80">
  <g class="icon">
    <rect class="frstbar" x="10" y="10" width="70" height="12" rx="7" ry="7" fill="#414141"/>
    <rect class="scndbar" x="10" y="35" width="70" height="12" rx="7" ry="7" fill="#414141"/>
    <rect class="thrdbar" x="10" y="60" width="70" height="12" rx="7" ry="7" fill="#414141"/>
  </g>
</svg>

CSS

.hamburger { display:block; text-align:center; }
svg { cursor:pointer; }

.frstbar, .scndbar, .thrdbar {
  -webkit-transition: all 0.35s linear;
  -moz-transition: all 0.35s linear;
    -o-transition: all 0.35s linear;
    transition: all 0.35s linear;
}
#burgericon.open .frstbar {
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}
#burgericon.open .thrdbar {
  -webkit-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  transform: rotate(-45deg);
}
#burgericon.open .scndbar { width: 0; opacity: 0; }

JS

$('#burgericon').on('click', function(e) {

  if($(this).attr('class') != "open") {
      $(this).attr('class','open');
      $('.frstbar').attr('x','25').attr('y','-5');
      $('.thrdbar').attr('x','-35').attr('y','55');
    } 
  else {
    $(this).attr('class','default');
    $('.frstbar').attr('x','10').attr('y','10');
      $('.thrdbar').attr('x','10').attr('y','60');
    }
});

我认为更改X/Y坐标会导致模糊效果。 我已经添加了下面的屏幕截图。 首先,您将看到完成的X图标,然后您将看到将其动画返回默认值时它的外观。
柱子不是完全直的,而是因为某种原因看起来弯曲。 此处放置屏幕截图 我对SVG操作仍然很陌生,因此我不确定如何使用CSS3 / JS正确旋转<rect>元素。 任何帮助或指向正确方向的提示都将不胜感激。

CodePen 可能不是最好的错误演示网站,因为它有自动保存功能。是否可以在这里发布您的标记(供将来的读者参考)? - jbutler483
1
很奇怪...即使在Chrome中,如果我尝试几次,有些会失败... - vals
我认为使用线性的 transition-timing-function 无法使过渡效果完美结束。在我的有限测试中,切换到默认的 ease 看起来可以解决这个问题。 - andyb
1
@jbutler483 当然!我刚刚将所有的代码添加到了这篇文章中,所以它可以在没有CodePen的情况下显示。 - Thomas Lancy
2个回答

8
您可以使用CSS transform-origin属性来移除JS定位。您可以使用transform-origin: 0 50%;将其设置在第一根和第二根条纹的左侧。

这样它们在旋转时就会相互交叉:

document.getElementById('burgericon').addEventListener('click', function (e) {
    this.classList.toggle('open');
});
.hamburger {
  display: block;
  text-align: center;
}
svg {
  cursor: pointer;
}
.frstbar,.scndbar,.thrdbar {
  transition: all 0.35s linear;
  transform: rotate(0deg);
  transform-origin: 0% 50%;
}
#burgericon.open .frstbar {
  transform: rotate(45deg);
}
#burgericon.open .thrdbar {
  transform: rotate(-45deg);
}
#burgericon.open .scndbar {
  width: 0;
  opacity: 0;
}
<nav class="hamburger">
  <svg id="burgericon" xmlns="http://www.w3.org/2000/svg" width="90" height="80">
    <g class="icon">
      <rect class="frstbar" x="10" y="10" width="70" height="12" rx="7" ry="7" fill="#414141" />
      <rect class="scndbar" x="10" y="35" width="70" height="12" rx="7" ry="7" fill="#414141" />
      <rect class="thrdbar" x="10" y="60" width="70" height="12" rx="7" ry="7" fill="#414141" />
    </g>
  </svg>
</nav>
<div>
</div>

感谢David Thomas提供的JS代码。

请注意,transform-origin属性需与transform属性使用相同的浏览器前缀。上述示例中我省略了它们的前缀。


1
使用纯JavaScript同样简单(如果不是更简单):JS Fiddle演示 - David Thomas
@DavidThomas 在普通JS中肯定更简单。 - web-tiki
@ThomasLancy FF不支持svg元素的transform-origin属性。这里有一个解决方法https://dev59.com/R2Up5IYBdhLWcg3wo4yd - web-tiki
2
@web-tiki 只要避免使用百分比,它就支持在 SVG 元素上使用 transform-origin。 - Robert Longson
@RobertLongson 谢谢,使用像素在FF中似乎确实有效。虽然不是完美的适配,但看起来好多了。我已经更新了这个示例(http://jsfiddle.net/9xjkejbo/1/)以支持FF - 这可能是我在当前浏览器标准下能做到的最好的了。 - Thomas Lancy
显示剩余3条评论

5

CSS

使用 CSS 的 transform: rotate() 属性,我将元素旋转以形成 X 形状。
使用 CSS 的 opacity 和过渡效果,使对象逐渐变为透明。

.icon {
  stroke: none;
  fill: #777;
}
.icon .frstbar {
  transform-origin: 10% 50%;
  transition: transform 1s;
}
.icon:hover .frstbar {
  transform: rotate(45deg);
}
.icon .thrdbar {
  transform-origin: 10% 50%;
  transition: transform 1s;
}
.icon:hover .thrdbar {
  transform: rotate(-45deg);
}
.scndbar {
  opacity: 1;
  transition: opacity 1s;
}
.icon:hover .scndbar {
  opacity: 0;
}
<svg id="burgericon" xmlns="http://www.w3.org/2000/svg" width="90" height="90" viewBox="0 0 100 100">
  <g class="icon">
    <rect class="frstbar" x="10" y="10" width="90" height="12" rx="7" ry="7" />
    <rect class="scndbar" x="10" y="35" width="90" height="12" rx="7" ry="7" />
    <rect class="thrdbar" x="10" y="60" width="90" height="12" rx="7" ry="7" />
  </g>
</svg>


谢谢!我能理解你为什么删除了JS以简化代码。但是我注意到这个解决方案在Firefox中也会出现问题 - 有任何想法吗?即使是最新的浏览器支持似乎也很难实现。这里是你演示的Firefox截图,还有一个jsFiddle演示 - Thomas Lancy
嘿Persijn,我猜你应该将悬停样式添加到SVG而不是组中,因为当你在描边之间悬停时,悬停不会触发! - Max Payne
@TimKrul 哎呀呀,我有点喜欢这种感觉 :D - Persijn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接