利用css的cubic-bezier函数做出动态的缓冲效果

cubic-bezier即三次贝塞尔,可以生成贝塞尔曲线,在css中主要是给transition以及animation提供过渡效果的速度曲线

cubic-bezier函数默认接受四个参数,cubic-bezier(x1,y1,x2,y2),其中y1、y2是可以大于或小于0的,基于此可以做出一些缓冲的过渡效果

<template>
    <div class="menu">
        <div v-for="item in menuList">
            <div class="menu-item" @mouseover="mouseover($event, item)" @mouseleave="mouseleave">{{ item.name }}</div>
        </div>
    </div>
    <transition name="move">
        <div id="sub-menu" ref="subMenu" v-show="show" @mousemove="overSub">
            <div class="sub-menu-item" v-for="item in subMenuList">
                {{ item.name }}
            </div>
        </div>
    </transition>
</template>

<script>
import { ref } from 'vue';
export default {
    setup() {
        let menuList = ref([
            {
                name: 'cloud',
                children: [
                    {
                        name: 'cloud1'
                    },
                    {
                        name: 'cloud2'
                    }
                ]
            },
            {
                name: 'software',
                children: [
                    {
                        name: 'software1'
                    },
                    {
                        name: 'software2'
                    },
                    {
                        name: 'software3'
                    }
                ]
            },
            {
                name: 'docs',
                children: [
                    {
                        name: 'docs1'
                    },
                    {
                        name: 'docs2'
                    }
                ]
            }
        ]);
        let subMenuList = ref([]);
        let show = ref(false);
        return { menuList, subMenuList, show };
    },
    methods: {
        mouseover(e, item) {
            this.subMenuList = item.children;
            this.$refs.subMenu.style.left = e.target.offsetLeft + 'px';
            this.$refs.subMenu.style.height = `${43 * this.subMenuList.length}px`;
            this.show = true;
        },
        mouseleave() {
            this.show = false;
        }
    }
};
</script>

<style scoped>
.menu {
    display: flex;
}
.menu-item {
    height: 40px;
     fit-content;
    margin-left: 20px;
    font-size: 26px;
    font-weight: lighter;
    color: #aaa;
    cursor: pointer;
}
#sub-menu {
    position: absolute;
    font-size: 32px;
    font-weight: lighter;
    color: #000;
    border: solid 1px #ccc;
    padding: 15px;
    border-radius: 10px;
}
.move-enter-active,
.move-leave-active {
    transition: all 0.3s cubic-bezier(0.175, 0.585, 0.32, 1.275);
}
</style>

没有用原生的transition属性是因为v-if不支持,所以必须结合vue的transition组件

其中 cubic-bezier(0.175, 0.885, 0.32, 1.275);  是提供过渡效果的关键,可以看出整个菜单会有一个缓冲的过渡效果,视觉上也更加具有冲击力

补充一个html版本,可以直接打开看效果

<body>
    <div class="menu">
        <div class="menu-item">cloud</div>
        <div class="menu-item">software</div>
        <div class="menu-item">docs</div>
    </div>
    <div id="sub-menu">
        <div class="sub-menu-item">cloud1</div>
        <div class="sub-menu-item">cloud2</div>
    </div>
    <script>
        (function () {
            let menu = document.getElementsByClassName('menu-item');
            let subMenu = document.getElementById('sub-menu');
            for (let item of menu) {
                item.addEventListener('mouseover', function () {
                    subMenu.style.visibility = 'visible';
                    subMenu.style.left = item.offsetLeft;
                });
                item.addEventListener('mouseleave', function () {
                    subMenu.style.visibility = 'hidden';
                });
            }
        })();
    </script>
</body>
<style>
    .menu {
        display: flex;
    }
    .menu-item {
        height: 40px;
        width: fit-content;
        margin-left: 20px;
        font-size: 26px;
        font-weight: lighter;
        color: #aaa;
        cursor: pointer;
    }
    #sub-menu {
        visibility: hidden;
        position: absolute;
        font-size: 32px;
        font-weight: lighter;
        color: #000;
        border: solid 1px #ccc;
        padding: 15px;
        border-radius: 10px;
        transition: all 0.35s cubic-bezier(0.175, 0.585, 0.32, 1.275);
    }
</style>
原文地址:https://www.cnblogs.com/chh1995/p/14554698.html