평소에 관심있었던 FE 애니메이션에 대해 공부하고 싶어서, 관련 예제를 조금 찾다가 도전해보았다.
애플워치의 전용 어플리케이션인 Breathe를 html / css 기반으로 클론해 보았고, 좀 더 자세한 분석 및 공부는 추후 이어서 할 계획이다.
(참조 : https://css-tricks.com/recreating-apple-watch-breathe-app-animation/)
그럼 일단 결과물부터 보자! 움직이는 모든 것들은 아름답다!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Breathe Animation</title>
<style>
body {
background: #000000;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
/* 구현 대상의 포멧에 유연한 가운데 정렬 필수요소는 이렇다. */
}
.watch-face {
height: 125px;
width: 125px;
animation: pulse 4s cubic-bezier(0.5, 0, 0.5, 1) alternate infinite;
}
.circle {
height: 125px;
width: 125px;
border-radius: 80%;
position: absolute;
mix-blend-mode: screen;
transform: translate(0, 0);
animation: center 6s infinite;
}
/* 이 부분을 보면, css에는 모자관계가 있는 것으로 유추할 수 있다. */
.circle:nth-child(odd) {
background: #b86bff;
}
.circle:nth-child(even) {
background: #7e39ff;
}
.circle:nth-child(1) {
transform: translate(-35px, -55px);
}
.circle:nth-child(2) {
transform: translate(0px, -65px);
}
.circle:nth-child(3) {
transform: translate(35px, -55px);
}
.circle:nth-child(4) {
transform: translate(60px, -30px);
}
.circle:nth-child(5) {
transform: translate(65px, 0px);
}
.circle:nth-child(6) {
transform: translate(60px, 30px);
}
.circle:nth-child(7) {
transform: translate(35px, 55px);
}
.circle:nth-child(8) {
transform: translate(0px, 65px);
}
.circle:nth-child(9) {
transform: translate(-30px, 55px);
}
.circle:nth-child(10) {
transform: translate(-60px, 30px);
}
.circle:nth-child(11) {
transform: translate(-65px, 0px);
}
.circle:nth-child(12) {
transform: translate(-55px, -30px);
}
/* 애니메이션의 보다 부드러운 작동을 기대하며 원 객체의 수를 2배 했다. */
@keyframes circle-1 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-35px, -55px);
}
}
@keyframes circle-2 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0px, -65px);
}
}
@keyframes circle-3 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(35px, -55px);
}
}
@keyframes circle-4 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(60px, -30px);
}
}
@keyframes circle-5 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(65px, 0);
}
}
@keyframes circle-6 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(60px, 30px);
}
}
@keyframes circle-7 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(35px, 55px);
}
}
@keyframes circle-8 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0px, 65px);
}
}
@keyframes circle-9 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-30px, 55px);
}
}
@keyframes circle-10 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-60px, 30px);
}
}
@keyframes circle-11 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-65px, 0);
}
}
@keyframes circle-12 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-55px, -30px);
}
}
@keyframes pulse {
0% {
transform: scale(0.15) rotate(180deg);
}
100% {
transform: scale(1);
}
}
</style>
</head>
<body>
<div class="watch-face">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</body>
</html>