用vue做一个酷炫的menu

写在前面

        最近看到一个非常酷炫的menu插件,一直想把它鼓捣成vue形式,谁让我是vue的死灰粉呢,如果这都不算爱?。?开个小玩耍,我们一起来探索黑魔法吧。观看本教程的读者需要具备一定的vue和css3的知识.

本文结构

1.效果演示

2.使用方法介绍

3.关键步骤讲解

正文

1.效果演示

 

1240

pic_1

 

1240

pic2

 

1240

pic_3

     在线演示live demo

2.使用介绍

        项目地址:github.com/MingSeng-W/vue-bloom-menu,clone项目到本地

       a. 首先在单文件组件里引入menu组件,导入common文件夹stylus里的menuConfig.stylus.

       b.配置相应的参数

            可选参数

            * radius:default为100px,item距离menu的button的距离。

            *  startAngle:defaut为0,item开始的角度,以时钟3点钟方向记为0,然后顺时针方向为递增方向。

           *  endAngle:default为315,最后一个item的角度。

           *  itemNum:default为8

            *  animationDuration:default为0.5s,每个item动画的执行时间

            *  itemAnimationDelay:default为0.04s,每个item之间animation触发的间隔延迟时间

          必选参数

            * iconImgArr

        import您需要的icon,然后生成iconImgArr(computed属性绑定),作为props传给menu组件

           menu的位置

    目前有center,corner两种位置,在menu的class里指定。center的class:.menu-center-wrapper

corner的class:.menu-left-corner-wrapper。当然自己指定位置也是ok的。

          一个简单的example

 

1240

demo

3.关键步骤讲解

    整个menu的实现关键在于计算menu展开后最后的坐标,以及展开与收缩的动画.(由于整个项目布局比较简单,所以这里主要讲解逻辑和动画的实现)

    第一步:计算menu展开后横坐标和纵坐标

        下面的x,y分别表示item在页面的位置,以x为例。

    x:原始的位置,x2最后展开的位置,x1中间的过渡位置(主要是造成一个“拉回”的效果),以下是图片解释,为了解释简单明了,我放大了radius倍数以及增加了动画的执行时间。

 

1240

位置解释

    位置的计算:首先计算每个item之间的夹角,起始item是沿着顺时针布局的,每个item之间的夹角等于(endAngle-startAngle)/(itemNum-1)。当前item应该旋转的角度为:angleCur=startAngle+index*每个item之间的夹角。得到item的旋转角度之后,用Math.cos和Math.sin和radius相乘得到其横坐标和纵坐标.

    关键代码:

1240

计算每个item的夹角

1240

位置解释

第二步,根据生成的坐标使用js动态生成animtion,并插入到样式文件中。

1240

生成展开和收缩的keyframe

到这一步我们完成了点击menu展开与收缩。

    第二步,完成点击item之后item放大与消失,其他的item缩小与消失

    item消失的keyframe

    

1240

    item消失的keyframe

    这里触发动画使用vue提供transition ,当元素的v-show为false时,也就是display为none时,触发动画。

    每个item动画完成后都会触发animationEnd事件,监听item的animationEnd事件,当所有动画依次触发完毕之后,提醒menu置于关闭状态(父子组件通信 )。

    我在menu组件里使用v-on监听animationEnd事件,item自己的动画执行后,通过$emit触发animationEnd事件,通知menu的动画计数count++,当count达到总的项目数的时候,menu进行关闭.

1240

code

1240

code

1240

      再次打开menu的时候检查与item绑定的showItem是否为false,是的话置为true。点击时需要拿到被点击item的index,得到全局的currentIndex即被点击的item的index。被点中的使用放大动画,否则使用缩小动画。

1240

pic_6

 

1240

关键代码

至此所有步骤讲解完毕

转载于:https://my.oschina.net/u/3727086/blog/1573075

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些思路和代码示例。 首先,我们可以使用Vue3的Composition API来编写组件。我们可以创建一个LoginForm组件,它包含一个表单,用于输入用户名和密码。 ```html <template> <form> <label for="username">Username:</label> <input type="text" id="username" v-model="username"> <label for="password">Password:</label> <input type="password" id="password" v-model="password"> <button type="submit">Login</button> </form> </template> <script> import { ref } from 'vue'; export default { setup() { const username = ref(''); const password = ref(''); const handleSubmit = (event) => { event.preventDefault(); // TODO: handle login logic }; return { username, password, handleSubmit, }; }, }; </script> ``` 接下来,我们可以使用CSS来美化我们的登录界面。我们可以使用CSS3的渐变效果和动画效果来实现酷炫的效果。例如,我们可以使用以下CSS样式来实现一个渐变背景和一个动画效果,当用户输入用户名和密码时,表单会向上移动。 ```css <style> form { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; background: linear-gradient(to bottom right, #00c6ff, #0072ff); overflow: hidden; } input[type='text'], input[type='password'] { padding: 10px; margin: 10px; border: none; border-radius: 5px; background-color: #f5f5f5; font-size: 1.2em; width: 300px; height: 50px; box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); transition: all 0.3s ease-in-out; } input[type='text']:focus, input[type='password']:focus { transform: translateY(-20px); box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3); } button[type='submit'] { padding: 10px 20px; margin: 10px; border: none; border-radius: 5px; background-color: #0072ff; color: #fff; font-size: 1.2em; cursor: pointer; box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); transition: all 0.3s ease-in-out; } button[type='submit']:hover { background-color: #00c6ff; box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3); } </style> ``` 最后,我们可以将LoginForm组件导出并在App.vue中使用它。 ```html <template> <LoginForm /> </template> <script> import LoginForm from './components/LoginForm.vue'; export default { components: { LoginForm, }, }; </script> ``` 这样,我们就完成了一个简单而酷炫的登录界面。您可以根据自己的需求添加更多功能和样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值