1. 程式人生 > >解析:用 CSS3 和 JavaScript 制作徑向動畫菜單

解析:用 CSS3 和 JavaScript 制作徑向動畫菜單

select webkit on() making 它的 text tran 表示 har

原作者的解析(英文):http://creative-punch.net/2014/02/making-animated-radial-menu-css3-javascript/

原作者的解析(譯文):http://developer.51cto.com/art/201404/437152.htm

本文非轉載,為個人原創解析,轉載請先聯系博主。謝謝~

首先,看看html的結構:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>kissy  |  TaoBaoUED</title>

    <link rel="stylesheet" href="style.css" type="text/css" media="all">
    <script src="jquery-1.3.2.js"></script>
    <script src="ext.js"></script>
</head>
<!-- Demo by http://creative-punch.net -->
<!-- Modified by xzh - 20140701 -->

<nav class="circular-menu">
  <div class="circle">
    <a href="">●</a>
    <a href="">■</a>
    <a href="">◆</a>
    <a href="">?</a>
    <a href="">★</a>
    <a href="">卍</a>
    <a href="">卐</a>
    <a href="">?</a>
  </div>
  <a href="#" class="menu-button fa fa-bars fa-2x">A</a>
</nav>

<h1 class="author">Demo by <a href="" target="">Creative Punch</h1></span></span>

——Css完整代碼請參見文章最後。

——Js完整代碼請參見文章最後。

然後,看下頁面:

技術分享

圖1-1

一開始,僅僅有兩個是“可見”的元素,一個的類是.menu-button,還有一個的類是.circular-menu,由於按鈕的position屬性要設置在absolute,所以它的父元素外框.menu-button設置position為relative,如今分析.menu-button的屬性:

1、 top和left的值為calc(50% - 30px),50%非常好理解,30px是怎麽來的呢?註意到,height和left都為40px,而絕對位置的top和left屬性分別表示元素左上角相對上方和左方的距離,如圖1-2。為了讓元素的中心點居中,距離應該減去元素的長寬的一半,可是它的長寬都是20px,為什麽是減30px呢?原因在於它的padding屬性為10px,相當於給它的長寬分別添加了20px。

得(30px = 40px/2 +10px)

技術分享

圖1-2

2、 line-height和height都為40px。使得文字可以垂直居中。

3、 border-radius:50%。圓形。

4、 display:block,刪掉好像沒什麽影響。

再看被“隱藏”了的.circle,它裏面裝了幾個<a>標簽,它的透明度為0,還設置了CSS3的動畫——transform和transition。當中,transition: all 0.4s ease-out為一打開網頁時看到幾個白點突然藏到大button背後的效果就是它幹的,解釋一下意思,全部屬性在0.4s內漸漸消失。事實上完整的它是有4個參數的。單擊button後,為div切換一個類.open。

.open.circle {
  opacity: 1;

  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
}
漸顯/漸隱。從0倍放大到1倍,變成圖1-3的樣子。

技術分享

圖1-3

如今。讓我們去看看js代碼,document載入之後為各個小<a>加入了top和left屬性。為了更加easy被看懂。我略微改動了一下原demo代碼,例如以下:

items[i].style.left = (50 - 35*Math.cos(2*Math.PI*i/len)).toFixed(4) + "%";
items[i].style.top = (50 + 35*Math.sin(2*Math.PI*i/len)).toFixed(4) + "%";
35後面的一塊意思是,從一個點開始。經歷2π。期間2π平分成多少個點取決於<a>的個數。比如我們樣例。<a>有8個,從x=0開始。正向取2π,將2π平分成8段。依次取8個點,他們的y值如圖1-4所看到的,我們能夠看到,8個點上的y值變化不正符合我們的圓圈位置變化規律麽?35的意思是,讓top和left最多取85%,最小取15%。

技術分享

圖1-4


舉一反三:

1、 上面說了。2π被分成幾段取決於<a>的個數。試著增刪幾個<a>看看吧。

2、 上面的代碼是從0開始正向取2π的,試著改一下吧。註意始終不變的東西是2π*i/len,你能夠作加減一些東西,或者為它加入負號之類的修改。特別地。加減一些東西的時候。如加上π/5,由於影響的是第一個點的取值。間接影響其它點的值,你會發現,全部<a>組成的圓圈好像被人順/逆時針輕輕擰了一下,詳細效果是如何的,你能夠嘗試弄出來看一下。


如今回過來看樣式,.circle a中須要註意的的是margin-left和margin-top。還記得我們剛剛說的.menu-button中的left和top屬性嗎?對,兩者都是幾乎相同的意思。讓我們回過來看圖1-3。圖中虛線框位置為我們沒有設置margin-left和margin-top時的位置,相同地。我們取margin-left和margin-top為<a>元素的長寬的一半。記得負號。


觸類旁通:

都說了跟前面的.menu-button幾乎相同。那我們就不設置margin-top和margin-left了。那怎麽改?

答:(字體顏色為白色。全選文字可見-->在js裏,items[i].style.left和items[i].style.top都減20px就可以<--)


忘了說。註意假設還有border的時候,相同須要減去border的值。

最後。謝謝你認真看完了,不足之處,歡迎指出!


完整js和css代碼例如以下:

$(document).ready(function(){
  // Demo by http://creative-punch.net
  // Modified by xzh - 20140701
  var items = document.querySelectorAll(‘.circle a‘);
  for(var i = 0, len = items.length; i < len; i++) {
    items[i].style.left = (50 - 35*Math.cos(2*Math.PI*i/len)).toFixed(4) + "%";
    items[i].style.top = (50 + 35*Math.sin(2*Math.PI*i/len)).toFixed(4) + "%";
    console.log(items[i].style.left+"  "+items[i].style.top);
  }
  
  document.querySelector(‘.menu-button‘).onclick = function(e) {
    e.preventDefault();
    document.querySelector(‘.circle‘).classList.toggle(‘open‘);
  }
});
/* Demo by http://creative-punch.net */
/* Modified by xzh - 20140701 */
body {
  background: #39D;
}

.circular-menu {
  width: 250px;
  height: 250px;
  margin: 0 auto;
  position: relative;
}

.circle {
  width: 250px;
  height: 250px;
  opacity: 0;
  
  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  transform: scale(0);

  -webkit-transition: all 0.4s ease-out;
  -moz-transition: all 0.4s ease-out;
  transition: all 0.4s ease-out;
}

.open.circle {
  opacity: 1;

  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
}

.circle a {
  text-decoration: none;
  color: white;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  position: absolute;
  text-align: center;
}

.circle a:hover {
  color: #eef;
}

.menu-button {
  position: absolute;
  top: calc(50% - 30px);
  left: calc(50% - 30px);
  text-decoration: none;
  text-align: center;
  color: #444;
  border-radius: 50%;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  padding: 10px;
  background: #dde;
}

.menu-button:hover {
  background-color: #eef;
}

/* Author stuff */
h1.author {
  text-align:center;
  color: white;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: 300;
}

h1.author a {
  color: #348;
  text-decoration:none;
}

h1.author a:hover {
  color: #ddd;
} 

解析:用 CSS3 和 JavaScript 制作徑向動畫菜單