Возможно ли изменить анимацию открытию bootstrap burger менью?

252
22 мая 2018, 16:30

Как можно изменить стандартную анимацию открытия бургер менью в Bootstrap.

То есть чтобы при клике была анимация бургера к примеру вот такая

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/> 
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script> 
 
<nav class="navbar navbar-expand-lg navbar-light bg-light"> 
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo03" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation"> 
    <span class="navbar-toggler-icon"></span> 
  </button> 
    <a class="navbar-brand" href="#">Navbar</a> 
 
    <div class="collapse navbar-collapse" id="navbarTogglerDemo03"> 
      <div class="navbar-nav float-right text-right pr-3"> 
        <a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a> 
        <a class="nav-item nav-link" href="#">Features</a> 
        <a class="nav-item nav-link" href="#">Pricing</a> 
        <a class="nav-item nav-link disabled" href="#">Disabled</a> 
      </div> 
    </div> 
  </nav> 
   
  
 

Answer 1

Да, возможно. Вот вам небольшой набросок.

Только учтите, у приведенного в примере бургера - плохо с анимацией. А именно, когда анимация открытия выполняется, повтороное нажатие не запускает анимацию закрытия.

Пример на codepen.

$(document).ready(function() { 
  var $btn = $('.navbar-toggler'), 
    $burger = $('.burger'), 
    $topLine = $('.burger__line-top'), 
    $midLine = $('.burger__line-mid'), 
    $menuLine = $('.burger__menu'), 
    anim = false; 
 
  var changeClasses = { 
    addActive: function() { 
      for (var i = 0; i <= 2; i++) { 
        $burger.children().eq(i).removeClass('reverseLine' + (i + 1)).addClass('activeLine' + (i + 1)); 
      } 
    }, 
    addReverse: function() { 
      for (var i = 0; i <= 2; i++) { 
        $burger.children().eq(i).removeClass('activeLine' + (i + 1)).addClass('reverseLine' + (i + 1)); 
      } 
    } 
  } 
 
  var timeouts = { 
    initial: function(child, Y, rot, scale) { 
      $burger.children().eq(child).css('transform', 'translateY(' + Y + 'px) rotate(' + rot + 'deg) scale(' + scale + ',1)'); 
    }, 
    afterActive: function() { 
      // ES6 
      setTimeout(() => { 
        this.initial(0, 12, 45, 1.40); 
        this.initial(1, -12, -45, 1.40); 
        this.initial(2, 35, 0, 1); 
        $burger.children().eq(2).css('opacity', '0'); 
        anim = true; 
      }, 2300); 
      // With bind() 
      // setTimeout(function() { 
      //   this.initial(0, 12, 45, 1.40); 
      //   this.initial(1, -12, -45, 1.40); 
      //   this.initial(2, 35, 0, 1); 
      //   $burger.children().eq(2).css('opacity', '0'); 
      //   anim = true; 
      // }.bind(this), 1300); 
    }, 
    beforeReverse: function() { 
      setTimeout(() => { 
        for (var i = 0; i <= 2; i++) { 
          this.initial(i, 0, 0, 1); 
        } 
        $burger.children().eq(2).css('opacity', '1'); 
        anim = false; 
      }, 2300); 
    } 
  } 
 
  $btn.on('click', function() { 
    if (!anim) { 
      changeClasses.addActive(); 
      timeouts.afterActive(); 
    } else if (anim) { 
      changeClasses.addReverse(); 
      timeouts.beforeReverse(); 
    } 
  }); 
});
*, 
*:after, 
*:before { 
  box-sizing: border-box; 
  margin: 0; 
  padding: 0; 
} 
 
.navbar { 
  background-color: #ff6100 !important; 
} 
 
.navbar .navbar-toggler { 
  width: 71px; 
  padding: 0; 
  height: 71px; 
  position: relative; 
  margin-top: 10px; 
  border: none; 
  outline: none; 
} 
 
.activeLine1 { 
  transform-origin: left center; 
  animation: activeTop 1.3s forwards; 
} 
 
@keyframes activeTop { 
  20% { 
    transform: translateY(-6px) rotate(0deg); 
  } 
  40% { 
    transform: translateY(15px) rotate(48deg) scale(1.4, 1); 
  } 
  60% { 
    transform: translateY(7px) rotate(42deg) scale(1.4, 1); 
  } 
  100% { 
    transform: translateY(12px) rotate(45deg) scale(1.4, 1); 
  } 
} 
 
.activeLine2 { 
  transform-origin: right center; 
  animation: activeMid 1.3s forwards; 
} 
 
@keyframes activeMid { 
  20% { 
    transform: translateY(-8px) rotate(0deg); 
  } 
  40% { 
    transform: translateY(-3px) rotate(-45deg) scale(1.3, 1); 
  } 
  60% { 
    transform: translateY(-18px) rotate(-45deg) scale(1.4, 1); 
  } 
  100% { 
    transform: translateY(-12px) rotate(-45deg) scale(1.4, 1); 
  } 
} 
 
.activeLine3 { 
  animation: activeMenu 0.5s forwards; 
} 
 
@keyframes activeMenu { 
  40% { 
    transform: translateY(-7px); 
    opacity: 1; 
  } 
  60% { 
    transform: translateY(-7px); 
    opacity: 1; 
  } 
  70% { 
    opacity: 1; 
  } 
  100% { 
    transform: translateY(35px); 
    opacity: 0; 
  } 
} 
 
.reverseLine1 { 
  transform-origin: left center; 
  animation: reverseTop 1.5s forwards; 
} 
 
@keyframes reverseTop { 
  15% { 
    transform: translateY(3px) rotate(-3deg) scale(1, 1); 
  } 
  30% { 
    transform: translateY(-14px) rotate(-10deg) scale(1, 1); 
  } 
  40% { 
    transform: translateY(4px) rotate(5deg) scale(1, 1); 
  } 
  60% { 
    transform: translateY(-2px) rotate(-3deg) scale(1, 1); 
  } 
  100% { 
    transform: translateY(0px) rotate(0deg); 
  } 
} 
 
.reverseLine2 { 
  transform-origin: right center; 
  animation: reverseMid 1.5s forwards; 
} 
 
@keyframes reverseMid { 
  20% { 
    transform: translateY(0px) rotate(13deg) scale(1, 1); 
  } 
  40% { 
    transform: translateY(-6px) rotate(-9deg) scale(1, 1); 
  } 
  60% { 
    transform: translateY(8px) rotate(6deg) scale(1, 1); 
  } 
  100% { 
    transform: translateY(0px) rotate(0deg); 
  } 
} 
 
.reverseLine3 { 
  transform-origin: right center; 
  animation: reverseMenu 1.65s forwards; 
} 
 
@keyframes reverseMenu { 
  30% { 
    transform: translateY(-20px) rotate(0deg) scale(1, 1); 
    opacity: 1; 
  } 
  40% { 
    transform: translateY(9px) rotate(-10deg) scale(1, 1); 
    opacity: 1; 
  } 
  60% { 
    transform: translateY(-5px) rotate(5deg) scale(1, 1); 
    opacity: 1; 
  } 
  100% { 
    transform: translateY(0px) rotate(0deg); 
    opacity: 1; 
  } 
} 
 
.burger { 
  position: absolute; 
  left: 0; 
  right: 0; 
  top: 0; 
  bottom: 0; 
  margin: auto; 
  width: 71px; 
  height: 71px; 
  cursor: pointer; 
} 
 
.burger__line-top { 
  width: 100%; 
  height: 8px; 
  border-radius: 5px; 
  background-color: #fff; 
  box-shadow: 0 0 1px 0 #fff; 
} 
 
.burger__line-mid { 
  margin-top: 17px; 
  width: 100%; 
  height: 8px; 
  border-radius: 5px; 
  background-color: #fff; 
  box-shadow: 0 0 1px 0 #fff; 
} 
 
.burger__menu { 
  margin-top: 10px; 
} 
 
.burger__menu p { 
  text-align: center; 
  font-size: 20px; 
  font-family: 'Open Sans', sans-serif; 
  font-weight: 900; 
  color: #fff; 
  text-shadow: 0 0 1px #fff; 
  letter-spacing: 3px; 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet" /> 
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script> 
 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script> 
 
<nav class="navbar navbar-expand-lg navbar-light"> 
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo03" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation"> 
    <div class='burger'> 
    <div class='burger__line-top'></div> 
    <div class='burger__line-mid'></div> 
    <div class='burger__menu'> 
      <p>MENU</p> 
    </div> 
  </div> 
  </button> 
  <a class="navbar-brand" href="#">Navbar</a> 
 
  <div class="collapse navbar-collapse" id="navbarTogglerDemo03"> 
    <div class="navbar-nav float-right text-right pr-3"> 
      <a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a> 
      <a class="nav-item nav-link" href="#">Features</a> 
      <a class="nav-item nav-link" href="#">Pricing</a> 
      <a class="nav-item nav-link disabled" href="#">Disabled</a> 
    </div> 
  </div> 
</nav>

READ ALSO
Выбор двух дат при условии не disabled

Выбор двух дат при условии не disabled

air datepicker Не получается сделать условие, при котором нельзя будет выбирать range, когда между датами есть disabledКто знает, не стесняйтесь подсказывать...

174
Jquery to native js

Jquery to native js

есть JQ код:

223
Почему в данном случае не получается привязать контекст?

Почему в данном случае не получается привязать контекст?

К сожалению, не могу продемонстрировать код в работе, так как здесь осуществляется работа с сервером с помощью ajaxУпрощенный пример

224
Реализация scroll

Реализация scroll

Как сделать чтобы скролл доходил точно до того блока с которого выезжал?

181