解析:用 CSS3 和 JavaScript 制作徑向動畫菜單
原作者的解析(英文):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 制作徑向動畫菜單