tanjim anim
tanjim anim

Reputation: 531

How to fade-out and fade-in in React?

So, I have done FCC's project "Random Quote Machine", I have done the all the basic requirements such as changing the quote,color and tweet the quote. But one thing I can't do,that is the fade-in and fade-out animation of the quotes, e.g like this:https://codepen.io/freeCodeCamp/pen/qRZeGZ

In the above link,the animation has been done by jQuery. But I have done my project on ReactJS

Here's my codesandbox if you want to fork:https://codesandbox.io/s/amazing-feistel-b2u6j

and also here's the code:

import React from "react";
import "./styles.css";

import { useState, useCallback } from "react";
import {
  ChakraProvider,
  Box,
  Text,
  Button,
  Icon,
  Flex,
  HStack,
  Link
} from "@chakra-ui/react";

import { FaTwitter, FaQuoteLeft } from "react-icons/fa";
import quoteArray from "../public/quotes";
import { defaultColor, getRandomColor } from "../public/color";

const QuoteBox = () => {
  const [loading, setLoading] = useState(true);
  const [quote, setQuote] = useState(null);
  const [color, setColor] = useState(defaultColor);

  const onQuoteChange = useCallback(async () => {
    const nextColor = getRandomColor();
    setLoading(true);
    const randomQuote =
      quoteArray[Math.floor(Math.random() * quoteArray.length)];
    setTimeout(() => {
      setLoading(false);
      setColor(nextColor);
      setQuote(randomQuote);
    }, 500);
  }, []);

  React.useEffect(() => {
    onQuoteChange();
  }, [onQuoteChange]);

  var randomTweet = (quote) => {
    if (!quote) {
      return null;
    }

    const link = `https://twitter.com/intent/tweet?text="${quote.quote}"%20-${quote.author}`;
    return link;
  };

  return (
    <Box
      bg={color}
      h="100%"
      display="flex"
      flexDir="column"
      justifyContent="center"
    >
      <Box
        width="60%"
        border="1px"
        boxShadow="md"
        p={5}
        rounded="md"
        bg="white"
        borderColor="gray.400"
        mx="auto"
      >
        <Box>
          <Flex>
            <Box>
              <Icon as={FaQuoteLeft} w={7} h={6} color={color} />
              <Text fontSize="2xl" color={color} pl={8} mt="-20px">
                {loading || !quote ? "..." : quote.quote}
              </Text>
            </Box>
          </Flex>
        </Box>
        <Box>
          <Text fontSize="xl" align="right" color={color}>
            -{loading || !quote ? "..." : quote.author}
          </Text>
        </Box>

        <HStack mt="2%" ml="1%" spacing="2%">
          <Button color={color} size="sm" onClick={onQuoteChange}>
            New Quote
          </Button>

          <Button
            as={Link}
            color={color}
            size="sm"
            leftIcon={<FaTwitter />}
            target="_blank"
            href={randomTweet(quote)}
          >
            Tweet now!
          </Button>
        </HStack>
      </Box>
    </Box>
  );
};

function App() {
  return (
    <ChakraProvider>
      <QuoteBox />
    </ChakraProvider>
  );
}

export default App;

How to do the animation?

Upvotes: 2

Views: 12685

Answers (1)

Amaresh S M
Amaresh S M

Reputation: 3010

Working demo

Add transition="0.8s linear" property to the root element(box) to make color transition smoother.

  <Box
      bg={color}
      h="100%"
      display="flex"
      flexDir="column"
      justifyContent="center"
      transition="0.8s linear">
   </Box>

Add show and hide classname based on the opacity state className={ opacity ? "show" : "hide"}.

  <Box 
      className={ opacity ? "show" : "hide"}
      >
      <Flex>
        <Box>
          <Icon as={FaQuoteLeft} w={7} h={6} color={color} />
          <Text fontSize="2xl" color={color} pl={8} mt="-20px">
          -{quote.quote}
          </Text>
        </Box>
      </Flex>
    </Box>
    <Box>
      <Text   className={ opacity ? "show" : "hide"} fontSize="xl" align="right" color={color}>
        -{quote.author}
      </Text>
    </Box>

Add the below-given styles to apply animation based on opacity state:

.hide {
  -webkit-animation: fadeinout .3s linear forwards;
  animation: fadeinout .3s linear forwards;
}

@-webkit-keyframes fadeinout {
  0% { opacity: 0.6; }
  50% { opacity: 0.2; }
  100% { opacity: 0; }
}

@keyframes fadeinout {
  0% { opacity: 0.6; }
  50% { opacity: 0.2; }
  100% { opacity: 0; }
}

.show {
  -webkit-animation: display .5s linear forwards;
  animation: display .5s linear forwards;
}


@-webkit-keyframes display {
  0% { opacity: 0.2; }
  50% { opacity: 0.6; }
  100% { opacity: 1; }
}

@keyframes display {
  0% { opacity: 0.2; }
  50% { opacity: 0.6; }
  100% { opacity: 1; }
}

you can also adjust transition time based on your requirements.

Upvotes: 5

Related Questions