๊ฐœ๋ฐœ ๐Ÿพ/ReactJS

React ์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜, ์ธํ„ฐ๋ ‰์…˜ ๊ตฌ์ถ•ํ•˜๊ธฐ (emotion / tweenmax)

JOTOKKI 2021. 6. 23. 14:35
728x90

1. emotion keyframes ์‚ฌ์šฉํ•˜๊ธฐ

์ฐธ์กฐ์‚ฌ์ดํŠธ

https://www.npmjs.com/package/@emotion/react

https://emotion.sh/docs/keyframes

 

emotion/react ์—์„œ๋Š” keyframes๋ฅผ ํ†ตํ•˜์—ฌ ๊ธฐ์กด CSS์—์„œ ์‚ฌ์šฉํ•˜์˜€๋˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ keyframe์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ์„ค์น˜๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. 

yarn add @emotion/react

๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ• ๋ฐ ๋Ÿฐํƒ€์ž„์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค๋ฉด ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

 

์•„์ฃผ ์‹ฌํ”Œํ•œ floating ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € keyframes๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. 

floating ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค๊ณ , ์Šคํƒ€์ผ์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 

๊ฐ„๋‹จํ•œ ์„ธํŒ…๋งŒ์œผ๋กœ ๊ธฐ์กด์— ์“ฐ๋˜ CSS๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์•„์ฃผ ํŽธํ•ฉ๋‹ˆ๋‹ค. 

๋˜ํ•œ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์—ฌ๊ธฐ์ €๊ธฐ import ํ•ด์„œ ์“ธ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ ๋ ๊บผ๋ผ ์ƒ๊ฐ๋ฉ๋‹ˆ๋‹ค. 

import { css, keyframes } from '@emotion/react'

function Animation1() {
    return (
        <div>
            <h2>emotion Animation</h2>
            <div className="wrap">
                <div className="box" css={boxStyle}></div>
            </div>
        </div>
    )
}

const floating = keyframes`
    0 {
        transform: translateY(0);    
    }
    50% {
        transform: translateY(-15px);
    }
    100% {
        transform: translateY(0);
    }
`

const boxStyle = css`
    width: 50px; 
    height: 50px; 
    border-radius: 100%;
    background: #a951bf;
    animation: ${floating} 2s ease infinite;
`


export default Animation1

๊ฒฐ๊ณผ


2. gsap ์‚ฌ์šฉํ•˜๊ธฐ

์ฐธ์กฐ์‚ฌ์ดํŠธ

https://www.npmjs.com/package/react-gsap

 

๊ตฌํ˜„ํ•˜๋‹ค ๋ณด๋ฉด ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ณด๋‹ค๋Š” ์ธํ„ฐ๋ ‰์…˜์ด ํ•„์š”ํ•  ๋•Œ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. 

gsap ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋‹ˆ gsap ์™€ react-gsap ๋‘ ๊ฐ€์ง€๋ฅผ ์„ค์น˜ํ•˜๋„๋ก ์•ˆ๋‚ด๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. 

gsap๋Š” ๊ธฐ์กด javascript์—์„œ ์“ฐ๋˜ ๋ฐฉ๋ฒ•๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅธ๊ฒŒ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. 

yarn add gsap

gsap๋Š” from, to ํ‚ค์›Œ๋“œ๋กœ ์‹œ์ž‘์ ๊ณผ ๋์ ์„ ์—ฐ๊ฒฐ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

์•„๋‹ˆ๋ฉด ๋‹จ๋…์œผ๋กœ to๋งŒ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด css์—์„œ ๋ณ€ํ˜•์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๊ธฐ์กด gsap ๋™์ž‘๋ฐฉ์‹์€ ๊ฐ์ฒด์— ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ์›€์ง์ž„์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์•กํŠธ์—์„œ๋Š” useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ,

๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๊ธฐ๋ณธ์ ์œผ๋กœ ์ธํ„ฐ๋ ‰์…˜์€ ํ•œ ๋ฒˆ๋งŒ ๋™์ž‘ ํ•˜๋ฉฐ, ๋ฐ˜๋ณต์„ ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด repeat: -1 ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

import gsap from 'gsap'

function Animation2() {
    const boxRef = useRef(null);
    useEffect(() => {
        gsap.to(boxRef.current, 1, {transform: 'translateX(200px)', delay: .5, ease: 'ease'})
    }, [])

    return (
        <div>
            <h2>gsap Animation</h2>
            <div className="wrap">
                <div className="box" css={boxStyle} ref={boxRef}></div>
            </div>
        </div>
    )
}

const boxStyle = css`
    width: 50px; 
    height: 50px; 
    border-radius: 100%;
    background: #bf5160;
`
export default Animation2

๊ฒฐ๊ณผ ( ํ•œ ๋ฒˆ๋งŒ ๋™์ž‘ )


3. react-gsap ์‚ฌ์šฉํ•˜๊ธฐ

์ฐธ์กฐ์‚ฌ์ดํŠธ

https://bitworking.github.io/react-gsap/src-components-timeline

 

gsap์™€ react-gsap์˜ ์‚ฌ์šฉ๋ฒ•์ด ๊ฝค ๋งŽ์ด ๋‹ฌ๋ผ๊ณ  ๋ณ„๊ฐœ๋กœ ๊ตฌ๋ถ„์„ ํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. 

์ด๋ฒˆ์—๋Š” timeline์„ ์ฃผ์–ด ๋‘ ๊ฐ€์ง€ ๋™์ž‘์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

1. opacity 0 -> 1

2. ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์›€์ง์ž„

react-gsap๋Š” gsap์™€๋Š” ๋‹ฌ๋ฆฌ class ์ปดํฌ๋„ŒํŠธ ํ˜•ํƒœ๋กœ ์›€์ง์ž„์„ ์ฃผ๋ ค๋Š” ๊ฐ์ฒด๋ฅผ target์œผ๋กœ ๋ณด๋‚ด์„œ ๊ตฌํ˜„์„ ํ•ฉ๋‹ˆ๋‹ค. 

์ดํ›„ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ๋ชจ์…˜๋“ค์„ Tween์— ๋‹ด๊ณ  TimeLine์œผ๋กœ ๊ฐ์‹ธ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

yarn add gsap react-gsap
import { Timeline, Tween } from 'react-gsap';

function Animation3() {
    return (
        <div>
            <h2>react-gsap Animation</h2>
            <div className="wrap">
                <Timeline
                    target={<div className="box" css={boxStyle}></div>}
                >
                    <Tween from={{ opacity: 0 }} to={{opacity: 1}} duration={1} />
                    <Tween to={{ x: '200px' }} />
                </Timeline>
            </div>
        </div>
    )
}

const boxStyle = css`
    width: 50px; 
    height: 50px; 
    border-radius: 100%;
    background: #bf5160;
    opacity: 0;
`

export default Animation3

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ •๋ง ์‰ฝ๊ฒŒ ๊ตฌ์ถ• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ฒฐ๊ณผ ( ํ•œ ๋ฒˆ๋งŒ ๋™์ž‘ )

๊ณต์‹ ์‚ฌ์ดํŠธ๋ฅผ ๋ณด์‹œ๋ฉด stop, pause ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ชจ๋กœ ์ธํ„ฐ๋ ‰์…˜ ๊ตฌํ˜„ํ•˜์‹œ๋Š” ๋ถ„๋“ค์—๊ฒŒ ์ข‹์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๐Ÿ˜

 


 

๋ฐ˜์‘ํ˜•