基于vue实现圆形菜单栏组件


Posted in Javascript onJuly 05, 2019

基于vue实现圆形菜单栏组件

整个样式都是基于css3 得transform而实现得。

每个扇形角度为360/12=30deg,当然,你不想做圆形也可以,公式就是     扇形角度=你想绘制得角度/扇形个数

当你计算好每个扇形得角度时,需要将li元素倾斜,倾斜角度=90-扇形面积,我的这个倾斜角度就是90-30=60deg,然后使用css3 得skew()

基于vue实现圆形菜单栏组件 

circle-panel-1

基于vue实现圆形菜单栏组件

circle-panel-2

基于vue实现圆形菜单栏组件

circle-panel-3

当每个扇形倾斜60deg之后,会在原来得位置上,要想每个扇形有规律得组合在一起,那么就要旋转相应得角度,30deg,60deg,90deg…….这个以扇形得圆心角递加。

这是基础组件得完整代码,父组件只需导入使用传给子组件数据就可以了,当点击每个扇形得事件也在父组件监听实现相应的逻辑。script部分我加了js代码和ts代码,没有用过ts得小伙伴就忽略直接参考js代码就可以了。并且我调用了手势库hammer.js,这个库很全,大家感兴趣得可以去查一下使用方法,这样这个圆环是可以旋转得。

<template>
 <div id="cn-wrapper" :style="{transform:'rotate('+rotatePanel+'deg)'}" class="cn-wrapper" >
  <ul>
   <li @click="clickPanel(item)" v-for="(item,index) in panel" :key="index">
    <a href="#">
     <img class="li-img" :src="item.img" alt />
     <div class="li-text">{{item.title}}</div>
    </a>
   </li>
  </ul>
 </div>
</template>
 
<script >
// import { Component, Prop, Vue,Emit } from 'vue-property-decorator';
 
// @Component
// export default class CirclePanel extends Vue {
//  private rotatePanel=0;
//  @Prop() panel!: any;
 
//  mounted(){
//   this.initPanel()
//  }
 
//   // 操作版
//  @Emit()
//  clickPanel(item:any){
//   return item;
//  }
//  initPanel(){
//   let panel=document.getElementById("cn-wrapper") as HTMLElement;
//   let panelMan = new Hammer.Manager(panel);
//   panelMan.add(new Hammer.Pan({
//     threshold: 0
//    }));
//   panelMan.on('panstart', (ev: any) => {
//    if (ev.center.x < panel.clientWidth/2) {//左边
//     this.rotatePanel= this.rotatePanel - ev.angle
//    }else{
//     this.rotatePanel= this.rotatePanel + ev.angle
//     }
//   });
//  }
// }
 
export default {
   data () {
      return {
         rotatePanel: 0
      }
   },
   props: {
      panel: {
         type: Array,
         default: [    {img:'pics-gem/1.png',title:'一月石榴石'},
    {img:'pics-gem/2.png',title:'一月石榴石'},
    {img:'pics-gem/3.png',title:'一月石榴石'},
    {img:'pics-gem/4.png',title:'一月石榴石'},
    {img:'pics-gem/5.png',title:'一月石榴石'},
    {img:'pics-gem/6.png',title:'一月石榴石'},
    {img:'pics-gem/7.png',title:'一月石榴石'},
    {img:'pics-gem/8.png',title:'一月石榴石'},
    {img:'pics-gem/9.png',title:'一月石榴石'},
    {img:'pics-gem/10.png',title:'一月石榴石'},
    {img:'pics-gem/11.png',title:'一月石榴石'},
    {img:'pics-gem/12.png',title:'一月石榴石'},]
      },
   },
   activated(){
    this.initPanel()
   },
   methods: {
     // 操作版
     clickPanel(item){
      this.$emit('clickPanel',{item})
     },
     initPanel(){
      let panel=document.getElementById("cn-wrapper");
      let panelMan = new Hammer.Manager(panel);
      panelMan.add(new Hammer.Pan({
        threshold: 0
       }));
      panelMan.on('panstart', (ev) => {
       if (ev.center.x < panel.clientWidth/2) {//左边
        this.rotatePanel= this.rotatePanel - ev.angle
       }else{
        this.rotatePanel= this.rotatePanel + ev.angle
        }
      });
     }
   }
}
</script>
 
<style scoped>
.cn-wrapper {
 font-size: 1em;
 width: 24em;
 height: 24em;
 overflow: hidden;
 position: fixed;
 z-index: 10;
 bottom: 84px;
 margin-left: -288px;
 left: 50%;
 border-radius: 50%;
 -webkit-transform: scale(0.1);
 -ms-transform: scale(0.1);
 -moz-transform: scale(0.1);
 transform: scale(1);
 /* pointer-events: none; */
 -webkit-transition: all 0.3s ease;
 -moz-transition: all 0.3s ease;
 transition: all 0.3s ease;
}
 
.cn-wrapper li {
 position: absolute;
 font-size: 1.5em;
 width: 10em;
 height: 10em;
 -webkit-transform-origin: 100% 100%;
 -moz-transform-origin: 100% 100%;
 -ms-transform-origin: 100% 100%;
 transform-origin: 100% 100%;
 overflow: hidden;
 left: 50%;
 /* top: 50%; */
 margin-top: -2em;
 /* border: solid 1px #f2cc81; */
 margin-left: -10em;
 -webkit-transition: border 0.3s ease;
 -moz-transition: border 0.3s ease;
 transition: border 0.3s ease;
}
 
.cn-wrapper li a {
 display: block;
 font-size: 1.18em;
 height: 14.5em;
 width: 14.5em;
 /* position: absolute; */
 position: fixed; /* fix the "displacement" bug in webkit browsers when using tab key */
 bottom: -7.25em;
 right: -7.25em;
 border-radius: 50%;
 text-decoration: none;
 color: #fff;
 padding-top: 1em;
 text-align: center;
 -webkit-transform: skew(-60deg) rotate(-70deg) scale(1);
 -ms-transform: skew(-60deg) rotate(-70deg) scale(1);
 -moz-transform: skew(-60deg) rotate(-70deg) scale(1);
 transform: skew(-60deg) rotate(-70deg) scale(1);
 -webkit-backface-visibility: hidden;
 -webkit-transition: opacity 0.3s, color 0.3s;
 -moz-transition: opacity 0.3s, color 0.3s;
 transition: opacity 0.3s, color 0.3s;
}
 
/* for a central angle x, the list items must be skewed by 90-x degrees
in our case x=40deg so skew angle is 50deg
items should be rotated by x, minus (sum of angles - 180)2s (for this demo) */
 
.cn-wrapper li:first-child {
 transform: rotate(-10deg) skew(60deg);
}
 
.cn-wrapper li:nth-child(2) {
 transform: rotate(20deg) skew(60deg);
}
 
.cn-wrapper li:nth-child(3) {
 transform: rotate(50deg) skew(60deg);
}
 
.cn-wrapper li:nth-child(4) {
 transform: rotate(80deg) skew(60deg);
}
 
.cn-wrapper li:nth-child(5) {
 transform: rotate(110deg) skew(60deg);
}
.cn-wrapper li:nth-child(6) {
 transform: rotate(140deg) skew(60deg);
}
.cn-wrapper li:nth-child(7) {
 transform: rotate(170deg) skew(60deg);
}
.cn-wrapper li:nth-child(8) {
 transform: rotate(200deg) skew(60deg);
}
.cn-wrapper li:nth-child(9) {
 transform: rotate(230deg) skew(60deg);
}
.cn-wrapper li:nth-child(10) {
 transform: rotate(260deg) skew(60deg);
}
.cn-wrapper li:nth-child(11) {
 transform: rotate(290deg) skew(60deg);
}
.cn-wrapper li:nth-child(12) {
 transform: rotate(320deg) skew(60deg);
}
 
.cn-wrapper li:nth-child(odd) a {
 background-color: #a11313;
 background-color: hsla(0, 88%, 63%, 1);
}
 
.cn-wrapper li:nth-child(even) a {
 background-color: #a61414;
 background-color: hsla(0, 88%, 65%, 1);
}
 
/* active style */
.cn-wrapper li.active a {
 /* background-color: #b31515;
 background-color: hsla(0, 88%, 70%, 1); */
 background-color: rgba(135, 137, 155, 0.52);
 border: solid 0px #f2cc81;
}
 
/* hover style */
.cn-wrapper li:not(.active) a:hover,
.cn-wrapper li:not(.active) a:active,
.cn-wrapper li:not(.active) a:focus {
 background-color: rgba(135, 137, 155, 0.52);
 border: solid 0px #f2cc81;
}
 
.li-img {
 width: 50px;
 margin-bottom: 44px;
 margin-left: -30px;
}
.li-text {
 color: #f2cc81;
 font-size: 20px;
 line-height: 1.4;
 width: 76px;
 margin: 0 calc(50% - 50px);
}
</style>

父组件调用:

<div class="making-panel">
     <CirclePanel :title="title" :panel="panel"
           @clickTab="clickTabCircle"
           @clickPanel="clickPanel" ></CirclePanel>
  </div>

总结

以上所述是小编给大家介绍的基于vue实现圆形菜单栏组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
js停止输出代码
Jul 20 Javascript
JS控制图片等比例缩放的示例代码
Dec 24 Javascript
Jquery下EasyUI组件中的DataGrid结果集清空方法
Jan 06 Javascript
laytpl 精致巧妙的JavaScript模板引擎
Aug 29 Javascript
很棒的一组js图片轮播特效
Jan 12 Javascript
对称加密与非对称加密优缺点详解
Feb 06 Javascript
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
Aug 25 Javascript
require.js 加载过程与使用方法介绍
Oct 30 Javascript
原生js实现的移动端可拖动进度条插件功能详解
Aug 15 Javascript
微信小程序实现星级评价
Nov 20 Javascript
在vue和element-ui的table中实现分页复选功能
Dec 04 Javascript
JavaScript实现复选框全选和取消全选
Nov 20 Javascript
vue 使用axios 数据请求第三方插件的使用教程详解
Jul 05 #Javascript
vue中实现Monaco Editor自定义提示功能
Jul 05 #Javascript
VueCli3.0中集成MockApi的方法示例
Jul 05 #Javascript
Electron vue的使用教程图文详解
Jul 05 #Javascript
监控微信小程序中的慢HTTP请求过程详解
Jul 05 #Javascript
JS实现求字符串中出现最多次数的字符和次数示例
Jul 05 #Javascript
JS Math对象与Math方法实例小结
Jul 05 #Javascript
You might like
咖啡知识大全
2021/03/03 新手入门
PHP为表单获取的URL 地址预设 http 字符串函数代码
2010/05/26 PHP
通过dbi使用perl连接mysql数据库的方法
2014/04/16 PHP
php使用cookie实现记住用户名和密码实现代码
2015/04/27 PHP
php实现文件与16进制相互转换的方法示例
2017/02/16 PHP
基于CI(CodeIgniter)框架实现购物车功能的方法
2018/04/09 PHP
JavaScript实现禁止后退的方法
2006/12/27 Javascript
javascript之解决IE下不渲染的bug
2007/06/29 Javascript
jQuery中:enabled选择器用法实例
2015/01/04 Javascript
原生js实现addClass,removeClass,hasClass方法
2016/04/27 Javascript
js实现手机拍照上传功能
2017/01/17 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
2017/03/24 Javascript
使用jQuery实现页面定时弹出广告效果
2017/08/24 jQuery
实例详解ztree在vue项目中使用并且带有搜索功能
2018/08/24 Javascript
django中使用vue.js的要点总结
2019/07/07 Javascript
jQuery实现滑动开关效果
2020/08/02 jQuery
[13:21]DOTA2国际邀请赛采访专栏:RSnake战队国士无双,Fnatic.Fly
2013/08/06 DOTA
Python中类的继承代码实例
2014/10/28 Python
常见python正则用法的简单实例
2016/06/21 Python
Python 专题二 条件语句和循环语句的基础知识
2017/03/19 Python
python 统计代码行数简单实例
2017/05/04 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
Python3使用Matplotlib 绘制精美的数学函数图形
2019/04/11 Python
python基于递归解决背包问题详解
2019/07/03 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
RentCars.com巴西:汽车租赁网站
2016/08/22 全球购物
Aquatalia官网:意大利著名鞋履品牌
2019/09/26 全球购物
英文请假条
2014/04/11 职场文书
期末评语大全
2014/05/04 职场文书
财务会计专业求职信
2014/06/09 职场文书
大专毕业生求职信
2014/07/05 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
2014年扶贫工作总结
2014/11/18 职场文书
如何利用Matlab制作一款真正的拼图小游戏
2021/05/11 Python