🧑‍💻개발/아카이브

[라이브러리] GSAP.timeline을 활용한 말풍선 모션

무택 2024. 11. 5.

말풍선 모션

 

HTML/CSS

<link href="
https://cdn.jsdelivr.net/npm/spoqa-han-sans@3.3.0/css/SpoqaHanSansNeo.min.css
" rel="stylesheet">

<style>
    *{ list-style: none; margin: 0; padding: 0; box-sizing: border-box; }
    .wrap { width: 640px; height: 400px; background-color: #33ccff; position: relative; font-family: 'Spoqa Han Sans Neo', sans-serif;}
    .wrap .chat_wrap { width: 500px; height: 336px; margin: 0 auto; position: relative; top: 50%; transform: translateY(-50%); overflow: hidden; }
    .wrap .chat_wrap .bubble { overflow: hidden; transform: scale(0); padding-bottom: 10px; position: absolute; top: 252px; }
    .wrap .chat_wrap .bubble.left { text-align: left; transform-origin: left bottom; }
    .wrap .chat_wrap .bubble.right { text-align: right; transform-origin: right bottom; right: 0; }
    .wrap .chat_wrap .bubble .main { display: inline-block; padding: 18px 40px; border-radius: 38px; font-size: 32px; line-height: 1.2; max-width: 410px; font-weight: bold; }
    .wrap .chat_wrap .bubble.left .main { background-color: #131313; color: #fff; }
    .wrap .chat_wrap .bubble .sub { color: #fff; font-weight: 100; }
    .wrap .chat_wrap .bubble.left .sub { margin-left: 10px; }
    .wrap .chat_wrap .bubble.right .sub { margin-right: 10px; }
    .wrap .chat_wrap .bubble.right .main { background-color: #fff; color: #131313; }
    .wrap .chat_wrap .bubble.fifth .main { width: 320px; }
    .wrap .chat_wrap .bubble.fifth img { width: 100%;  }
</style>

<div class="wrap">
  <div class="chat_wrap">
    <div class="bubble left first">
      <p class="main">꿈은</p>
      <span class="sub">AM 15:30</span>
    </div>
    <div class="bubble right second">
      <span class="sub">AM 15:30</span>
      <p class="main">없고요</p>
    </div>
    <div class="bubble left third">
      <p class="main">그냥</p>
      <span class="sub">AM 15:30</span>
    </div>
    <div class="bubble right fourth">
      <span class="sub">AM 15:30</span>
      <p class="main">놀고 싶습니다.</p>
    </div>
    <div class="bubble left fifth">
      <p class="main">
        <img src="https://em-content.zobj.net/source/animated-noto-color-emoji/356/hear-no-evil-monkey_1f649.gif" alt="">
        </p>
      <span class="sub">AM 15:30</span>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script>

 

JS

const bubble_01 = () => gsap.timeline()
.to('.chat_wrap .bubble.first', {
  scale: 1,
  duration: .05,
}, .5);

const bubble_02 = () => gsap.timeline()
.to('.chat_wrap .bubble.first', {
  top: 168,
  duration: .05,
}, .5)
.to('.chat_wrap .bubble.second', {
  scale: 1,
  duration: .05,
}, .5)

const bubble_03 = () => gsap.timeline()
.to('.chat_wrap .bubble.first', {
  top: 84,
  duration: .05,
}, 0.5)
.to('.chat_wrap .bubble.second', {
  top: 168,
  duration: .05,
}, 0.5)
.to('.chat_wrap .bubble.third', {
  scale: 1,
  duration: .05,
}, 0.5)

const bubble_04 = () => gsap.timeline()
.to('.chat_wrap .bubble.first', {
  top: 0,
  duration: .05,
}, .5)
.to('.chat_wrap .bubble.second', {
  top: 84,
  duration: .05,
}, .5)
.to('.chat_wrap .bubble.third', {
  top: 168,
  duration: .05,
}, .5)
.to('.chat_wrap .bubble.fourth', {
  scale: 1,
  duration: .05,
}, .5)

const bubble_05 = () => gsap.timeline()
.to('.chat_wrap .bubble.first', {
  top: -284,
  duration: .05,
}, 0.75)
.to('.chat_wrap .bubble.second', {
  top: -200,
  duration: .05,
}, 0.75)
.to('.chat_wrap .bubble.third', {
  top: -116,
  duration: .05,
}, 0.75)
.to('.chat_wrap .bubble.fourth', {
  top: -32,
  duration: .05,
}, 0.75)
.to('.chat_wrap .bubble.fifth', {
  top: 52,
  scale: 1,
  duration: .05,
}, 0.75)

gsap.timeline({repeat: -1, repeatDelay: 1.5})
  .add(bubble_01())
  .add(bubble_02())
  .add(bubble_03())
  .add(bubble_04())
  .add(bubble_05())

 

Codepen

See the Pen [Library] GSAP.timeline bubble by TytanLee (@TytanLee) on CodePen.

 

 

 

  • 기본적인 사용법은 `gsap.to("HTML 요소", { 적용시킬 css 내용 }, 딜레이 초);`
  • 하지만 아래처럼 변수를 선언하고 하나의 모션을 묶어서 만들 수도 있다
const 모션1 = () => gsap.timeline()
.to('HTML 요소', {
  적용 내용
}, 딜레이 초);

const 모션2 = () => gsap.timeline()
.to('HTML 요소', {
  적용 내용
}, 딜레이 초)
.to('HTML 요소', {
  적용 내용
}, 딜레이 초);

.
.
.

gsap.timeline({repeat: -1, repeatDelay: 1.5})
  .add(모션1)
  .add(모션2)
  • `repeat: -1`로 설정하면 계속 반복되게 할 수 있다
  • 마지막 모션의 딜레이가 1초라면 `repeatDelay`를 최소 1 이상으로 설정해야 모션을 다 보여줄 수 있다. 설정하지 않거나 그 아래의 값으로 설정하면 마지막 모션은 진행되지 않은 채로 계속 반복되게 된다.

 

 

더 자세한 정보는 GSAP 원문을 참고