今天來學習 利用css 製作的偽過場動畫
文章 : Rounded Animated Navigation
範例: demo
先來看完整的html布局
<body>
<header>
<a class="cd-logo" href="#0"><img src="img/cd-logo.svg" alt="Logo"></a>
</header>
<nav>
<ul class="cd-primary-nav">
<li><a href="#0">The team</a></li>
<li><a href="#0">Our services</a></li>
<li><a href="#0">Our projects</a></li>
<li><a href="#0">Start a project</a></li>
<li><a href="#0">Join In</a></li>
<li><a href="#0">Create an account</a></li>
</ul>
</nav>
<main class="cd-content">
<!-- your content here -->
<div class="cd-intro">
<h1>Rounded Animated Navigation</h1>
</div>
<p>
Lorem ipsum dolor sit amet....
</p>
</main> <!-- cd-content -->
<div class="cd-overlay-nav">
<span></span>
</div> <!-- cd-overlay-nav -->
<div class="cd-overlay-content">
<span></span>
</div> <!-- cd-overlay-content -->
<a href="#0" class="cd-nav-trigger">Menu<span class="cd-icon"></span></a>
</body>
整體的動畫過程為 :
點擊按鈕 -> icon 執行變化動畫 -> span fill full screen -> 顯示span 背景 -> span縮小 -> 顯示另外一個版面
首先來了解下 當點擊時 icon的動畫如何製作
<a href="#0" class="cd-nav-trigger">Menu<span class="cd-icon"></span></a>
首先先給按鈕一個基本的樣式
.cd-nav-trigger {
top: 18px;
right: 5%;
height: 44px;
width: 44px;
z-index: 5;
/* image replacement */
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
}
在圖片中,按下鈕後 背景顏色也同時切換並且有短暫的scale的切換動畫,這個功能則是在
.cd-nav-trigger 中前後添加了 before 跟 after 偽元素,當按下時則切換這兩個虛偽元素來實現的功能,舉個例子 :
當 class 為 cd-nav-trigger 時 則顯示before偽元素(scale:1),而after 偽元素則隱藏(scale:0)
當 class 為 .cd-nav-trigger.close-nav 時 則隱藏before偽元素(scale:0),而after 偽元素則顯示(scale:1)
.cd-nav-trigger::before, .cd-nav-trigger::after {
/* 2 rounded colored backgrounds for the menu icon */
position: absolute;
top: 0;
left: 0;
border-radius: 50%;
height: 100%;
width: 100%;
transition-property: transform;
}
/*預設為.cd-nav-trigger::before 先顯示*/
.cd-nav-trigger::before {
background-color: #091d23;
transform: scale(1);
transition-duration: 0.3s;
transition-delay: 0.4s;
}
.cd-nav-trigger::after {
background-color: #ffb441;
transform: scale(0);
transition-duration: 0s;
transition-delay: 0s;
}
.cd-nav-trigger.close-nav::before {
/* user clicks on the .cd-nav-trigger element - 1st rounded background disappears */
transform: scale(0);
}
.cd-nav-trigger.close-nav::after {
/* user clicks on the .cd-nav-trigger element - 2nd rounded background appears */
transform: scale(1);
transition-duration: 0.3s;
transition-delay: 0.4s;
}
解決了顏色變換的動畫,輪到了icon的圖標動畫, ≡ 變成 x
而這個icon其實也是利用偽元素來做的
首先給icon基本設置
.cd-nav-trigger .cd-icon {
/* icon created in CSS */
position: absolute;
left: 50%;
top: 50%;
bottom: auto;
right: auto;
transform: translateX(-50%) translateY(-50%);
display: inline-block;
width: 18px;
height: 3px;
background-color: #ffffff;
z-index: 10;
}
.cd-nav-trigger .cd-icon::before, .cd-nav-trigger .cd-icon:after {
/* upper and lower lines of the menu icon */
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: inherit;
transition: transform .3s;
}
.cd-nav-trigger.close-nav .cd-icon::before, .cd-nav-trigger.close-nav .cd-icon::after {
background-color: white;
}
≡ 的icon十分簡單, 中間的一槓為元素span自己本身,而上下 則各為 before 跟 after形成
.cd-nav-trigger .cd-icon::before {
transform: translateY(-6px) rotate(0deg);
}
.cd-nav-trigger .cd-icon::after {
transform: translateY(6px) rotate(0deg);
}
.cd-nav-trigger.close-nav .cd-icon {
/* user clicks on the .cd-nav-trigger element - transform the icon */
background-color: rgba(255, 255, 255, 0);
}
而 x icon 則是after 跟 before 元素 rotate 45度後相交差 就形成了 x
.cd-nav-trigger.close-nav .cd-icon::before {
transform: translateY(0) rotate(45deg);
}
.cd-nav-trigger.close-nav .cd-icon::after {
transform: translateY(0) rotate(-45deg);
}
可能有人會注意到,為什麼要給 元素設定 roate (0) 呢? 這是因為在兩個另外一個icon設定了roate(45) 如此一來就能夠形成 0 -> 45 度的動畫 ,而中間那一槓 則從 原本的白色 變成透明色從而達到消失
那麼完整的代碼就是 :
.cd-nav-trigger .cd-icon {
/* icon created in CSS */
position: absolute;
left: 50%;
top: 50%;
bottom: auto;
right: auto;
transform: translateX(-50%) translateY(-50%);
display: inline-block;
width: 18px;
height: 3px;
background-color: #ffffff;
z-index: 10;
}
.cd-nav-trigger .cd-icon::before, .cd-nav-trigger .cd-icon:after {
/* upper and lower lines of the menu icon */
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: inherit;
transition: transform .3s;
}
.cd-nav-trigger .cd-icon::before {
transform: translateY(-6px) rotate(0deg);
}
.cd-nav-trigger .cd-icon::after {
transform: translateY(6px) rotate(0deg);
}
.cd-nav-trigger.close-nav .cd-icon {
/* user clicks on the .cd-nav-trigger element - transform the icon */
background-color: rgba(255, 255, 255, 0);
}
.cd-nav-trigger.close-nav .cd-icon::before, .cd-nav-trigger.close-nav .cd-icon::after {
background-color: white;
}
.cd-nav-trigger.close-nav .cd-icon::before {
transform: translateY(0) rotate(45deg);
}
.cd-nav-trigger.close-nav .cd-icon::after {
transform: translateY(0) rotate(-45deg);
}
在進入接下來圓形的過場動畫之前,先解說如何切換兩個畫面
藉由nav中ul 的 visibility: visible; 和opacity: 1; 的 屬性,來達到切換效果,注意 main是不需要做任何隱藏顯示的動作,只將 ul的層級(z-index)設為最高即可
<nav>
<ul class="cd-primary-nav">
<li><a href="#0">The team</a></li>
<li><a href="#0">Our services</a></li>
<li><a href="#0">Our projects</a></li>
<li><a href="#0">Start a project</a></li>
<li><a href="#0">Join In</a></li>
<li><a href="#0">Create an account</a></li>
</ul>
</nav>
<main class="cd-content">
<!-- your content here -->
</main>
.cd-primary-nav {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
padding: 80px 5%;
z-index: 3;
background-color: #091d23;
overflow: auto;
-webkit-overflow-scrolling: touch;
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 0s,opacity .3s;
-moz-transition: visibility 0s,opacity .3s;
transition: visibility 0s,opacity .3s;
}
cd-primary-nav.fade-in {
visibility: visible;
opacity: 1;
}
解釋完如何切換兩個畫面之後,最後則是圓圈的動畫
cd-overlay-nav和cd-overlay-content則為 兩個圓圈(span)動畫的容器
實際放大的動畫效果由span來完成
<div class="cd-overlay-nav">
<span></span>
</div> <!-- cd-overlay-nav -->
<div class="cd-overlay-content">
<span></span>
</div>
圓圈的動畫其實是藉由span 的scale 從 0 -> 1 -> 0 這樣的過程動畫實現。
最開始有點疑惑的是這兩個盒子存在的真正用途,其實這兩個盒子影藏在按鈕的後面,
並以這個位置放大,來製造是點擊按鈕後按鈕放大的錯覺,實際是span放大,而盒子則提供span放大定位的位置
.cd-overlay-nav, .cd-overlay-content {
/* containers of the 2 main rounded backgrounds - these containers are used to position the rounded bgs behind the menu icon */
position: fixed;
top: 18px;
right: 5%;
height: 4px;
width: 4px;
transform: translateX(-20px) translateY(20px);
}
.cd-overlay-nav span, .cd-overlay-content span {
display: inline-block;
position: absolute;
border-radius: 50%;
will-change: transform;
transform: scale(0);
}
最後 動畫的順序為 span scale 動畫 -> 切換顏色 -> 顯示內容 ,文章中作者是使用 Velocity.js 插件來完成的,過幾天 我來使用gsap來實現看看,完成後再補上demo
以上!!