Js Challenge14 - #3 Snow animation

가짜 개발자·2023년 1월 24일
0

JS Challenge14

목록 보기
4/15


요즘 눈이 많이 와서 눈내리는 애니메이션 효과를 만들어보면 어떨까? 하는 마음에 만들어 보았다.


✅ Goal

  • 자바스크립트를 활용하여 눈 내리는 효과를 구현한다.
  • 반복적으로 재생하는 오토 텍스트 기능을 구현한다.

✅ Keyword

Math.random()
setTimeout()
@keyframes

위 3가지 키워드는 은근히 많이 쓰는 키워드중 하나이다. 랜덤 숫자를 생성하는 Math.random 지정 코드를 비동기식으로 실행하는 타이머 setTimeout() 애니메이션 제어가 가능한 @keyframes 까지 정말 유용하게 쓰이는 것 같다.

https://developer.mozilla.org/ko/docs/Web/API/setTimeout
https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes

🟢 snow animation

우선 눈을 만들어주는 함수를 제작하였다. 중요한 포인트는 randomSnow함수이다. 이함수는 뷰포트 넓이를 랜덤으로 추출해서 값을 얻을수 있도록 하였다. 그리고 createSnow 함수를 통해 추출된 넓이만큼 마진값을 넣어 눈의 위치를 다양한 위치에서 출발 할 수 있도록 하였다.

//index.js
function createSnow() {
  const snowDiv = document.createElement("div");
  snowDiv.classList.add("snow");
  snowDiv.style.marginLeft = randomSnow() + "px";
  document.body.appendChild(snowDiv);
}

function randomSnow() {
  return Math.floor(Math.random() * window.innerWidth);
}
for (let i = 0; i < 550; i++) {
  createSnow();
}

스노우 애니메이션 효과는 @keyframes 을 활용하여 구현하였다. transform은 인터렉티브한 ui나 효과를 줄때 매우 유용한 css속성이다.

/*css*/
.snow {
  width: 10px;
  height: 10px;
  background-color: #fff;
  border-radius: 50%;
  animation: snow 10s linear infinite;
  opacity: 0;
}

.snow:nth-of-type(2n) {
  animation-duration: 7s;
  width: 7px;
  height: 7px;
  animation-delay: 1s;
}

.snow:nth-of-type(2n + 1) {
  animation-duration: 8s;
  width: 7px;
  height: 7px;
  animation-delay: 1s;
}

.snow:nth-of-type(9n) {
  animation-duration: 9s;
  width: 7px;
  height: 7px;
  animation-delay: 3s;
}

@keyframes snow {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  20% {
    opacity: 1;
    transform: translateY(-15px, 20vh);
  }
  40% {
    opacity: 1;
    transform: translate(15px, 40vh);
  }
  60% {
    opacity: 1;
    transform: translate(-15px, 60vh);
  }
  80% {
    opacity: 1;
    transform: translate(15px, 80vh);
  }
  100% {
    opacity: 1;
    transform: translateY(100vh);
  }
}

🟢 auto text

auto text의 핵심은 slicesetTimeout 이다. myTextslice함수를 사용하여 idx가 증가할때마다 text의 해당 인덱스의 글자가 나올수 있도록 하였고 setTimeout을 활용하여 0.2마다 글자가 순차적으로 나올수있도록 구현하였다.

// index.js
const h1 = document.createElement("h1");
const myText = "Snow falls from the sky";
let idx = 1;
function writeText() {
  h1.innerText = myText.slice(0, idx);
  idx++;
  if (idx > myText.length) {
    idx = 1;
  }
  setTimeout(writeText, 200);
}

container.appendChild(h1);
writeText();

추가적으로 text의 네온효과는 css에서 @keyframes 을 활용하여 구현하였다.

/*css*/
@keyframes neon {
  from {
    text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #228dff,
      0 0 70px #228dff;
  }
  to {
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #228dff,
      0 0 35px #228dff;
  }
}

🟥 조금은 고민했던 부분

auto text에서 반복적으로 글짜가 나올수있도록 구현해보고자 했다.


// index.js
//...
const myText = "Snow falls from the sky";
let idx = 1;
function writeText() {
  // 첫글자씩 잘라서 글짜 추가
  h1.innerText = myText.slice(0, idx);
  idx++;
  // 자동반복 할 수 있는 조건
  if (idx > myText.length) {
    idx = 1;
  }
  // 0.2초마다 글자 나오게 실행
  setTimeout(writeText, 200);
}

위와 같이 자동반복 할 수 있는 조건을 주지 않으면 myText글자는 다나오고 idx만 계속 늘어 날 것이다. 그래서 myText의 길이보다 계속 증가하는 idx보다 작으면 idx값을 1로 다시 할당하여 반복적으로 글자가 나오게 구현하였다.



✅ 기능 시연 및 코드

아이디어만 있다면 자바스크립트를 통해 재미있는 기능구현이 가능하다. 내일은 어떤것을 해볼까나..

// index.js
const container = document.querySelector("#container");
const h1 = document.createElement("h1");

function createSnow() {
  const snowDiv = document.createElement("div");
  snowDiv.classList.add("snow");
  snowDiv.style.marginLeft = randomSnow() + "px";
  document.body.appendChild(snowDiv);
}

function randomSnow() {
  return Math.floor(Math.random() * window.innerWidth);
}
for (let i = 0; i < 550; i++) {
  createSnow();
}

const myText = "Snow falls from the sky";
let idx = 1;
function writeText() {
  h1.innerText = myText.slice(0, idx);
  idx++;
  if (idx > myText.length) {
    idx = 1;
  }
  setTimeout(writeText, 200);
}

container.appendChild(h1);
writeText();

https://github.com/fake-dp/Js-Challenge14-Mini-Project/tree/main/Snow
배포링크

profile
프론트 개발 일지

0개의 댓글