javascript - 汉堡按钮上的反向动画
问题描述
我正在尝试为汉堡按钮设置动画。问题是动画只适用于第一次点击,我不知道如何让第二次点击做反向动画。我不确定这是否可以在不使用关键帧的情况下完成。附言。css 中的括号未格式化,因为它是从 scss 编译的。
var hamburger = document.getElementById("hamburger");
var nav_items = document.getElementsByClassName("nav-items")[0];
var line1 = document.getElementsByClassName("line1")[0];
var line2 = document.getElementsByClassName("line2")[0];
var line3 = document.getElementsByClassName("line3")[0];
hamburger.addEventListener("click", function() {
nav_items.classList.toggle("nav-open");
line1.classList.toggle("first-line");
line2.classList.toggle("middle-line-hidden");
line3.classList.toggle("last-line");
});
body {
background-color: white;
margin: 0;
padding: 0;
}
#navbar {
position: fixed;
top: 0;
width: 100%;
height: 100px;
color: white;
z-index: 100;
background-color: blue;
}
#logo {
position: absolute;
top: 50%;
left: 25px;
transform: translateY(-50%);
font-size: 25px; }
#logo a {
text-decoration: none;
color: white; }
#logo a::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
height: 5px;
width: 100%;
background-color: yellow;
z-index: -1; }
.nav-items {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
visibility: hidden;
justify-content: center;
font-size: 2rem;
background-color: black; }
.nav-items a {
text-decoration: none;
color: white;
margin: 15px 0; }
.nav-items a:first-child {
margin-top: 0; }
.nav-items a:hover {
color: yellow; }
#hamburger {
height: 40px;
width: 40px;
background-color: transparent;
border: 0px solid transparent;
padding: 0;
position: absolute;
right: 80px;
top: 50%;
transform: translateY(-50%);
z-index: 100;
}
#hamburger .line1,
#hamburger .line2,
#hamburger .line3 {
position: absolute;
left: 0;
height: 5px;
width: 100%;
background-color: white;
border-radius: 25px;
transition: 0.5s linear; }
#hamburger .line1 {
top: 3px; }
#hamburger .line2 {
top: 50%;
transform: translateY(-50%); }
#hamburger .line3 {
bottom: 3px; }
.nav-open {
visibility: visible; }
.middle-line-hidden {
animation: hamburger-mid-line 0s linear;
animation-fill-mode: forwards;
animation-delay: 0.3s; }
.first-line {
animation: hamburger-first-line 0.5s;
animation-fill-mode: forwards; }
.last-line {
animation: hamburger-last-line 0.5s;
animation-fill-mode: forwards; }
@keyframes hamburger-mid-line {
from {
visibility: visible; }
to {
visibility: hidden; } }
@keyframes hamburger-first-line {
0% { }
50% {
top: 50%;
transform: translateY(-50%); }
100% {
top: 42%;
transform: rotate(45deg); } }
@keyframes hamburger-last-line {
0% { }
50% {
bottom: 50%;
transform: translateY(50%); }
100% {
bottom: 45%;
transform: rotate(-45deg); } }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./css/main.css" />
</head>
<body>
<header id="navbar">
<div class="nav-items">
<a href="#">link1</a>
<a href="#">link2</a>
<a href="#">link3</a>
</div>
<button id="hamburger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</button>
</header>
</body>
</html>
解决方案
最简单的方法是在 css 中将动画分配给一个类,例如带有开场动画的 .openedhamburger。
现在使用结束动画创建分配给其他类的其他动画,例如 .closedhamburger。
最后用javascript切换分配给元素的类,只要分配不同的类,就会触发正确的动画。
编辑:另外,虽然在你的情况下使用两步动画,所以这不适用,知道使用这个类方法,如果你启用平滑过渡,那么有时你甚至可以在没有任何动画的情况下做到这一点:只需关联位置和在两种状态下旋转元素,然后因为启用了平滑变换,所以会出现动画。
推荐阅读
- haskell - 将多个列表的内容加在一起
- c++ - 使用元胞自动机生成洞穴
- python - Python 文件未运行,并显示此错误:repl 进程意外死亡
- sql - 将动态多边形 JSON 数组转换为 SQL Server 中的计算几何列
- sql - 如何使用 Oracle regexp_replace 删除数字之间的空格和特殊字符
- vue.js - Nuxt.js:`npm run generate` 无法生成 `index.html`
- arrays - 如何替换 fgets() 放在字符串末尾的 '''\n''' 什么都没有(或 '' 只是不是 \0 所以字符串不会结束)?
- netlogo - 访问列表中项目的值
- javascript - 如何防止测试被汇总捆绑?
- apache-kafka - Reactor - Kafka - 消费者在处理消息时因错误而停止