基于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 相关文章推荐
Zero Clipboard js+swf实现的复制功能使用方法
Mar 07 Javascript
jquery tab标签页的制作
May 10 Javascript
javascript动态判断html元素并执行不同的操作
Jun 16 Javascript
JavaScript AOP编程实例
Jun 16 Javascript
Web前端框架bootstrap实战【第一次接触使用】
Dec 28 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
Jan 05 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
Dec 06 jQuery
vue使用element-ui的el-input监听不了回车事件的解决方法
Jan 12 Javascript
mpvue将vue项目转换为小程序
Sep 30 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
Aug 22 Javascript
JavaScript Blob对象原理及用法详解
Oct 14 Javascript
js实现纯前端压缩图片
Nov 16 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
php访问数组最后一个元素的函数end()用法
2015/03/18 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
php实用代码片段整理
2016/11/12 PHP
PHP实现文字写入图片功能
2019/02/18 PHP
Gird组件 Part-3:范例RSSFeed Viewer
2007/03/10 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
深入分析jquery解析json数据
2014/12/09 Javascript
jQuery div拖拽用法实例
2016/01/14 Javascript
javascript url几种编码方式详解
2016/06/06 Javascript
使用Bootstrap Tabs选项卡Ajax加载数据实现
2016/12/23 Javascript
用jQuery实现圆点图片轮播效果
2017/03/19 Javascript
iframe与主框架跨域相互访问实现方法
2017/09/14 Javascript
jQuery实现动态加载select下拉列表项功能示例
2018/05/31 jQuery
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
jQuery+css last-child实现选择最后一个子元素操作示例
2018/12/10 jQuery
实例分析Array.from(arr)与[...arr]到底有何不同
2019/04/09 Javascript
JavaScript this在函数中的指向及实例详解
2019/10/14 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
使用Vue+Django+Ant Design做一个留言评论模块的示例代码
2020/06/01 Javascript
详解Python函数作用域的LEGB顺序
2016/05/14 Python
python实现装饰器、描述符
2018/02/28 Python
Pandas 同元素多列去重的实例
2018/07/03 Python
python3使用pandas获取股票数据的方法
2018/12/22 Python
Python调用.NET库的方法步骤
2019/12/27 Python
python生成13位或16位时间戳以及反向解析时间戳的实例
2020/03/03 Python
Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)
2020/07/20 Python
VICHY薇姿美国官方网站:欧洲药房第一的抗衰老品牌
2017/11/22 全球购物
澳大利亚购买最佳炊具品牌网站:Cookware Brands
2019/02/16 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
Muziker英国:中欧最大的音乐家商店
2020/02/05 全球购物
理工科学生的自我评价
2013/12/15 职场文书
人力资源经理的岗位职责范本
2014/02/28 职场文书
小学家长意见怎么写
2015/06/03 职场文书
运动会1000米加油稿
2015/07/21 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书
Django框架中表单的用法
2022/06/10 Python