SCSS에서는 mixin
기능으로 파라미터를 넣어 애니메이션을 유연하게👻 만들 수 있습니다.
@mixin jump($name: default, $x: 1.1, $y: 0.9, $z: -2rem, $time: 2.4s, $bounce: 0.05) {
@keyframes jump__#{$name} {
0% {
transform: scale(1, 1) translateY(0);
}
5% {
transform: scale($x, $y) translateY(0);
}
25% {
transform: scale($y, $x) translateY($z);
}
50% {
transform: scale($x, $y) translateY(0);
}
60% {
transform: scale(#{$x + $bounce}, $y) translateY(0);
}
70% {
transform: scale(1, 1) translateY(0);
}
100% {
transform: scale(1, 1) translateY(0);
}
}
animation: jump__#{$name} $time ease infinite;
}
@mixin animate($animation, $duration, $method, $times) {
animation: $animation $duration $method $times;
}
Styled-components로도 animation을 유동적으로 생성할 수 있는 방법이 있을까 고민하다,
리터럴 문법을 활용해 보기로 하였습니다.
// _app.tsx
import { ThemeProvider } from 'styled-components';
import DefaultStyle from '@/assets/style';
import theme from '@/assets/style/Theme';
import HeadInfo from '@/components/common/HeadInfo';
import ModalView from '@/components/common/modal/ModalView';
import type { AppProps } from 'next/app';
import { Provider } from 'react-redux';
import indexStore from '@/redux';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<HeadInfo />
<DefaultStyle />
<Provider store={indexStore}>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
<ModalView />
</ThemeProvider>
</Provider>
</>
);
}
일단 애니메이션을 어떤 컴포넌트에서도 사용할 수 있도록,
theme을 정의한 theme.ts
파일을 만들고 루트 컴포넌트에서ThemeProvider
로 내려주었습니다.
//theme.ts
import { css } from 'styled-components';
import { fadeInParamType } from './animation';
export const color = {...};
export const layout = {...};
export const font = {...};
export const animation = {
fadeIn: ({ name, duration, count = '1', direction = 'normal' }: FadeInParamType) => css`
@keyframes fadeInAni${name} {
0% {
opacity: 0;
}
100% {
opacity: 100%;
}
}
animation: ${'fadeInAni' + name} ${duration} ${count} ${direction};
`,
};
const theme = {
color,
layout,
font,
animation,
};
export default theme;
그 다음에는 theme.ts 파일에 animation을 함수 형식으로 정의해 줍니다.
styled-components 라이브러리에서 css
함수를 import 한 뒤
유동적으로 만들어 줄 부분을 파라미터로 만들고, css 리터럴을 반환해주는 함수를 만들어 주었습니다. 💨
// animation.d.ts
type DirectionType = 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
interface BaseAniParamType {
name: string;
duration: string;
}
interface FadeInParamType extends BaseAniParamType {
direction?: directionType;
count?: string;
}
추가적으로, 저는 typeScript를 사용했기 때문에 함수 파라미터의 타입을 정의해 주는 animation.d.ts 파일을 만들었습니다.
const Modal = {
Section: styled.section`
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.63);
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
height: 100%;
${({ theme }) => theme.animation.fadeIn({ name: 'modalFadeIn', duration: '0.2s' })};
${({ theme }) => theme.animation.fadeIn({ name: 'modalFadeIn', duration: '0.2s' })};
만든 애니메이션은 스타일 컴포넌트의 props.theme
에서 꺼내 다음과 같이 사용이 가능합니다.🙇