简体   繁体   English

汉堡菜单导航项动画

[英]Hamburger menu navigation items animations

https://drive.google.com/file/d/1LCS6Z-oP1rqPbRF7tydgVWZEdCEt_RPP/view?usp=sharing this the animation effect on hamburger menu navigation menu items. https://drive.google.com/file/d/1LCS6Z-oP1rqPbRF7tydgVWZEdCEt_RPP/view?usp=共享此 animation 对汉堡菜单导航菜单项的影响。 On click on the hamburger menu there is animation going on each navigation menu items.单击汉堡菜单时,每个导航菜单项上都有 animation。
I have tried to recreate one.我试图重新创建一个。 https://codepen.io/coral_Sb/pen/VwmQbLo I don't understand where I getting wrong? https://codepen.io/coral_Sb/pen/VwmQbLo我不明白我哪里错了?

The animation is playing everytime when hamburger menu is clicked.每次点击汉堡菜单时,animation 都会播放。

 .nav-menu { background-color: red; }.nav-menu ul li a { color: #fff; text-decoration: none; margin-bottom: 20px; } li:first-child { animation: bringback 1s 0s forwards; } li:nth-child(2) { animation: bringback 1s 2s forwards; }.nav-menu li:nth-child(3) { animation: bringback 1s 3s forwards; }.nav-menu li:nth-child(4) { animation: bringback 1s 4s forwards; }.nav-menu li:nth-child(5) { animation: bringback 1s 5s forwards; }.nav-menu li:nth-child(6) { animation: bringback 1s 6s forwards; }.nav-menu li:nth-child(7) { animation: bringback 1s 7s forwards; }.nav-menu li:nth-child(8) { animation: bringback 1s 8s forwards; }.nav-menu li:nth-child(9) { animation: bringback 1s 9s forwards; }.nav-menu li:nth-child(10) { animation: bringback 1s 10s forwards; } @keyframes bringback { to { opacity: 1; text-indent: 25px; } }
 <div class="nav-menu" id="nav-menu"> <ul id=" check-ul" style="list-style:none"> <li> <.-- class="active1"--> <span><img src="images/birla-logo:png" alt=""></span> </li> <br> <li> <a href="#">Home</a> </li> <li> <a href="#">About us <span class="fas fa-sort-down mr-3" style="width; 20px;"></span> </a> </li> <li> <a href="#">Curriculum</a> </li> <li> <a href="#">Criteria</a> </li> <li> <a href="#">Admission Process</a> </li> <li> <a href="#">Careers </a> </li> <li> <a href="#">Contact us </a> </li> <li> <a href="#">Enquire Now </a> </li> </ul> </div>

Don't hardcode CSS for an arbitrary number of items li:nth-child( N ) - it's hard to maintain .不要为任意数量的项目 li:nth-child( N ) 硬编码 CSS -这很难维护

Sequentially staggered delay animation顺序交错延迟 animation

Use CSS variables to create a staggered animation by using fill-mode both and control the delay using that CSS variable inside CSS calc() : Use CSS variables to create a staggered animation by using fill-mode both and control the delay using that CSS variable inside CSS calc() :

 #check-ul li { animation: animate 350ms ease calc(var(--i) * 200ms) both; } @keyframes animate { 0% { opacity: 0; transform: translateX(-2em); } 100% { opacity: 1; } }
 <div class="nav-menu" id="nav-menu"> <ul id="check-ul"> <li style="--i:1"><a href="#">Home</a></li> <li style="--i:2"><a href="#">About us</a></li> <li style="--i:3"><a href="#">Curriculum</a></li> <li style="--i:4"><a href="#">Criteria</a></li> <li style="--i:5"><a href="#">Admission Process</a></li> <li style="--i:6"><a href="#">Careers </a></li> <li style="--i:7"><a href="#">Contact us</a></li> <li style="--i:8"><a href="#">Enquire Now</a></li> </ul> </div>

Trigger menu animations on open via button click:通过按钮单击打开时触发菜单动画:

 const toggleTarget = (sel) => { const EL_targets = document.querySelectorAll(sel); EL_targets.forEach(EL => EL.classList.toggle("is-active")); }; const EL_toggleButtons = document.querySelectorAll("[data-toggle]"); EL_toggleButtons.forEach(EL => EL.addEventListener("click", (ev) => { toggleTarget(ev.currentTarget.dataset.toggle); }));
 #nav-menu { position: fixed; background: #d00; color: #fff; top: 0; left: 0; height: 100vh; padding: 20px; transition: 0.3s; transform: translateX(-100%); } #nav-menu.is-active { transform: translateX(0%); } #nav-menu.is-active li { animation: animate 350ms ease calc(var(--i) * 100ms) both; } @keyframes animate { 0% { opacity: 0; transform: translateX(-2em); } 100% { opacity: 1; } }
 <button type="button" data-toggle="#nav-menu">OPEN MENU</button> <div id="nav-menu"> <button type="button" data-toggle="#nav-menu">CLOSE</button> <ul> <li style="--i:1"><a href="#">Home</a></li> <li style="--i:2"><a href="#">About us</a></li> <li style="--i:3"><a href="#">Curriculum</a></li> <li style="--i:4"><a href="#">Criteria</a></li> <li style="--i:5"><a href="#">Admission Process</a></li> <li style="--i:6"><a href="#">Careers </a></li> <li style="--i:7"><a href="#">Contact us</a></li> <li style="--i:8"><a href="#">Enquire Now</a></li> </ul> </div>

In order to complete a full example, I think you need some JavaScript in the mix.为了完成一个完整的例子,我认为你需要一些 JavaScript 混合。

Let's approach this problem by first creating the necessary components to properly display the navigation from the video:让我们首先创建必要的组件来正确显示视频中的导航来解决这个问题:

<div class="navigation">
  <button id="toggle-button">
  <svg class="menu-button" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
  </svg>
</button>

And style it accordingly:并相应地设置样式:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-family: 'Roboto';
}

#toggle-button {
  background: none;
    color: inherit;
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    outline: inherit;
}

.navigation {
  background: #1f2937;
}

.menu-button {
  color: white;
  width: 2.3rem;
  height 2.3rem;
}

What we need to do next is prepare the necessary markup for the panel, fader, and side menu.我们接下来需要做的是为面板、推子和侧边菜单准备必要的标记。

<div class="overlay-container hidden">
    <div class="overlay"></div>
    <div class="panel">
      <ul class="menu">
        <li class="hidden" style="--i:1">Menu item #1</li>
        <li class="hidden" style="--i:2">Menu item #2</li>
        <li class="hidden" style="--i:3">Menu item #3</li>
        <li class="hidden" style="--i:4">Menu item #4</li>
      </ul>
    </div>
  </div>

And of course style it:当然还有它的样式:

.overlay-container.hidden {
  display: none;
}

.overlay-container {
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.overlay.fade {
  opacity: 0.6;
}

.overlay {
  position: absolute;
  width: 100vw;
  height: 100vh;
  opacity: 0;
  background: black;
  transition: opacity 300ms ease-out;
}

.panel.slide {
  transform: translateX(0%);
}

.panel {
  position: absolute;
  height: 100vh;
  width: 18rem;
  background: #c00136;
  transform: translateX(-100%);
  transition: transform 300ms ease-out;
}

.menu {
  padding: 1rem 1rem;
  list-style-type: none;
}

.menu li.hidden {
  visibility: hidden;
}

.menu li {
  color: #f7f7f7;
  margin: 1rem 0;
}

.menu li.fadeInLeft {
  animation: fadeInLeft 350ms ease calc(var(--i) * 200ms) both;
}

@keyframes fadeInLeft {
  0% {
    opacity: 0;
    transform: translateX(-2em);
  }

  100% {
    opacity: 1;
  }
}

Now using this bit of javascript, you can orchestrate everything together.现在使用 javascript 的这一位,您可以将所有内容编排在一起。 Notice how I used some transitions as well as animations so we can sequentially time请注意我如何使用一些过渡和动画,以便我们可以按顺序计时

let button = document.getElementById("toggle-button");
let backbox = document.querySelectorAll('.overlay-container')[0];
let overlay = document.querySelectorAll('.overlay')[0];
let panel = document.querySelectorAll('.panel')[0];

/*
 * Since transitions from 'hidden'
 * to 'block' don't animate we need 
 * to trigger a browser repaint by
 * asking the element for it's height
 */
function forceRepaint(element) {
  return element.offsetHeight;
}

button.addEventListener("click", function () {
  backbox.classList.remove('hidden');
  forceRepaint(backbox);
  overlay.classList.add('fade');
  panel.classList.add('slide');
});

panel.addEventListener("transitionend", function () {
  document.querySelectorAll('.menu li').forEach(node => {
    node.classList.remove("hidden");
    node.classList.add('fadeInLeft');
  })
});

I suggest you approach these problems gradually and step by step, that way you'll be able to solve these problems yourself in the future too.我建议你循序渐进地解决这些问题,这样你将来也可以自己解决这些问题。 Problems like this seem complex at first, but it's essential that you break them down into smaller parts.像这样的问题一开始看起来很复杂,但你必须将它们分解成更小的部分。

Finally, here's how it all comes together.最后,这就是这一切是如何结合在一起的。

 let button = document.getElementById("toggle-button"); let backbox = document.querySelectorAll('.overlay-container')[0]; let overlay = document.querySelectorAll('.overlay')[0]; let panel = document.querySelectorAll('.panel')[0]; /* * Since transitions from 'hidden' * to 'block' don't animate we need * to trigger a browser repaint by * asking the element for it's height */ function forceRepaint(element) { return element.offsetHeight; } button.addEventListener("click", function() { backbox.classList.remove('hidden'); forceRepaint(backbox); overlay.classList.add('fade'); panel.classList.add('slide'); }); panel.addEventListener("transitionend", function() { document.querySelectorAll('.menu li').forEach(node => { node.classList.remove("hidden"); node.classList.add('fadeInLeft'); }) });
 * { margin: 0; padding: 0; box-sizing: border-box; } html { font-family: 'Roboto'; } #toggle-button { background: none; color: inherit; border: none; padding: 0; font: inherit; cursor: pointer; outline: inherit; }.navigation { background: #1f2937; }.menu-button { color: white; width: 2.3rem; height 2.3rem; }.overlay-container.hidden { display: none; }.overlay-container { overflow: hidden; position: fixed; top: 0; left: 0; right: 0; bottom: 0; }.overlay.fade { opacity: 0.6; }.overlay { position: absolute; width: 100vw; height: 100vh; opacity: 0; background: black; transition: opacity 300ms ease-out; }.panel.slide { transform: translateX(0%); }.panel { position: absolute; height: 100vh; width: 18rem; background: #c00136; transform: translateX(-100%); transition: transform 300ms ease-out; }.menu { padding: 1rem 1rem; list-style-type: none; }.menu li.hidden { visibility: hidden; }.menu li { color: #f7f7f7; margin: 1rem 0; }.menu li.fadeInLeft { animation: fadeInLeft 350ms ease calc(var(--i) * 200ms) both; } @keyframes fadeInLeft { 0% { opacity: 0; transform: translateX(-2em); } 100% { opacity: 1; } }
 <div class="navigation"> <button id="toggle-button"> <svg class="menu-button" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> </svg> </button> <div class="overlay-container hidden"> <div class="overlay"></div> <div class="panel"> <ul class="menu"> <li class="hidden" style="--i:1">Menu item #1</li> <li class="hidden" style="--i:2">Menu item #2</li> <li class="hidden" style="--i:3">Menu item #3</li> <li class="hidden" style="--i:4">Menu item #4</li> </ul> </div> </div> </div>

EDIT I used the snippet from Roko C.编辑我使用了来自 Roko C 的片段。 Buljan's answer to change my timing logic, as I was doing that with javascript and it makes the example so much simpler. Buljan 更改我的时序逻辑的答案,正如我使用 javascript 所做的那样,它使示例变得更加简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM