프로토타입 작업중에,
@keyframe을 이용한 애니메이션을 구현해야 했다.
props를 전달한 styledComponent를 이용해 모듈화를 시키고
반복문을 통해 같은 컴포넌트에 다른 객체를 집어넣어 랜더링을 시켰다.
그런데,
다른 요소들은 다 동작하는데
@keyframe 만 따로 동작했다.
마지막으로 집어넣은 객체의 값으로 통일이 되는 현상이 발생했다.
그래서 이곳 저곳 돌아다니면서 삽질을 시작했다.
기필코 하드코딩 하지 않으리라는 마음으로.
키 프레임이 여러번 정의 된 경우,
스펙에서는 모든 속성이 각 키 프레임이 지정된 게 아니라
키 프레임이 여러번 정의 된 경우에는
가장 최근의 키프레임에 선언된 값들만 유효하다고 나와 있다.
키프레임에서 !important 속성을 이용한 정의는 모두 무시된다.
아래와 같은 sytlyed component 에서,
export const LineAni = styled.div`
...(생략)
animation-name: ${(props) => `lineMoving` + props.lineOptions.index};
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
${(props) =>
props.lineOptions.animation === "forward"
? css`
animation-direction: normal;
`
: css`
animation-direction: reverse;
`}/* animation-direction:alternate; */
/* animation-fill-mode: forwards; */
`;
export default LineAni;
@keyframe을 동적으로 선언하기 위해서는
함수를 만들어서 @keyframe 선언을 강제로 붙여 넣어줘야한다.
export const addAnimation = (name, body) => {
let dynamicStyles = null;
dynamicStyles = document.createElement("style");
dynamicStyles.type = "text/css";
document.head.appendChild(dynamicStyles);
dynamicStyles.sheet.insertRule(
`@keyframes ${name} {${body}}`,
dynamicStyles.length
);
};
강제로 붙여주는 함수를 작성한 뒤에,
component rendering 함수안에 위치시켜서
@keyframe 의 name 값과, body 값을 넣어주면 !
const lineAniHorLayerRender = () => {
if (LineOptions) {
let _LineOptions = LineOptions.filter((el) => el.rotate === "hor");
return _LineOptions.map((item, index) => {
addAnimation(
`lineMoving${item.index}`,
`to {
left: ${item.x + item.width}px;
}`
);
return (
<LineAni
lineOptions={item}
className={"lineAniHor-" + item.index}
key={"lineAniHor" + index}
/>
);
});
}
styledComponent에서 동적으로 @keyframe을 이용할 수 있다.
짜잔.