iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
自我挑戰組

Do you wanna play? CSS game ぎりぎり系列 第 20

[Day 20] Elastic: 彈跳球今天彈性放假

  • 分享至 

  • xImage
  •  

人與人之間都是具有彈性的,好人就會被凹一下(='X'=),同事:「诶你用完囉,今天進度幫我一下好不好~」
今天我們來實作Day #18

Elastic

CodePen: https://codepen.io/stevetanus/pen/QWraKpp


1. HTML

<div class="frame">
  <div class="top"></div>
  <div class="ball"></div>
  <div class="bottom"></div>
  <div class="ellipse">
    <div class="grey"></div>
    <div class="green"></div>
  </div>
</div>

.top是上面的灰色背景,.bottom是下面的綠色背景,.ball是我自己加上去的球,打算隨著介面的彈性彈上去,.ellipse內有兩個橢圓,分別是.grey.green


2. SCSS(CSS)

變數

$green: #37d493;
$grey: #444;
$speed: 5s; // 動畫時間
$e-width: 420px; // 橢圓的寬
$e-w-offset: -10px; // 寬度的抵銷,使寬420px的橢圓置中
$e-height: 400px; // 橢圓的高

.top & .bottom(上下長方形背景)

.top {
  position: absolute;
  width: 100%;
  height: 200px; // 下半 
  top: 0;
  left: 0;
  background: $grey;
}

.bottom {
  @extend .top;
  top: 50%; // 下半
  background: $green;
}

.ellipse(橢圓)

.ellipse {
  position: absolute;
  z-index: 2;
  width: $e-width; // 420px
  height: $e-height; // 400px
  top: 0;
  left: $e-w-offset; // -10px
  transform-style: preserve-3d; // tfs為快捷鍵
  animation: elastic $speed ease-in-out infinite;

將橢圓設為3D屬性,使得背面的背景色可以看到,再將.grey.green分別設成正面和背面,加上動畫elastic的旋轉效果。

.grey & .green

.grey {
    position: absolute;
    width: $e-width;
    height: $e-height;
    background: $grey;
    backface-visibility: hidden; // bf為快捷鍵
    border-radius: 50%;
    z-index: 2;
    rotate: x 0deg;
  }
  
  .green {
    @extend .grey;
    background: $green;
    z-index: 1;
    rotate: x 180deg; // 以X軸為軸心旋轉180度,來到背面
  }

.greyz-index較大,所以將backface-visibility設為隱藏,使得背面的.green可以顯現。

.ball

.ball {
  blur: 10px;
	position:relative;
	width:100px;
	height:100px;
	border-radius:50%;
	top:100px;
	left:150px;
	background: rgb(9,21,233);
	background: linear-gradient(90deg, $green 0%, rgba(84,111,191,1) 100%);
	z-index:3;
	animation: ball 5s ease-in-out infinite;
}

z-index設為3高過於.grey.green,加上ball的動畫,透過topleft的屬性調整位置,隨著介面而移動。

動畫

@keyframes elastic {
  0% {
    rotate: x 90deg;
  }
  ...  // 旋轉角度越來越小,正面背景灰色逐漸往下。
  65% {
    rotate: x 30deg; // 下到底點,猛力回彈
  }
  70% {
    rotate: x 130deg; 
  }
  75% {
    rotate: x 60deg;
  }
  80% {
    rotate: x 110deg;
  }
  85% {
    rotate: x 80deg;
  }
  90% {
    rotate: x 97deg;
  }
  95% {
    rotate: x 87deg;
  }
  100% {
    rotate: x 90deg;
  }
}

elastic介面70%~100%的彈跳幅度趨緩,回到rotate: x 90deg的原點。

@keyframes ball {
	0% {
		top:100px;
		left:150px;
	}
    ... // 0% ~ 65% 球逐漸下滑,從0deg逐漸旋轉到180deg
    65% {
        top:274px;
        left:150px;
    }
    // 猛力回彈,旋轉停止並從180開始轉向0deg
    70% {
        top:-200px;
        left:150px;
    rotate: 180deg;
    }
    90% {
        top:-100px;
        left:150px;
    }
    100% {
        top:100px;
        left:150px;
    }
}

配合elasticball的動畫後,產生以下的作品


打包帶走(take away)

CSS

目標 屬性
彈性介面 寬度大於.frame的3d橢圓形,裡面有前面和後面的背景色(rotate x: 180deg),配合z-indexbackface-visibility
彈性動畫 rotate x屬性的調整
彈跳球 top屬性配合動畫調整

後記

第20天,感謝各位的觀看~咱們明天見!


上一篇
[Day 19] Penrose Triangle: 潘洛斯三角(不可能三角)
下一篇
[Day 21] Slider with Radio Button: 三點換頁
系列文
Do you wanna play? CSS game ぎりぎり30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言