animation ?
페이지 전환, 스크롤 이벤트, 구성 요소 진입, 종료 등을 처리 할 때 나 그 외 시각적으로 보이는 애니메이션 입니다.
현재 2021년 기준 animation의 라이브러리 사용률은
- React Spring.
- React Circle.
- React Particle Effect Button.
- React Stonecutter.
- Ant Motion.
- React Scroll Parallax.
- React Loading.
- React flip toolkit.
이라고 합니다.
그래서 React Spring 라이브러리로 코드를 짜볼겁니다.
라이브러리 설치
npm install --save react-spring
사이트에 codesandbox.io/embed/n9vo1my91p
이 예시로 코드를 한번 보겠습니다.
import { render } from 'react-dom'
import React, { useRef } from 'react'
import clamp from 'lodash-es/clamp'
import { useSprings, animated } from 'react-spring'
import { useGesture } from 'react-use-gesture'
import './styles.css'
const pages = [
'https://images.pexels.com/photos/62689/pexels-photo-62689.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/296878/pexels-photo-296878.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/1509428/pexels-photo-1509428.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/351265/pexels-photo-351265.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/924675/pexels-photo-924675.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
]
function Viewpager() {
const index = useRef(0)
const [props, set] = useSprings(pages.length, i => ({ x: i * window.innerWidth, sc: 1, display: 'block' }))
const bind = useGesture(({ down, delta: [xDelta], direction: [xDir], distance, cancel }) => {
if (down && distance > window.innerWidth / 2)
cancel((index.current = clamp(index.current + (xDir > 0 ? -1 : 1), 0, pages.length - 1)))
set(i => {
if (i < index.current - 1 || i > index.current + 1) return { display: 'none' }
const x = (i - index.current) * window.innerWidth + (down ? xDelta : 0)
const sc = down ? 1 - distance / window.innerWidth / 2 : 1
return { x, sc, display: 'block' }
})
})
return props.map(({ x, display, sc }, i) => (
<animated.div {...bind()} key={i} style={{ display, transform: x.interpolate(x => `translate3d(${x}px,0,0)`) }}>
<animated.div style={{ transform: sc.interpolate(s => `scale(${s})`), backgroundImage: `url(${pages[i]})` }} />
</animated.div>
))
}
render(<Viewpager />, document.getElementById('root'))
공식사이트 코드입니다. 참조하면 좋을 것 같습니다.
Hooks
useChain - 이전에 정의 된 애니메이션 후크의 실행 순서를 설정합니다. 여기서 하나의 애니메이션은 순서대로 다른 애니메이션이 시작됩니다. 연결하려는 애니메이션에서 참조를 수집해야 애니메이션이 자체적으로 시작되지 않습니다. 순서는 후속 렌더 패스에서 변경할 수 있습니다.
useSpring - 값을 애니메이션 값으로 바꿉니다.
useSprings - 각각 자체 구성을 가진 여러 스프링을 만듭니다. 정적 목록 등에 사용됩니다.
useTrail - 단일 구성으로 여러 스프링을 생성하고 각 스프링은 이전 구성을 따릅니다. staggered animations 에 사용된다고합니다.
useTransition - 애니메이션 된 TransitionGroup입니다. items and lifecycles를 추가해야합니다. 항목이 추가되거나 제거 될 때마다 이러한 변경 사항이 애니메이션으로 표시됩니다.
공식페이지의 Hooks 부분을 보면 자세히 나와있습니다!
import { useSpring, animated } from 'react-spring'
function App() {
const data = useSpring({ count: 1, from: { count: 0 } })
// spring을 useSpring 으로 정의합니다
return <animated.div>{props.number}</animated.div>
// animated을 return으로 묶기
}
Hooks api 구조입니다.
Render Props
spring - 값을 애니메이션 값으로 바꿉니다.
springContext - 지정된 children에서 애니메이션을 수정 하지만 후크 API (예 useSpring:) 또는 renderprops API (예 :)로 만든 애니메이션 만 <Spring>영향을받습니다. new SpringValue()또는 new Controller()로 생성 된 애니메이션 은 영향을받지 않습니다.
trail - 단일 구성으로 여러 스프링을 생성하고 각 스프링은 이전 구성을 따릅니다. staggered animations에 사용하세요
transition - 애니메이션 된 TransitionGroup입니다. items and lifecycles를 추가해야합니다. 항목이 추가되거나 제거 될 때마다 이러한 변경 사항이 애니메이션으로 표시됩니다.
import { Spring } from 'react-spring/renderprops'
function App() {
return (
<Spring from={{ count: 0 }} to={{ count: 1 }}>
{props => <div>{props.count}</div>}
</Spring>
)
}
Render Props api 구조입니다.
두개의 차이
Hooks, Render Props (Class) 둘 중에 자신의 코드에 따라 사용하면 될 것 같습니다.
둘의 가장 큰 차이점은 Hooks는 view를 몰라서 스타일을 스코프 밖에 사용했다면 해당 스타일을 custom hooks를 사용해서 <animated.div />에 알려줘야 합니다.
결론
아직 프로젝트에 적용은 안해보고 흥미롭고 나중에 적용해야지 생각하고 정리글을 올려봤습니다. 추가 피드백이나 부족한 부분이 있으면 알려주시면 감사하겠습니다!
'React' 카테고리의 다른 글
Emotion 라이브러리란? (0) | 2021.12.29 |
---|---|
상태 관리 라이브러리 Recoil 이란? (0) | 2021.12.27 |
React Styled Component에 대해 알아보자! (0) | 2019.10.07 |
canvas 라이브러리 Fabric Demo (0) | 2019.09.20 |
CORS 란?! (0) | 2019.09.16 |