如何使用純CSS實現方塊跳躍的動畫(附源碼)

來源:互聯網
上載者:User
本篇文章給大家帶來的內容是關於如何使用純CSS實現方塊跳躍的動畫(附源碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。

效果預覽

原始碼下載

https://github.com/comehope/front-end-daily-challenges

代碼解讀

定義 dom,容器中包含 2 個子項目,分別代表 1 個女生和一群男生(4個),每個 span 元素代表 1 個人(1 個方塊):

<figure class="container">    <span class="girl"></span>    <p class="boys">        <span></span>        <span></span>        <span></span>        <span></span>    </p></figure>

置中顯示:

body {    margin: 0;    height: 100vh;    display: flex;    align-items: center;    justify-content: center;}

定義容器尺寸和它的子項目布局:

.container {    width: 8em;    height: 1em;    font-size: 35px;    display: flex;    justify-content: space-between;}

畫出 5 個方塊,用邊框作為輔助線協助定位:

.container span {    width: 1em;    height: 1em;    border: 1px dashed black; /* 輔助線 */}.boys {    width: 6em;    display: flex;    justify-content: space-between;}

用虛擬元素設定元素的樣式,使它們變得柔和一些,為男生和男生填上不同的顏色,同時刪掉上一步的輔助線:

.container span::before {        content: '';    position: absolute;    width: inherit;    height: inherit;    border-radius: 15%;    box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.3);}.girl::before {    background-color: hotpink;}.boys span::before {    background-color: dodgerblue;}

使 4 個男生色塊的顏色逐漸層淡,增加一點層次感:

.boys span:nth-child(1)::before {    filter: brightness(1);}.boys span:nth-child(2)::before {    filter: brightness(1.15);}.boys span:nth-child(3)::before {    filter: brightness(1.3);}.boys span:nth-child(4)::before {    filter: brightness(1.45);}

接下來製作動畫效果。

先增加女生移動的效果,同時顏色也做漸淡處理,後面其他動畫的時間要保持一致,所以把動畫時間長度設定為變數:

.container span {    width: 1em;    height: 1em;    --duration: 3s;}.girl {    animation: slide var(--duration) ease-in-out infinite;}@keyframes slide {    from {        transform: translateX(0);        filter: brightness(1);    }    to {        transform: translatex(calc(8em - (1em * 1.25)));        filter: brightness(1.45);    }}

然後增加第 1 個男生跳開的動畫效果,注意從 15% 到 35% 旋轉的原點是在元素的正上方:

.boys span {    animation: var(--duration) ease-in-out infinite;}.boys span:nth-child(1) {    animation-name: jump-off-1;}@keyframes jump-off-1 {    0%, 15% {        transform: rotate(0deg);    }    35%, 100% {        transform-origin: -50% center;        transform: rotate(-180deg);    }}

參考第 1 個男生的動畫效果,再增加另外 3 個男生跳開的動畫效果,區別只是調整了主要畫面格的時間,依次後延 15% 的時間:

.boys span:nth-child(2) {    animation-name: jump-off-2;}.boys span:nth-child(3) {    animation-name: jump-off-3;}.boys span:nth-child(4) {    animation-name: jump-off-4;}@keyframes jump-off-2 {    0%, 30% {        transform: rotate(0deg);    }    50%, 100% {        transform-origin: -50% center;        transform: rotate(-180deg);    }}@keyframes jump-off-3 {    0%, 45% {        transform: rotate(0deg);    }    65%, 100% {        transform-origin: -50% center;        transform: rotate(-180deg);    }}@keyframes jump-off-4 {    0%, 60% {        transform: rotate(0deg);    }    80%, 100% {        transform-origin: -50% center;        transform: rotate(-180deg);    }}

為第 1 個男生增加擬人的動畫效果,這個效果寫在 ::before 虛擬元素中,動畫的過程是從正常到壓扁、然後抻長、再壓扁、最後恢複正常,注意從 25% 到 40% 的壓扁變形,因為此時主要元素已經翻個兒,所以 transform-origin 的原點和 從 5% 到 15% 的壓扁變形的原點不一樣:

.boys span::before {    animation: var(--duration) ease-in-out infinite;}.boys span:nth-child(1)::before {    filter: brightness(1);    animation-name: jump-down-1;}@keyframes jump-down-1 {    5% {        transform: scale(1, 1);    }    15% {        transform-origin: center bottom;        transform: scale(1.3, 0.7);    }    20%, 25% {        transform-origin: center bottom;        transform: scale(0.8, 1.4);    }    40% {        transform-origin: center top;        transform: scale(1.3, 0.7);    }    55%, 100% {        transform: scale(1, 1);    }}

參考第 1 個男生 ::before 虛擬元素的動畫效果,再增加另外 3 個男生擬人的動畫效果,區別只是調整了主要畫面格的時間,依次後延 15% 的時間:

.boys span:nth-child(2)::before {    animation-name: jump-down-2;}.boys span:nth-child(3)::before {    animation-name: jump-down-3;}.boys span:nth-child(4)::before {    animation-name: jump-down-4;}@keyframes jump-down-2 {    20% {        transform: scale(1, 1);    }    30% {        transform-origin: center bottom;        transform: scale(1.3, 0.7);    }    35%, 40% {        transform-origin: center bottom;        transform: scale(0.8, 1.4);    }    55% {        transform-origin: center top;        transform: scale(1.3, 0.7);    }    70%, 100% {        transform: scale(1, 1);    }}@keyframes jump-down-3 {    35% {        transform: scale(1, 1);    }    45% {        transform-origin: center bottom;        transform: scale(1.3, 0.7);    }    50%, 55% {        transform-origin: center bottom;        transform: scale(0.8, 1.4);    }    70% {        transform-origin: center top;        transform: scale(1.3, 0.7);    }    85%, 100% {        transform: scale(1, 1);    }}@keyframes jump-down-4 {    50% {        transform: scale(1, 1);    }    60% {        transform-origin: center bottom;        transform: scale(1.3, 0.7);    }    65%, 70% {        transform-origin: center bottom;        transform: scale(0.8, 1.4);    }    85% {        transform-origin: center top;        transform: scale(1.3, 0.7);    }    100%, 100% {        transform: scale(1, 1);    }}

至此,女生從左側移動到右側的動畫效果已經完成。
把所有動畫屬性都加上 alternate 參數,使所有動畫都往複執行,就實現了從右側再回到左側的效果:

.girl {    animation: slide var(--duration) ease-in-out infinite alternate;}.boys span {    animation: var(--duration) ease-in-out infinite alternate;}.boys span::before {    animation: var(--duration) ease-in-out infinite alternate;}

大功告成!

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.