【问题标题】:Rotate a SVG hamburger icon into an X?将 SVG 汉堡图标旋转成 X?
【发布时间】:2015-09-05 15:42:36
【问题描述】:

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

这会导致 Internet Explorer、Firefox 和 Safari 出现很多错误问题。 Chrome 似乎没问题,但显然我想以“正确”的方式对此进行编码,以便它适用于所有浏览器。

Here's my live 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 图标,然后您将看到动画恢复为默认值时的外观。

这些条不是完全笔直的,而是由于某种原因看起来弯曲了。

Screenshot here

我还是 SVG 操作的新手,所以我不确定如何使用 CSS3/JS 正确旋转 &lt;rect&gt; 元素。任何正确方向的帮助或提示将不胜感激。

【问题讨论】:

  • codepen 可能不是最好的错误演示站点,因为它具有自动保存功能。是否也可以在此处发布您的标记(供未来的读者使用?)
  • 很奇怪...即使在Chrome中,如果我尝试多次,有些会失败...
  • 我不认为 linear transition-timing-function 提供了正确完成的过渡时间。在我有限的测试中,切换到默认的 ease 似乎可以解决它。
  • @jbutler483 当然!刚刚添加了所有代码,因此在没有 CodePen 的情况下可以从这篇文章中看到它。

标签: javascript jquery css svg css-transforms


【解决方案1】:

您可以使用 CSS transform-origin property 删除 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 属性相同的供应商前缀。我在上面的 sn-p 中都省略了它们

【讨论】:

  • 又好又简单的jquery解决方案:P
  • 使用纯 JavaScript 也同样简单(如果不是更简单的话):JS Fiddle demo
  • 这看起来确实更干净,但你知道为什么它在 IE 中不起作用吗?我正在测试来自 web-tiki 和 @DavidThomas 的最新 IE11 代码,但 IE 似乎很麻烦。我知道这是一个讨厌的问题,我可以放弃对 IE 的支持,但它在 FireFox 中似乎也有问题。 jsFiddle
  • @DavidThomas 在纯 JS 中绝对更简单
  • @web-tiki 只要避免百分比,它就支持 svg 元素上的 transform-origin。
【解决方案2】:

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 screenshot 以及 jsFiddle demo
  • 嘿 Persijn 我猜你应该将悬停样式添加到 svg 而不是组,因为当你悬停在笔画之间时,悬停不会触发!
  • @TimKrul naaaaa 我有点喜欢这样:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多