vue下CSS实现带动画效果的菜单图标点击切换效果,干货代码

2021-09-05 1016点热度 0人点赞 0条评论

需求

一些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>

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论