less做个径向菜单

在慕课网发现了一个有意思的课程,叫 数学知识在CSS动画中的应用 。用到的数学知识是如何计算圆上每个点的坐标。统一名称,中间的菜单叫触发菜单,四周发散的菜单叫子菜单,

径向菜单效果
效果预览

慕课网通过jquery计算子菜单的坐标,控制相应的css属性,来实现这一功能。
有关计算,又有关css属性,那么css预处理器便是一个不错的选择。

less与scss

scss基于ruby,使用在服务器端。less基于node,可以直接在浏览器端使用,但会消耗更多的性能。所以两者一般都会在前期使用工具编译为css。scss不支持三角函数,less却能够很好的支持三角函数,less便成了一个不错的选择。

先把大致布局放在这里。

<div class="container">
    <a class="btn"></a>
    <input type="checkbox" class="toggle">
    <div class="circle">1</div>
    <div class="circle">2</div>
    <div class="circle">3</div>
    <div class="circle">4</div>
    <div class="circle">5</div>
    <div class="circle">6</div>
    <div class="circle">7</div>
    <div class="circle">8</div>
    <div class="circle">9</div>
    <div class="circle">10</div>
    <div class="circle">11</div>
    <div class="circle">12</div>
</div>

绝对定位居中

把径向菜单置于窗口中间,可以使用绝对定位,然后使它居中。写一个MIXIN

.center() {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

画一个圆

以下mixin表示一个以@radius为半径,@color为背景的一个圆。圆是一个圆角半径为50%的正方形。box-sizing: border-box使得可以给圆添加边框长度而不至于使圆变形。

.radius(@radius, @color: transparent) {
    width: @radius * 2;
    height: @radius * 2;
    border-radius: 50%;
    background-color: @color;
    box-sizing: border-box;
}

设置径向菜单大小及初始位置

.container表示子菜单所在的圆,.circle为子菜单,初始化时无大小,text-alignline-height控制字体居中。

.container {
    .center();
    .radius(@distance);
    border: 1px dotted #aaa;
}

.circle {
    .radius(0);
    .center();
    font-size: 0;
    opacity: 0;
    transition: all 800ms ease;
    line-height: @circle-radius * 2;
    text-align: center;
    color: #ffc;
    cursor: pointer;
}

触发菜单

点击触发菜单会使子菜单发散。checkbox通过:checked伪类选择器可以模拟点击触发的效果,使它的透明度改为0,再增加一个装饰的.btn设置背景,使它看起来像一个按钮。

.btn, 
.toggle {
    .radius(@toggle-radius, rgb(0, 51, 51));
    .center();
}

.toggle {
    opacity: 0;
    cursor: pointer;
    &:checked {
        .generate-circle();
    }
}

子菜单的发散

点击触发菜单会使子菜单发散开来。此时子菜单的选择器应该使用~选择器。计算其位置设置translate的平移属性,并设置动画。
less使用循环生成每个子菜单的位置,count是子菜单的数量。不得不说,还是scss的for循环好用太多。

注意其下用的是nth-of-type

.generate-circle(@i: 1) when (@i < @count + 1) {
    & ~ .circle:nth-of-type(@{i}) {
        .radius(@circle-radius, @color);
        @top: round(sin(pi() * 2 * (@i - 1)/ @count) * @distance) - @circle-radius;
        @left: round(cos(pi() * 2 * (@i - 1)/ @count) * @distance) - @circle-radius;
        transform: translate(@top, @left);
        opacity: 1;
        font-size: 1em;
        transition: all 800ms ease;
        &:hover {
            background-color: #033;
        }
    }
    .generate-circle(@i + 1);
}

源码

使用less做的径向菜单
效果预览

参考

less语言特性
再谈 CSS 预处理器
数学知识在CSS动画中的应用

posted @ 2015-12-15 21:52  山月水风  阅读(1272)  评论(1编辑  收藏  举报