需求
一些Mobile版本的网站,上面顶部菜单图标,按上去可以展开菜单,再点击,可以收回菜单,如图所示:
![]()
下面分享我项目中用到的菜单Toggle效果的代码
实现
利用CSS画出三个横线,以及一个叉叉,然后加入动画效果
<!doctype html>
<html>
<head>
<style>
.menu-toggle .span {
height: 2px;
margin: 7px 0 0 0;
transition: all .3s ease-out;
backface-visibility: visible;
visibility: visible;
opacity: 1;
}
.menu-toggle {
position: absolute;
right: 10px;
top: 10px;
z-index: 999;
width: 24px;
height: 24px;
cursor: pointer;
float: right;
transition: all .3s ease-out;
}
.menu-toggle .span {
border-radius: 5px;
background: #0478cf;
transition: all 0.3s ease-out;
backface-visibility: hidden;
}
.menu-toggle .top.span.active {
transform: rotate(45deg) translateX(3px) translateY(5px);
}
.menu-toggle .middle.span.active {
opacity: 0;
}
.menu-toggle .bottom.span.active {
transform: rotate(-45deg) translateX(8px) translateY(-10px);
}
</style>
</head>
<body>
<div id="app">
<div class="menu-toggle" @click="menuToggled()">
<div class="span top" :class="{ active: isMenuActive }"></div>
<div class="span middle" :class="{ active: isMenuActive }"></div>
<div class="span bottom" :class="{ active: isMenuActive }"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var app = new Vue({
el: '#app',
data: {
isMenuActive: false,
},
created() {
},
methods: {
menuToggled: function () {
this.isMenuActive = !this.isMenuActive;
},
}
})
</script>
</body>
</html>
另一种写法:
<!doctype html>
<html>
<head>
<style>
.frame {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
margin-top: -200px;
margin-left: -200px;
border-radius: 2px;
box-shadow: 1px 2px 10px 0px rgba(0, 0, 0, 0.3);
background: #3FAF82;
color: #fff;
}
.center {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.menu-icon {
width: 80px;
height: 52px;
cursor: pointer;
z-index: 50;
}
.menu-icon .line-1,
.menu-icon .line-2,
.menu-icon .line-3 {
height: 8px;
width: 100%;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.3);
transition: background-color .2s ease-in-out;
}
.menu-icon .line-1 {
-webkit-animation: animate-line-1-rev .7s ease-in-out;
animation: animate-line-1-rev .7s ease-in-out;
}
.menu-icon .line-2 {
margin: 14px 0;
-webkit-animation: animate-line-2-rev .7s ease-in-out;
animation: animate-line-2-rev .7s ease-in-out;
}
.menu-icon .line-3 {
-webkit-animation: animate-line-3-rev .7s ease-in-out;
animation: animate-line-3-rev .7s ease-in-out;
}
.menu-icon:hover .line-1,
.menu-icon:hover .line-2,
.menu-icon:hover .line-3 {
background-color: #fff;
}
.menu-icon.active .line-1,
.menu-icon.active .line-2,
.menu-icon.active .line-3 {
background-color: #fff;
}
.menu-icon.active .line-1 {
-webkit-animation: animate-line-1 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
animation: animate-line-1 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
}
.menu-icon.active .line-2 {
-webkit-animation: animate-line-2 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
animation: animate-line-2 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
}
.menu-icon.active .line-3 {
-webkit-animation: animate-line-3 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
animation: animate-line-3 0.7s cubic-bezier(0.3, 1, 0.7, 1) forwards;
}
.no-animation {
-webkit-animation: none !important;
animation: none !important;
}
@-webkit-keyframes animate-line-1 {
0% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
50% {
-webkit-transform: translate3d(0, 22px, 0) rotate(0);
transform: translate3d(0, 22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 22px, 0) rotate(45deg);
transform: translate3d(0, 22px, 0) rotate(45deg);
}
}
@keyframes animate-line-1 {
0% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
50% {
-webkit-transform: translate3d(0, 22px, 0) rotate(0);
transform: translate3d(0, 22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 22px, 0) rotate(45deg);
transform: translate3d(0, 22px, 0) rotate(45deg);
}
}
@-webkit-keyframes animate-line-2 {
0% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
100% {
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0;
}
}
@keyframes animate-line-2 {
0% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
100% {
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0;
}
}
@-webkit-keyframes animate-line-3 {
0% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
50% {
-webkit-transform: translate3d(0, -22px, 0) rotate(0);
transform: translate3d(0, -22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, -22px, 0) rotate(135deg);
transform: translate3d(0, -22px, 0) rotate(135deg);
}
}
@keyframes animate-line-3 {
0% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
50% {
-webkit-transform: translate3d(0, -22px, 0) rotate(0);
transform: translate3d(0, -22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, -22px, 0) rotate(135deg);
transform: translate3d(0, -22px, 0) rotate(135deg);
}
}
@-webkit-keyframes animate-line-1-rev {
0% {
-webkit-transform: translate3d(0, 22px, 0) rotate(45deg);
transform: translate3d(0, 22px, 0) rotate(45deg);
}
50% {
-webkit-transform: translate3d(0, 22px, 0) rotate(0);
transform: translate3d(0, 22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
}
@keyframes animate-line-1-rev {
0% {
-webkit-transform: translate3d(0, 22px, 0) rotate(45deg);
transform: translate3d(0, 22px, 0) rotate(45deg);
}
50% {
-webkit-transform: translate3d(0, 22px, 0) rotate(0);
transform: translate3d(0, 22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
}
@-webkit-keyframes animate-line-2-rev {
0% {
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
}
@keyframes animate-line-2-rev {
0% {
-webkit-transform: scale(0);
transform: scale(0);
opacity: 0;
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1;
}
}
@-webkit-keyframes animate-line-3-rev {
0% {
-webkit-transform: translate3d(0, -22px, 0) rotate(135deg);
transform: translate3d(0, -22px, 0) rotate(135deg);
}
50% {
-webkit-transform: translate3d(0, -22px, 0) rotate(0);
transform: translate3d(0, -22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
}
@keyframes animate-line-3-rev {
0% {
-webkit-transform: translate3d(0, -22px, 0) rotate(135deg);
transform: translate3d(0, -22px, 0) rotate(135deg);
}
50% {
-webkit-transform: translate3d(0, -22px, 0) rotate(0);
transform: translate3d(0, -22px, 0) rotate(0);
}
100% {
-webkit-transform: translate3d(0, 0, 0) rotate(0deg);
transform: translate3d(0, 0, 0) rotate(0deg);
}
}
</style>
</head>
<body>
<div id="app">
<div class="frame">
<div class="center">
<div class="menu-icon" :class="{active: isMenuActive}" @click="menuToggled">
<div class="line-1"></div>
<div class="line-2"></div>
<div class="line-3"></div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var app = new Vue({
el: '#app',
data: {
isMenuActive: true,
},
created() {
console.log("created")
},
methods: {
menuToggled: function() {
this.isMenuActive = !this.isMenuActive;
console.log(this.isMenuActive);
},
}
})
</script>
</body>
</html>
文章评论