Как отменить анимацию, когда опора - это компоненты с ложным стилем - PullRequest
1 голос
/ 27 мая 2020

Я передаю открытую опору стилизованному компоненту для создания анимации для значка гамбургера. Это код

const StyledBurger = styled.button`
  display: flex;
  flex-direction: column;
  justify-content: center;
  border: 0;
  background-color: ${colors.cobaltBlue};
  border-radius: 2.7px;
  cursor: pointer;
  div {
    width: 27px;
    height: 3px;
    margin: 1.5px;
    transition: all 0.2s linear;
    border-radius: 1.4px;
    background-color: ${colors.white};
    :first-child {
      ${({ open }) => open && firstOpenAnimation};
    }
    :nth-child(2) {
      opacity: ${({ open }) => (open ? '0' : '1')};
    }
    :nth-child(3) {
      ${({ open }) => open && seconOpenAnimation}
    }
  }
`;

const firstOpenKeyframe = keyframes`
  50% {
    transform: translateY(6px) rotate(0);
  }
  100% {
    transform: translateY(6px) rotate(45deg);
  }
`;

const secondOpenKeyframe = keyframes`
  50% {
    transform: translateY(-6px) rotate(0);
  }
  100% {
    transform: translateY(-6px) rotate(-45deg);
  }
`;

const firstCloseKeyFrame = keyframes`
  50% {
    transform:translateY(0) rotate(-45deg);
  }
  100% {
    transform:translateY(-6px) rotate(-45deg)  ;
  }
`;

const firstOpenAnimation = css`
  animation: 0.3s linear ${firstOpenKeyframe} forwards;
`;

const seconOpenAnimation = css`
  animation: 0.3s linear ${secondOpenKeyframe} forwards;
`;

const firstCloseAnimation = css`
  animation: 0.3s linear ${firstCloseKeyFrame} forwards;
`;

export default StyledBurger;

В основном я хочу, чтобы меню не было открыто, чтобы отменить анимацию, созданную после первого щелчка. Я пробовал сделать условный рендеринг ключевого кадра анимации на основе свойства open, но что происходит, когда страница загружается, сразу создается анимация not, открытая, потому что она удовлетворяет false. Что я могу сделать, чтобы исправить это и создать противоположную анимацию при отключении

1 Ответ

1 голос
/ 27 мая 2020

Внесите несколько исправлений, и все должно работать правильно.

  • используйте состояние для переключения открытия и отправьте его как опору для вашего стилизованного компонента
  • используйте троичный для анимации (не только && ) ${({ open }) => (open ? firstOpenAnimation : firstCloseAnimation)}.
  • реализация отсутствующей второй анимации закрытия

рабочая копия вашего кода здесь

Фрагмент рабочего кода

const StyledBurger = styled.button`
  display: flex;
  flex-direction: column;
  justify-content: center;
  border: 0;
  background-color: red;
  border-radius: 2.7px;
  cursor: pointer;
  height: 30px;
  div {
    width: 27px;
    height: 3px;
    margin: 1.5px;
    transition: all 0.2s linear;
    border-radius: 1.4px;
    background-color: white;
    :first-child {
      ${({ open }) =>
        open !== null && (open ? firstOpenAnimation : firstCloseAnimation)}
    }
    :nth-child(2) {
      opacity: ${({ open }) => (open ? "0" : "1")};
    }
    :nth-child(3) {
      ${({ open }) =>
        open !== null && (open ? seconOpenAnimation : secondCloseAnimation)}
    }
  }
`;

const firstOpenKeyframe = keyframes`
  50% {
    transform: translateY(6px) rotate(0);
  }
  100% {
    transform: translateY(6px) rotate(45deg);
  }
`;

const secondOpenKeyframe = keyframes`
  50% {
    transform: translateY(-6px) rotate(0);
  }
  100% {
    transform: translateY(-6px) rotate(-45deg);
  }
`;

const firstCloseKeyFrame = keyframes`
  50% {
    transform:translateY(0) rotate(-45deg);
  }
  100% {
    transform:translateY(0) rotate(0)  ;
  }
`;
const secondCloseKeyFrame = keyframes`
  50% {
    transform:translateY(0) rotate(-45deg);
  }
  100% {
    transform:translateY(0) rotate(0)  ;
  }
`;

const firstOpenAnimation = css`
  animation: 0.3s linear ${firstOpenKeyframe} forwards;
`;

const seconOpenAnimation = css`
  animation: 0.3s linear ${secondOpenKeyframe} forwards;
`;
const secondCloseAnimation = css`
  animation: 0.3s linear ${secondCloseKeyFrame} forwards;
`;

const firstCloseAnimation = css`
  animation: 0.3s linear ${firstCloseKeyFrame} forwards;
`;
export default function App() {
  const [open, setOpen] = useState(null);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <StyledBurger onClick={() => setOpen(prev => !prev)} open={open}>
        <div />
        <div />
        <div />
      </StyledBurger>
    </div>
  );
}

...