Rotating Text

Demo

Nachos are

사용한 API

  • requestAnimationFrame, setTimeout()
  • 3D transform (rotateX, translateZ)
  • display: absolute

동작 방법

여러 단어를 한곳에 곂치게 위치

display: absolute를 사용하면 같은 위치에 컨텐츠가 곂치게 위치시킬 수 있다.

곂쳐진 단어 중 한개만 보이게

opacity: 0을 주어 모든것을 안보이게 하고, 보여주고 싶은것만 1을 주어 보여준다.
처음에는 제일 첫번째 단어만 보여주어야 하기 때문에 첫번째 단어에 1을 설정한다.

보여진 단어를 문자로 짜른다.

보여지는 단어의 문자를 한개씩 아래로 내려 보내야하기 때문에, 먼저 문자로 쪼개야한다.
보여지는 단어를 .innerHTML통해 획득하고 charAt(i)를 통해 하나씩 가져와 span 태그를 만든다.

splitWord(word: Element) {
  const content = word.innerHTML
  word.innerHTML = ''
  const chars = []
  for (let i = 0; i < content.length; i++) {
    const char = document.createElement('span')
    char.className = 'char'
    char.innerHTML = content.charAt(i)
    word.appendChild(char)
    chars.push(char)
  }
  this.words.push(chars)
}

문자를 순차적으로 아래로 내려 사라지게 한다.

문자 하나씩 for loop 돌려, setTimeout을 걸어놓는다.
뒤에 있는 문자일 수록 더 늦게 설정하여 하나씩 사라지게끔 보여지게 한다.
x axis 중심으로 90deg가 이동되네 글자가 z axis 중심에 위치되어 우리 눈에 안보이게 된다.
여기서 알아두어야 할 점은 inline element는 transform이 작동되지 않는다. 그래서 inline-block으로 변경해주어야 작동한다.

hide(ele: HTMLSpanElement[], i: number) {
  setTimeout(function () {
    ele[i].className = 'char out'
  }, i * 80)
}
.char.out {
    transform: rotateX(90deg);
    transition: 0.2s ease-in-out;
}

rotateX()

사라진 후 상위로 올려 나중에 내려올 수 있게

.char element의 클래스를 behind로 변경하여 위에서 아래로 내려오는것 처럼 보이도록 미리 설정한다.
-90 deg이면 아까와 180deg 다른 쪽에 위치한다. negative Z axis에 위치할것이다.

.char.behind {
  transform: rotateX(-90deg);
}

새로운 단어가 위에서 아래로 노출

in class가 추가되면서 rotateX(0deg)가 실행된다. 즉 원래 자리로 되돌아가는것이다.
이때 부모 element에서 opacity 1로 설정하는걸 잊지 말자

show(nw: HTMLSpanElement[], i: number) {
  setTimeout(function () {
    nw[i].className = 'char in'
  }, 340 + i * 80)
}
.char.in {
    transform: rotateX(0deg);
    transition: 0.2s ease-in-out;
}

반복해서 단어 교체

requestAnimationFrame을 이용하여 계속 변하게 개발했다.
4초마다 단어가 바뀌는데, 현 시간과 변경된 시간의 차를 비교하여 다음단어가 노출되도록 하였다.
처음에 숨기고(hide), z-aixs 뒤로 위치시켰다가 (behind), 새로운 단어를 보여주게끔(show) 개발했다

z-axis

transform-origin 에 z 값을 꼭 추가해주어야 한다.
않그러면, z-axis를 사용하지 않는것처럼 작동하여 단어가 아래로 사라지지 않는다.

.char {
  display: inline-block;
  transform: translateZ(10px);
  transform-origin: 50% 50% 10px;
}

Reference

https://codepen.io/rachsmith/pen/BNKJme

https://stackoverflow.com/questions/14883250/css-transform-doesnt-work-on-inline-elements