前言

上一篇面试的总结,大家看的还行,因为量很大,错误在所难免,希望大家发现错误了可以告诉我一声,我的邮箱是236490794@qq.com,一个小前端的希望。

言归正传

我们老样子直接先上效果图再开始今天的分享
这个项目的github可以看一看

组件分析

  1. 界面组成
  2. 逻辑分析
  3. 最终实现
界面组成

从上图中,我们可以看出界面主要分为menu和item2块,其中menu的动画是自传,item的动画是位移,然后这里我们通过绝对布局的方式将整个控件定位在四个角落

.menu_container {position: absolute;z-index: 100;border-radius: 50%;transition-duration: 400ms;text-align: center;border: #efefef 3px solid;box-shadow: aliceblue 1px 1px 1px;}.menu_item {position: absolute;border-radius: 50%;z-index: 99;border: #efefef 3px solid;text-align: center;box-shadow: aliceblue 1px 1px 1px;}
逻辑分析

这里我将这个控件几个属性独立出来,方便下次开发,其中包含,menu的背景,整个控件在屏幕的哪个角落,menu的宽高,item距离menu位移的距离,menu的背景色,及item的背景色,item的相关内容则由数据来控制,具体的我们直接在下方的实现里来讲解。

最终实现

这里我用代码加注释的方式,帮助大家理解,template我简单的带过一下

<div><div class="menu_container" ref="menuHome" @click="toggleMenu"><img :src="menuSrc"><!--menu图--></div><div class="menu_item" v-for="(item,index) in menuItems" :id="item.name" @click="clickMenu(item,index)"><img :src="item.src"><!--item图--></div></div>

核心实现
通过分析可以得出,每个item的偏移量应该为
横向x:基础值 * sin(角度值)
纵向y:基础值 * cos(角度值)
角度值:(数组的长度-1-当前的下标) 每一块所占的角度 弧度表示
弧度表示:2 * Math.PI / 360

export default {...props: {//开放的属性,方便自定义menuSrc: {default: require('../assets/menu.png')},position: {default: 'LT'//可选择LT、LB、RT、RB4个角落},width: {default: 50,},baseDistance: {default: 150,},menuBg: {default: 'white'},itemBg: {default: 'white'},menuItems: {type: Array,}},data() {return {openFlag: false,//展开合并标志operators: ['+', '+'],//用于记录展开时动画XY方向}},mounted() {//根据props初始化各内容的各种stylethis.$refs.menuHome.style.width = this.width + 'px';this.$refs.menuHome.style.height = this.width + 'px';this.$refs.menuHome.style.lineHeight = this.width + 'px';this.$refs.menuHome.style.background = this.menuBg;this.menuItems.forEach((item) => {let el = document.getElementById(item.name);el.style.width = `${this.width * 0.8}px`;el.style.height = `${this.width * 0.8}px`;el.style.lineHeight = `${this.width * 0.8}px`;el.style.background = this.itemBg;});//根据position,选择不同的定位switch (this.position) {case 'LT':this.$refs.menuHome.style.left = '20px';this.$refs.menuHome.style.top = '20px';this.menuItems.forEach((item) => {let el = document.getElementById(item.name);el.style.left = '26px';el.style.top = '26px';});this.operators = ['+', '+'];break;...}},methods: {toggleMenu() {if (!this.openFlag) {//合并时,点击展开操作this.menuItems.forEach((item, index) => {this.toggleMenuTransition(item.name, index, false)});//menu本身转一周this.$refs.menuHome.style.transform = 'rotate(360deg)';} else {this.menuItems.forEach((item, index) => {this.toggleMenuTransition(item.name, index, true)});//menu恢复this.$refs.menuHome.style.transform = 'rotate(0)';}this.openFlag = !this.openFlag;},toggleMenuTransition(name, index, revert) {let oneArea = 90 / (this.menuItems.length - 1);//每一块所占的角度let axisX = Math.sin((this.menuItems.length - 1 - index) * oneArea * 2 * Math.PI / 360);//横坐标所偏移的比例let axisY = Math.cos((this.menuItems.length - 1 - index) * oneArea * 2 * Math.PI / 360);//纵坐标所便宜的比例let el = document.getElementById(name);//若所传的name一直,会报错。let that = this;if (!revert) {setTimeout(function () {el.style.transitionDuration = '200ms';el.style.transform = `translate(${that.operators[0]}${that.baseDistance * axisX}px,${that.operators[1]}${that.baseDistance * axisY }px)`;//进行动画}, index * 100)//通过定时器的方式,达到一个一个弹出来的效果} else {//item恢复el.style.transitionDuration = '200ms';el.style.transform = `translate(0,0)`;}},clickMenu(item, index) {//暴露方法给父组件,进行点击事件的操作this.$emit('clickMenu', item, index)}}}

再父组件中引入就可以大功告成啦,先跳一会儿吧,燃烧你的卡路里

父组件调用

引入组件

import toggleMenu from './toggleMenu'

在 components声明

components: {toggleMenu
},

template中使用

menuItems: [//name和src必填,且name唯一否则会报错{name: 'menu1', src: require('../assets/emoji.png')},{name: 'menu2', src: require('../assets/cart.png')},{name: 'menu3', src: require('../assets/folder.png')},{name: 'menu4', src: require('../assets/home.png')},{name: 'menu5', src: require('../assets/my.png')},
]
<toggle-menu :menuItems="menuItems"@clickMenu="clickMenu"></toggle-menu>

属性及方法一栏

属性名 用处 默认值 是否必须
position 四个方位(LT、LB、RT、RB) LT
menuBg 菜单背景 white
menuSrc 菜单图片 一个菜单图片
itemBg 按钮背景 white
width 按钮宽度 50px
baseDistance 位移距离,若item很多,可适当提高 150px
menuItems 菜单数组
方法名 用处 参数
clickMenu 点击item触发事件 item,index

好了,差不多就分享这么多,


我的github,求戳,求star

弹弹弹,弹走鱼尾纹的弹出菜单(vue)相关推荐

  1. 用 JA Transmenu 模块做多级弹出菜单

    转自http://www.joomlagate.com "弹出菜单"这个说法本来不规范,尽管你我都明白这是什么意思,而实际上我们所理解的那个菜单样式英文说法是"Slide ...

  2. JQUERY打造隐藏在左侧的弹性弹出菜单

    代码简介: 隐藏在左侧的弹性弹出菜单,从淘宝扣下来的,也可作为JAvaScript缓冲动画的典型教程.本弹性菜单可扩展性强,实际上不光可以做成菜单,也可布局一些图文混排的内容或一段视频,总之被弹出的内 ...

  3. vc+如何添加右键弹出菜单

    2019独角兽企业重金招聘Python工程师标准>>> 一.创建新工程 二.编辑菜单资源 1.添加菜单 按"Ctrl+R",双击"Menu"图 ...

  4. python tkinter 下拉框_python中tkinter入门之Menu创建顶级菜单、下拉菜单和弹出菜单。...

    创建顶级菜单 Menu 组件通常被用于实现应用程序上的各种菜单.使用add_command可以添加菜单内容.创建后通过root.config()添加到窗口上. from tkinter import ...

  5. 如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题

    如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题 参考文章: (1)如何利用PopupWindow实现弹出菜单并解决焦点获取以及与软键盘冲突问题 (2)https://ww ...

  6. android 单选、多选弹出菜单

    菜单单选窗口: import android.app.Activity; import android.app.AlertDialog; import android.content.DialogIn ...

  7. 纯CSS三级弹出菜单

    以前收藏的代码,贴出来分享下.兼容IE\FF. CSS: <style type="text/css"> /**//*common styling*/.menu{}{f ...

  8. 机器性能这么好,为什么点击右键弹出菜单还这么慢?

    为什么80%的码农都做不了架构师?>>>    我想很多人估计遇到过这样的问题,一开始估计会怀疑是系统问题或者是有什么硬件瓶颈. 其实不然, 在与一位同事交流后发现,其实问题的原因很 ...

  9. 教你如何创建类似QQ的android弹出菜单

    热心推荐: Android  ListView两种长按弹出菜单方式 popupwindow实现弹出菜单效果 Android人才招聘--最新招聘 大家可能看到 android 的自带的系统菜单比较难看, ...

最新文章

  1. Database design best practice(1):关于primary key及其它
  2. [BZOJ2502]清理雪道 有上下界网络流(最小流)
  3. 1、ios开发之 内购
  4. [JAVA]引入目录下所有jar包等问题
  5. [BZOJ 2555] SubString
  6. Android中使用AsyncTask实现文件下载以及进度更新提示
  7. linux下用脚本语言开发自动重启程序
  8. Vista曝致命漏洞 10秒钟可让系统崩溃
  9. 深度学习与硬件GPU,软件框架关系及相关概念解析
  10. Mybatis-generator自动生成
  11. 利用C#编写一个附和闭合导线平差程序
  12. 工控组态编程相关知识点介绍
  13. 如何在WordPress中添加免费实时聊天(简便方法)
  14. python将数据导入数据库 atomic_Python3 连接 Sqlite3
  15. html5附近餐厅,【天津】必吃的5家餐厅8种美食,让你的小长假周边游更完美!...
  16. GITC--2014全球互联网技术大会正式开始售票
  17. 《Java并发编程的艺术》——Java中的并发工具类、线程池、Execute框架(笔记)
  18. 对面向过程,对象,接口,切面的理解
  19. 虚拟机登陆界面一直转圈
  20. 一文讲透:HMM隐马尔科夫模型

热门文章

  1. 从市场观察到案例解析,来看TopOn与JoyPac的2020年手游出海运营全攻略
  2. 超简单的3步搭建静态网站(Franklin.jl)
  3. 如何选型APS系统,还需明确这七大关键因素
  4. 自学unity,该不该阻止?
  5. collapsible data-collapsed Jquery-mobile动态设置
  6. Linux(一): 磁盘分区
  7. 【Tableau 图表大全27】之区域图(面积图)
  8. h2o.ai源码解析(1)—项目简介
  9. php 实现斗牛算法,趣味js之斗牛算法详解
  10. 【_ 面試 】在单点登录中,如果 cookie 被禁用了怎么办?