๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Front-end/GSAP

GSAP ๊ธฐ์ดˆ ์ •๋ฆฌ - Tween๊ณผ Timeline

GSAP์ด๋ž€?

GreenSock Animation Platform

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์™€ ๋””์ž์ด๋„ˆ๋“ค์ด ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ฃผ ๊ฐ•๋ ฅํ•œ ํƒ€์ž„๋ผ์ธ ๊ธฐ๋ฐ˜์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

GSAP๋Š” CSS์˜ keyframe๊ณผ animation ๋ณด๋‹ค ๋” ์ •๋ฐ€ํ•œ ์ปจํŠธ๋กค์„ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ€๋ณ๊ณ  ์‚ฌ์šฉ๋ฐฉ๋ฒ•์ด ์‰ฝ๋‹ค๋Š” ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด ์žˆ๋‹ค.

 

 

Tween

 

Tween์€ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ •์˜ํ•˜๋Š” ๊ฐ์ฒด ๊ฐœ๋…์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. 

gsap.to("#b", 3, {delay:2, x:700, repeat:-1});
gsap.from("#g", 3, {delay:2, x:700, repeat:-1});
gsap.fromTo("#r", 3, {x:200}, {delay:2, x:700, repeat:-1})

 

์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐ์„ฑ์„ ์œ„ํ•ด fromTo method์˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

 

 

 

Timeline

 

Timeline์€ tween ๋ฐ ๊ธฐํƒ€ timeline์˜ ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์‹œํ€€์‹ฑ ๋„๊ตฌ๋กœ, ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ํƒ€์ด๋ฐ์„ ์ •ํ™•ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

ํƒ€์ž„๋ผ์ธ์˜ ์†์„ฑ์€ tween์˜ ๋ชจ๋“  ๋””ํดํŠธ ์†์„ฑ๋“ค์„ overrideํ•œ๋‹ค.

์‚ฌ์šฉ๋ฒ•์€ ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค.

 

let tl = gsap.timeline({ 
  defaults: 
    {duration: 2, ease: "power1.inOut", yoyo: true, repeat: -1}
})

  .to("#cr1", {x: 500})
  .to("#cr2", {x: 461.94, y: -191.64}, "<0.25")
  .to("#cr3", {x: 353.55, y: -353.56}, "<0.25")
  .to("#cr4", {x: 191.34, y: -461.94}, "<0.25")
  .to("#cr5", {y: -500}, "<0.25")
  .to("#cr6", {x: -191.35, y: -461.94}, "<0.25")
  .to("#cr7", {x: -353.55, y: -353.56}, "<0.25")
  .to("#cr8", {x: -461.94, y: -191.34}, "<0.25")

document.addEventListener("click", function(e) {
  tl.reverse(); 
});
document.addEventListener("dblclick", function(e) {
  tl.play(); 
});

 

 

position parameter

์œ„์˜ ์ฝ”๋“œ์—์„œ "<0.25" ๋ถ€๋ถ„์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์ด๋‹ค.

๋ชจ๋“  tween method์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ณ , ํƒ€์ž„๋ผ์ธ์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ insertion location์„ ๊ฒฐ์ •ํ•œ๋‹ค.

 

 

 

 

position parameter์„ absolute time [seconds]๋กœ ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด

๊ธฐ์กด ์ฝ”๋“œ์™€ ๋˜‘๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

 

 

 

 

relative to the end of a timeline [+=seconds / -=seconds] ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค๋ฉด

 

์ฒซ๋ฒˆ์งธ ์›์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์›์ด ์ฒ˜์Œ์œผ๋กœ๋ถ€ํ„ฐ 0.25์ดˆ ์ดํ›„์— ์›€์ง์ด๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

 

ํƒ€์ž„๋ผ์ธ์˜ ์ง€์†์‹œ๊ฐ„์„ ์ •ํ•˜์ง€ ์•Š์•˜๊ณ , ๊ฐ tween์˜ ์ง€์†๊ธฐ๊ฐ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋””ํดํŠธ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ง€์ •ํ•œ ๊ฒƒ๋„ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์—, 

ํƒ€์ž„๋ผ์ธ์˜ duration์€ ์ ์ง„์ ์œผ๋กœ ๋Š˜์–ด๋‚˜๊ฒŒ ๋œ๋‹ค.

์•ž tween์˜ ๋™์ž‘์ด ๋๋‚˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ 0.25์ดˆ ํ›„์— ๋™์ž‘ํ•œ๋‹ค.

relative to the end of the most recently-added animation [>seconds] ์˜ ๋ฐฉ์‹๋„ ์ด์™€ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

 

 

 

relative to the end of the most recently-added animation [>seconds]์ธ๋ฐ seconds ๊ฐ’์„ ์Œ์ˆ˜๋กœ ํ•œ๋‹ค๋ฉด

์•ž tween์ด ๋๋‚˜๊ธฐ 0.25์ดˆ ์ „์˜ ์‹œ์ ๋ถ€ํ„ฐ ๋™์ž‘ํ•œ๋‹ค.

 

relative to the end of a timeline์ธ "-=0.25" ๋„ ์ด์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

 

 

 

tween์˜ position parameter์— label ๋ณ€์ˆ˜๋ช…์„ ๋„ฃ์œผ๋ฉด, ํ•ด๋‹น ๋ผ๋ฒจ ๊ธฐ์ค€์œผ๋กœ -=, += ํ•˜์—ฌ ์‹œ๊ฐ„์ฐจ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

control method

์˜ˆ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

gsap.registerPlugin(MotionPathPlugin); //path๋ฅผ ๋”ฐ๋ผ ์›€์ง์ด๊ฒŒ ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ

let timeline = gsap.timeline({
  repeat: 2, 
  repeatDelay: 5, 
  defaults: {duration: 12, ease: "power1.inOut"}
})

  .to("#hand", {
    motionPath: {
      path:"#path", 
      align:"#path", 
      alignOrigin:[0.28, 0.08]}
  })

  .to("#path", {strokeDasharray: "4046, " + "0"}, "<");  

document.getElementById("pause").onclick = () => timeline.pause();
document.getElementById("play").onclick = () => timeline.play();
document.getElementById("reverse").onclick = () => timeline.reverse();
document.getElementById("seek").onclick = () => timeline.seek(5);
document.getElementById("restart").onclick = () => timeline.restart();