I want to slow down the animation of the Box when the button is pressed

Solution for I want to slow down the animation of the Box when the button is pressed
is Given Below:

I’m using react.js, Typescript, chakra and animation framer.
There is a MotionSwipe component that allows you to swipe right and left. It can be dragged to swipe the Box of a child element.
We want the Box to move to the right or left not only by dragging, but also by pressing a button.
In the function onClickSwipe, which is called when the button is pressed, I executed the animateCardSwipe function to make it swipe to the right. However, the animation is too fast for me to see. I would like to slow down the animation of the Box moving to the right when the button is pressed.

import { Button,Box  } from '@chakra-ui/react';
import { PanInfo, useMotionValue, useTransform } from 'framer-motion';
import { NextPage } from 'next';
import { MotionSwipe } from 'components/MotionSwipe';
import React, { useState } from 'react';

const Component: React.VoidFunctionComponent = () => {
  const [cards, setCards] = useState([
    { text: 'Up or down', background: 'red' },
    { text: 'Left or right', background: 'green' },
    { text: 'Swipe me!', background: 'gray' },
  ]);

  const [dragStart, setDragStart] = useState<{ axis: string | null; animation: { x: number; y: number } }>({
    axis: null,
    animation: { x: 0, y: 0 },
  });

  const x = useMotionValue(0);
  const y = useMotionValue(0);

  const onDirectionLock = (axis: string | null) => setDragStart({ ...dragStart, axis: axis });

  const animateCardSwipe = (animation: { x: number; y: number }) => {
    setDragStart({ ...dragStart, animation });

    setTimeout(() => {
      setDragStart({ axis: null, animation: { x: 0, y: 0 } });
      x.set(0);
      y.set(0);
      setCards([...cards.slice(0, cards.length - 1)]);
    }, 200);
  };

  const onDragEnd = (info: PanInfo) => {
    if (dragStart.axis === 'x') {
      if (info.offset.x >= 400) animateCardSwipe({ x: 300, y: 0 });
      else if (info.offset.x <= -400) animateCardSwipe({ x: -300, y: 0 });
    } else {
      if (info.offset.y >= 100) animateCardSwipe({ x: 0, y: 100 });
      else if (info.offset.y <= -100) animateCardSwipe({ x: 0, y: -100 });
    }
  };

  const rotate = useTransform(x, [-700, 700], [-90, 90]);

  const onClickSwipe = () => {
    animateCardSwipe({ x: 500, y: 0 });
  };

  return (
    <>
      <Box display="flex" justifyContent="center" width="300px">
        {cards.map((card, index) =>
          index === cards.length - 1 ? (
            <MotionSwipe
              animate={dragStart.animation}
              card={card}
              key={index}
              onDirectionLock={(axis: string) => onDirectionLock(axis)}
              onDragEnd={(e: MouseEvent, info: PanInfo) => onDragEnd(info)}
              style={{ x, y, zIndex: index, rotate: rotate }}
            >
              <Box background={card.background} height="300px" width="300px"></Box>
            </MotionSwipe>
          ) : (
            <MotionSwipe
              card={card}
              key={index}
              style={{
                zIndex: index,
              }}
            >
              <Box background={card.background} height="300px" width="300px"></Box>
            </MotionSwipe>
          ),
        )}
      </Box>
      <Button onClick={onClickSwipe}>
        ○
      </Button>
      <Button>✖︎</Button>
    </>
  );
};

const SwipeBox: NextPage = () => {
  return <Component />;
};

export default SwipeBox;

interface Props {
  animate?: { x: number; y: number };
  onDirectionLock?: (axis: 'x' | 'y') => void;
  onDragEnd?: (e: MouseEvent, info: PanInfo) => void;
  style: { x?: MotionValue; y?: MotionValue; zIndex: number; rotate?: MotionValue };
  card: { text: string; background: string };
}

export const MotionSwipe: React.FunctionComponent<Props> = (props) => {
  return (
    <MotionBox
      animate={props.animate}
      background="white"
      borderTopRadius="8px"
      className="card"
      display="grid"
      drag
      dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
      dragDirectionLock
      left={0}
      onDirectionLock={props.onDirectionLock}
      onDragEnd={props.onDragEnd}
      placeItems="center center"
      position="absolute"
      style={{ ...props.style }}
      top={0}
      transition={{ ease: [0.6, 0.05, -0.01, 0.9], duration: 3 }}
    >
      {props.children}
    </MotionBox>
  );
};

Yes, it’s ok when it moves fast. How to change:

  1. set useState variable to check if the button was pressed.
    For example: const [pressed, setPressed] = useState(false);
  2. If the button was pressed, you set setPressed(true)
  3. If pressed(true) you add some transition or animation props with duration.

If you don’t have duration, your element will triggers instantly after button click.