彈簧動效是IOS系統原生自帶的一個效果,如在iPhone上面的照片點開大圖的展現效果就是一個彈簧動畫,以下圖所示:javascript
它有一個彈閃的過程,一大一小交替縮放就像一個彈簧在彈動同樣,而不是以往那種簡單的線性變大。css
若是使用CSS的animation-timing-function只是改變運動的速度,不能改變運動的方向。html
而本身手動寫CSS模擬這種先變大再變小的效果:前端
@keyframes spring-show {
0% {
transform: scale(0);
}
90% {
transform: scale(1);
}
/* 先放大一點 */
95% {
transform: scale(1.1);
}
/* 而後再縮回去 */
100% {
transform: scale(1);
}
}複製代碼
是沒有這種彈性動感的。vue
由於要實現一個彈簧振動效果,須要有兩個參數,一個是阻尼係數damping ration,另外一個是剛度stiffness,阻尼係數決定了衰減的快慢,剛度決定了往返的週期長短。給定這兩個參數和彈簧的始末位移,根據一些物理公式能夠推導出任意時刻彈簧的位移,這個位移就能夠看成上面的scale縮放的值,或者是translate、rotate等的值。java
那怎麼算呢?大漠在《CSS如何實現彈簧動畫效果》也詳細地討論了這種效果,並寫一個SASS函數實現,不過這種方式生成的CSS廣泛比較大,因此我改用了JS實現,原理都是計算一個CSS的keyframes關鍵幀動畫的在1%, 2%, 3%, ..., 100%的時候屬性值應該是多少,而後再動態地插入一個style標籤。這裏借用了一個css spring的庫,這個庫gzip後只有3KB,使用方法以下:git
import spring, { toString } from 'css-spring';
const keyframes = spring(
{ scale: 0 }, // from
{ scale: 1 }, // to
// precision表示精度有2位
{ damping: 14, stiffness: 170, precision: 2}
);
const keyframeString = toString(keyframes);
console.log(keyframeString);複製代碼
生成的CSS以下圖所示:github
它會有一個大小的變化過程:0 -> 1 -> 1.1 -> 0.99 -> 1,把這些值畫成一個圖表看起來更加直觀:web
能夠看到它有一個抖動且週期衰減的過程,實際的效果以下圖所示:spring
除了放大,縮小也能這樣處理,還能夠應用於旋轉,效果以下圖所示:
這個是用下面的代碼生成的:
const keyframes = spring(
{ rotateZ: 30 }, // from
{ rotateZ: 0 }, // to
{ damping: 14, stiffness: 170, precision: 3}
);複製代碼
當咱們須要藉助animation-delay讓3個星星逐個出現的時候,須要先visibility: hidden隱藏而後再出現,這個時候須要在keyframes裏面添加visibility屬性,以下代碼所示:
let from = {rotateZ: '30', visibility: 'hidden' },
to = {rotateZ: '0', visibility: 'visible' };
if (from.visibility) {
keyframes['0%'].visibility = from.visibility;
keyframes['1%'].visibility = to.visibility;
// 最後結束animate-fill-mode: forwards使用
keyframes['100%'].visibility = to.visibility;
}複製代碼
最後生成一個keyframes:
@keyframes spring-rotate {
0% {transform:rotateZ(29.1deg);visibility:hidden;}
1% {transform:rotateZ(27.507deg);visibility:visible;}
/* ... */
100% {transform:rotateZ(0deg);visibility:visible;}
}複製代碼
再讓每一個star星星的animation-delay依次增大:
.star {
visibility: hidden;
animation: spring-rotate .59s linear forwards;
}
.star:nth-of-type(2) {
animation-delay: .15s;
}
.star:nth-of-type(3) {
animation-delay: .3s;
}複製代碼
這樣就能實現逐個出現的效果了,以下圖所示:
這種彈簧動效可以加強動感,比普通的單向效果看起來更帶感。
在實際的實現中我寫了一個util,當頁面初始化的時候就生成keyframes,而後插入一個style標籤放在head裏面。由於若是再加上webkit前綴,一個keyframes有4KB,10個就有40KB,直接用JS動態計算的方式,會更省空間,靈活性也更強一點。
【人人網招聘中高級前端】
1. 項目背景: 咱們在作一個企業級海外的SAAS CRM(客戶管理系統)產品, 前端的技術挑戰很大, 好比在咱們的網站讓客戶直接打網絡電話(直接打手機那種), 發email, 自動根據用戶場景處理業務等。
2. 技術棧背景: 也是採用比較流行的vue, vuex等框架, 通信是WebRTC, 消息分發系統用Google的FCM和蘋果的APN。服務部署在亞馬遜或谷歌雲上。服務全球客戶。
3. 另外由於產品是一個企業級用戶產品因此個方面要求比較高(好比性能,安全,多任務處理等)。因此對候選人技術要求比較高,若是您對技術特別在乎,那麼咱們的空缺提供了很好的才能發揮空間和鍛鍊成長的機會。
【其它文章】實現WebRTC P2P鏈接