基于vue實(shí)現(xiàn)圓形菜單欄組件

整個(gè)樣式都是基于css3 得transform而實(shí)現(xiàn)得。
每個(gè)扇形角度為360/12=30deg,當(dāng)然,你不想做圓形也可以,公式就是 扇形角度=你想繪制得角度/扇形個(gè)數(shù)
當(dāng)你計(jì)算好每個(gè)扇形得角度時(shí),需要將li元素傾斜,傾斜角度=90-扇形面積,我的這個(gè)傾斜角度就是90-30=60deg,然后使用css3 得skew()


circle-panel-3
當(dāng)每個(gè)扇形傾斜60deg之后,會(huì)在原來得位置上,要想每個(gè)扇形有規(guī)律得組合在一起,那么就要旋轉(zhuǎn)相應(yīng)得角度,30deg,60deg,90deg…….這個(gè)以扇形得圓心角遞加。
這是基礎(chǔ)組件得完整代碼,父組件只需導(dǎo)入使用傳給子組件數(shù)據(jù)就可以了,當(dāng)點(diǎn)擊每個(gè)扇形得事件也在父組件監(jiān)聽實(shí)現(xiàn)相應(yīng)的邏輯。script部分我加了js代碼和ts代碼,沒有用過ts得小伙伴就忽略直接參考js代碼就可以了。并且我調(diào)用了手勢(shì)庫(kù)hammer.js,這個(gè)庫(kù)很全,大家感興趣得可以去查一下使用方法,這樣這個(gè)圓環(huán)是可以旋轉(zhuǎn)得。
<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>
父組件調(diào)用:
<div class="making-panel">
<CirclePanel :title="title" :panel="panel"
@clickTab="clickTabCircle"
@clickPanel="clickPanel" ></CirclePanel>
</div>
總結(jié)
以上所述是小編給大家介紹的基于vue實(shí)現(xiàn)圓形菜單欄組件,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
vuejs如何清空表單數(shù)據(jù)、刪除對(duì)象中的空屬性公共方法
這篇文章主要介紹了vuejs如何清空表單數(shù)據(jù)、刪除對(duì)象中的空屬性公共方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
Vue開發(fā)中出現(xiàn)Loading?Chunk?Failed的問題解決
本文主要介紹了Vue開發(fā)中出現(xiàn)Loading?Chunk?Failed的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03
vue項(xiàng)目中輪詢狀態(tài)更改方式(鉤子函數(shù))
這篇文章主要介紹了vue項(xiàng)目中輪詢狀態(tài)更改方式(鉤子函數(shù)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue3項(xiàng)目中的el-carousel 輪播圖的使用
Carousel(走馬燈)是一種常見的前端組件,通常用于展示多個(gè)項(xiàng)目(通常是圖片或內(nèi)容塊)的輪播效果,這篇文章主要介紹了vue3項(xiàng)目中的el-carousel 輪播圖的使用,需要的朋友可以參考下2024-02-02
vue項(xiàng)目中自動(dòng)導(dǎo)入svg并愉快的使用方式
這篇文章主要介紹了vue項(xiàng)目中自動(dòng)導(dǎo)入svg并愉快的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
Element?Plus?去掉表格外邊框的實(shí)現(xiàn)代碼
使用el-table組件拖拽時(shí),?想使用自定義樣式進(jìn)行拖拽,?想去掉外邊框,?并在表頭加入豎杠樣式,本文給大家介紹Element?Plus?去掉表格外邊框的實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2025-04-04
使用Vue后如何針對(duì)搜索引擎做SEO優(yōu)化
本文介紹了Vue.js在SEO優(yōu)化方面的挑戰(zhàn),并提供了一些方法來解決這些問題,包括使用服務(wù)器端渲染、預(yù)渲染和使用VueRouter的History模式來生成靜態(tài)HTML頁(yè)面,以及添加meta信息和內(nèi)部鏈接來提高搜索引擎的索引和排名2025-02-02

