您的位置:首页 > Web前端 > CSS

纯css使用transform实现同心圆导航栏菜单

2017-01-07 10:32 351 查看
最近遇到客户来了一个我没遇到过的需求。那就是制作一个同心圆菜单栏。因为公司没有其他人指导我,所以我自己在网上搜索了很久,最后是根据(http://www.w3cplus.com/css3/building-a-circular-navigation-with-css-transforms.html)这个链接上的教程逐步实现了。是使用纯css3的transform来实现的,没有用过什么插件。之前对transform属性接触的比较少,所以刚开始做的时候有点吃力,当你理解后你就会知道transform是有多么的强大,当然做的时候遇到一个bug我怎么也解决不了,下面我会提出来的,希望哪位大神能够解决的告知一声;

制作的步骤:

 1.我们需要将导航项绝对定位在容器里面

 2.将每一项的变换原点设置成他们的右下角

 3.然后往左上角平移导航项,让它们的变换原点和容器中心相吻合

 4.然后按照公式顺时针旋转每一项到指定的位置:对于第i项,需要旋转:i*x,其中x是圆心角的值。

 5.然后让它们变形以获取我们想要的圆心角(使用上面提到过的公式)。

 6.反向倾斜a标签,意味着按列表项需要按相反的值倾斜, 然后用- [90 – (x/2) ]的值反向 旋转,x是圆心角的值。那么对于40度的圆心角,我们需要倾斜a标签-40度并且按-[ 90 – (40/2) ] = -70 度旋转。

a标签被绝对定位在它们的父级中,而且列表项的overflow被设置为hidden,这意味着a标签的一部分被裁切,所以为了确保a标签中的文字/图标出现在可见部分,我们将内容居中对齐。

使用到的数学知识:

 旋转导航项到指定位置:角度y = i * x (i是第几项,x是圆心角的值)

 按照90-x倾斜(x是圆心角的值)

 如果要相对称反方向旋转导航项(这一步实际上和前一步合并)

 “反向倾斜”“反向旋转”导航中的a标签(设置text-align为center)

其他不说了,贴上我的代码;

html源码:

<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0" name="viewport" />
<title></title>
<link rel="stylesheet" href="css/shouye.css">
</head>
<body>

<header id="header">
<ul>
<li><a href="">我的朋友圈</a></li>
<li><a href="">消息提醒<em>3</em></a></li>
<li><a href="">佩戴天数<em>6</em></a></li>
</ul>
</header>

<div class="logo">
<img src="img/logo.png" alt="">
</div>

<div class="wrap">

<!-- 制作圆的外层导航 -->
<div class="csstransforms">
<div class="cn-wrapper" id="cn-wrapper">
<ul>
<li><a href="#"><span>血氧</span></a></li>
<li><a href="#"><span>心率</span></a></li>
<li><a href="#"><span>呼吸</span></a></li>
<li><a href="#"><span>体温</span></a></li>
<li><a href="#"><span>体重</span></a></li>
<li><a href="#"><span>身高</span></a></li>
<li><a href="#"><span>血压</span></a></li>
<li><a href="#"><span>BMI</span></a></li>
</ul>
</div>
</div>

<!-- 制作圆的第二层导航 -->
<div class="csstransforms2">
<div class="cn-wrapper2" id="cn-wrapper2">
<ul>
<li><a href="#"><span>睡眠</span></a></li>
<li><a href="#"><span>运动</span></a></li>
<li><a href="#"><span>饮食</span></a></li>
<li><a href="#"><span>情绪</span></a></li>

</ul>
</div>
</div>

<!-- 制作圆的最内层的logo -->
<div class="lat">
<div class="img">
<img src="img/yuan.png" alt="">
</div>

</div>
</div>
<!-- 遮罩层 -->
<div id="cn-overlay" class="cn-overlay"></div>

<footer id="footer">
<ul>
<li><a href="">Life Watch</a></li>
<li><a href="">天使服务</a></li>
<li><a href="">SOS</a></li>
<li><a href="">健康数据</a></li>
<li><a href="">个人中心</a></li>
</ul>
</footer>

</body>
</html>


b6a1

css源码:

@charset 'ute-8';

*{
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
body {
overflow-x: hidden;
overflow-y: hidden;/* 禁止滚动条 */
}
/* header */
#header{
width: 100%;
height: 50px;
background-color: #3cb649;
position: fixed;
top:0;
z-index: 9999;
}

#header li {
width: 33.3%;
height: 50px;
line-height: 50px;
float: left;
text-align:center;
}
#header li:nth-child(3){
text-indent: 20px;
}
#header li a {
display:  block;
color: #FFF;
}
#header li em {
font-style: normal;
position: relative;
top: -4px;
left: 2px;
}
/* end header */

/* logo */
.logo {
width: 100%;
height: 40px;
position: fixed;
top: 50px;
background-color: #fff;

}
.logo img {
display: block;
width: 60%;
position: relative;
left: 18%;
}
/* end logo */

.csstransforms .cn-wrapper li, .csstransforms2 .cn-wrapper2 li {
position: absolute;
transform-origin: 100% 100%;/* 变形原点,bottom right | right bottom 等价于 100% 100% ,每一项的变换原点设置成他们的右下角*/
overflow: hidden;
left: 40%;
top:150px;

}

.csstransforms .cn-wrapper li a, .csstransforms2 .cn-wrapper2 li a {
box-sizing: border-box;/* 为了设置内边距让字体居中一点的时候不会让圆变形 */
display: block;
position: absolute;
border-radius: 50%;
text-decoration: none;
color: #fff;
text-align: center;/* 为了确保a标签中的文字/图标出现在可见部分,将内容居中对齐 */
transition: opacity 0.3s, color 0.3s;
}
.csstransforms .cn-wrapper li {
font-size: 1.2em;
width: 10em;
height: 10em;
margin-top: -1.3em;
margin-left: -8em;
}

.csstransforms .cn-wrapper li a {
font-size: 1.18em;
height: 13em;
width: 13em;
bottom: -6.5em;
right: -6.5em;
transform: skew(-45deg) rotate(-68.5deg) scale(1);/* 反向倾斜a标签,意味着按列表项需要按相反的值倾斜, 然后用- [90 – (x/2) ]的值反向 旋转,x是圆心角的值。那么对于45度的圆心角,我们需要倾斜a标签-40度并且按-[ 90 – (40/2) ] = -68.5 度旋转 */
padding-top: 10px;
}

.csstransforms2 .cn-wrapper2 li {
font-size: 1.3em;
width: 6.5em;
height: 6.5em;
margin-top: 1.6em;
margin-left: -4.7em;
transition: border .3s ease;
}

.csstransforms2 .cn-wrapper2 li a {
font-size: 1.18em;
height: 8em;
width: 8em;
bottom: -4em;
right: -4em;
transform: rotate(-45deg) scale(1);
padding-top: 15px;
}

/* 外圈旋转与倾斜 */
.csstransforms .cn-wrapper li:first-child {
transform: skew(45deg);/* 90deg-xdeg,  x是你想得到的圆心角的值。*/
}

.csstransforms .cn-wrapper li:nth-child(2) {
transform: rotate(45deg) skew(45deg);
}

.csstransforms .cn-wrapper li:nth-child(3) {
transform: rotate(90deg) skew(45deg)
}

.csstransforms .cn-wrapper li:nth-child(4) {
transform: rotate(135deg) skew(45deg);
}

.csstransforms .cn-wrapper li:nth-child(5) {
transform: rotate(180deg) skew(45deg);
}

.csstransforms .cn-wrapper li:nth-child(6) {
transform: rotate(225deg) skew(45deg);
}

.csstransforms .cn-wrapper li:nth-child(7) {
transform: rotate(270deg) skew(45deg);
}

.csstransforms .cn-wrapper li:nth-child(8) {
transform: rotate(315deg) skew(45deg);
}

/* 修改外圈背景颜色 */
.csstransforms .cn-wrapper li:nth-child(1) a {
background-color: #70a4cc;/* 血氧 */
}

.csstransforms .cn-wrapper li:nth-child(2) a {
background-color: #0a71bc;/* 心率 */
}
.csstransforms .cn-wrapper li:nth-child(3) a {
background-color: #70a4cc;/* 呼吸 */
}
.csstransforms .cn-wrapper li:nth-child(4) a {
background-color: #0a71bc;/* 体温 */
}
.csstransforms .cn-wrapper li:nth-child(5) a {
background-color: #70a4cc;/* 体重 */
}
.csstransforms .cn-wrapper li:nth-child(6) a {
background-color: #0a71bc;/* 身高 */
}
.csstransforms .cn-wrapper li:nth-child(7) a {
background-color: #70a4cc;/* 血压 */
}
.csstransforms .cn-wrapper li:nth-child(8) a {
background-color: #0a71bc;/* BMI */
}

/* 内圈旋转与倾斜 */
.csstransforms2 .cn-wrapper2 li:first-child {

}

.csstransforms2 .cn-wrapper2 li:nth-child(2) {
transform: rotate(90deg);
}

.csstransforms2 .cn-wrapper2 li:nth-child(3) {
transform: rotate(180deg);
}

.csstransforms2 .cn-wrapper2 li:nth-child(4) {
transform: rotate(270deg);
}

/*  修改内圈背景颜色 */
.csstransforms2 .cn-wrapper2 li:nth-child(1) a {
background-color: #70a4cc;/* 睡眠 */
}

.csstransforms2 .cn-wrapper2 li:nth-child(2) a {
background-color: #0a71bc;/* 运动 */
}
.csstransforms2 .cn-wrapper2 li:nth-child(3) a {
background-color: #70a4cc;/* 饮食 */
}
.csstransforms2 .cn-wrapper2 li:nth-child(4) a {
background-color: #0a71bc;/* 情绪 */
}

/* 最里层 */
.lat {
height: 5em;
width: 5em;
position: absolute;
left: 41%;
top: 285px;
margin-top: -8px;
margin-left: -6px;
background-color: #0a71bc;
border-radius: 50%;

}
.lat .img {
height: 3em;
width: 3em;
margin: 4px 0 0 15px;
}
.lat img {
display: block;
width: 100%;
}

/*  @media screen and (max-width:480px){

} */

@media screen and (max-width:320px){
.csstransforms .cn-wrapper li, .csstransforms2 .cn-wrapper2 li {
left: 38%;
top:100px;
}

.csstransforms .cn-wrapper li a {
font-size: 1em;
height: 12em;
width: 12em;
bottom: -6em;
right: -6em;
}

.csstransforms2 .cn-wrapper2 li a {
font-size: 1em;
height: 7em;
width: 7em;
bottom: -3.5em;
right: -3.5em;
padding-top: 10px;/* 为了设置内边距的时候不会让圆变形 */
}
.lat {
height: 4em;
width: 4em;
left: 34%;
top: 243px;
margin-top: -8px;
margin-left: 18px;

}
.lat .img {
height: 2em;
width: 2em;
margin: 8px 0 0 15px;
}
.lat img {
display: block;
width: 100%;
}
}

.cn-overlay{
width:100%
height:100%;
background-color: #eeedf3;
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
transition: all .3s ease;
z-index:-2;
pointer-events:auto;
opacity:0.8;
}

#footer {
width: 100%;
height: 40px;
position: fixed;
bottom: 0;
background-color: #e7e7e7;
}
#footer li {
height: 40px;
line-height: 40px;
float: left;
text-align: center;
}
#footer li:first-child{
width: 26%;
box-sizing: border-box;
border-right: 1px solid #0e7a9e;
}
#footer li:nth-child(2){
width: 20%;
}
#footer li:nth-child(3){
width: 14%;
height: 50px;
border-radius: 50%;
background-color: #3cb649;
position: relative;
top: -20px;
}
#footer li:nth-child(4){
width: 20%;
box-sizing: border-box;
border-right: 1px solid #0e7a9e;
}
#footer li:nth-child(5){
width: 20%;

}
#footer li a {
color: #333;
font-size: 14px;
}
#footer li:nth-child(3) a{
font-size: 20px;
color: #daede9;
}


最后提一下自己遇到的一个问题,就是我设置了li隐藏,因为它是绝对定位的,脱离了文档流,所以我想去除掉他的溢出,但是我没有实现到,可以用边框就能检验到,所以他依旧占着空间造成滚动条的出现,我是这样来解决的:

body {
overflow-x: hidden;
overflow-y: hidden;/* 禁止滚动条 */
}


希望哪位牛人能有解决方法告诉我一声。如下图:



最后附上自己最终实现客户需要的效果:




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: