PK creative Spring Festival, I am participating in the “Spring Festival creative submission contest”, please see: Spring Festival creative submission Contest

What I remember most about the Spring Festival is fortune-telling. When I was a child, my father would take an old calendar and use some copper money to tell the fortune of my family. Throw copper coins and then check the old calendar, anyway, no matter how to calculate, give us a good fortune, what the future is boundless, life wealth. At first I still feel very magical, believe it, once told my sister that my life, my father heard me said, don’t be superstitious, you still have to study hard.

No, now I only believe in science. But sometimes I recall the warm yellow light bulb when I was a child, and the family gathered around the table chatting, throwing copper coins and looking up the old calendar.

This year, because of the epidemic, and can not go back home for the Spring Festival, many people like me, let’s try to use the code to achieve fortune telling.

In addition, this project can also be used as a beginner’s guide to build a React project from 0, as well as learn how to animate, function components and hooks.

First take a look at the finished product, experience link:

Create a project

npx create-react-app goodluck
cd goodluck
yarn dev
Copy the code

This command requires the node environment to support, and the version requires 14+, so if you are prompted to update the version, you can use n: NPM install -g n

Install node specified version: n stable

background

To create a hot background image, write a className style centered in the center for future use. I wrote the following in index.css:

html.body {
  height: 100%;
}
body {
  background-image: url(".. /public/imgs/fu.png");
  background-size: contain;
}

.center {
  display: flex;
  align-items: center;
  justify-content: center;
}
Copy the code

Coin rotation effect

To detect luck, we first to realize the COINS turn a animation, first come first two pictures on both sides of the coin (of course I did not find the same size as completely, so I went online to find first two basically can be used, but they are of different size, not the PNG, so I started to ps, myself behind the use of a lot of pictures, is a net figure + ps, If you don’t know how to photoshop, you can go to Github and directly use my pictures, or leave a comment 1, I can post a basic photoshop tutorial.

I set up five copper coins to achieve the rotation effect, and each copper coin rotates once for 0.5s, with infinite rotation:

      <div className="canvas">
        {[0.1.2.3.4].map((item, index) = > (
          <div key={index} className={classnames("coin-rotate","coin")} >
            <div className={classnames("coin0")} ></div>
            <div className={classnames("coin1")} ></div>
          </div>
        ))}
      </div>
Copy the code

The CSS implementation of rotation is a bit more complicated, but the core is the rotation of two divs, the detailed CSS code is as follows:

.canvas {
  display: flex;
  justify-content: space-around;
}

.coin {
  position: relative;
  width: 100px;
  height: 100px;
}

.coin:hover {
  animation-play-state: paused;
}

.coin-rotate {
  transform-style: preserve-3d;
  animation: rotate 0.5s infinite linear;
  -webkit-transform-origin: center center;
  -ms-transform-origin: center center;
  transform-origin: center center;
}

@keyframes rotate {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}

.coin0,
.coin1 {
  position: absolute;
  left: 0px;
  top: 0px;
  width: inherit;
  height: inherit;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
.coin0 {
  transform: translateZ(1px);
  background-image: url(".. /public/imgs/coin0.png");
}
.coin1 {
  background-image: url(".. /public/imgs/coin1.png");
}
Copy the code

If you are not familiar with CSS, or are not familiar with certain properties, I recommend beginner tutorials with detailed animations and descriptions of different CSS effects.

Gets the copper status

We just set the infinite rotation of copper coins, which must stop, and each coin has its own head and tail. In this case, we need to define the copper money state. For example, I set a global variable defaultState:

const defaultState = {
  // If loading is true, copper money is spinning
  loading: false.// Array with length 5 and default value 0 (0 for tails and 1 for heads)
  data: new Array(5).fill(0),
  luck: {
    // The result of fortune telling
    destiny: "".// A class array that marks different animation effects for different fates. The code is defined in index.css
    classNames: [].// Head diagram, such as leopard
    banner: "",}};Copy the code

Here we first need to get the state of the copper coin. Here I call getLuckNum several times, which randomly gets 0 and 1:

// Get the heads and tails of five copper coins, of course, is a random number, what do you think
export function getLuckNum() {
  return Math.round(Math.random());
}
Copy the code

Here we get the result of fate as follows:

  const getLuck = () = > {
    letnewState = { ... defaultState };if (state.loading) {
      newState.loading = false;
      // Get the two sides of five copper coins
      for (let i = 0; i < 5; i++) {
        newState.data[i] = getLuckNum();
      }
      newState.luck = getGoodLuck(wish);
    } else {
      newState.loading = true;
    }
    setState(newState);
  };
Copy the code

Ok, all the preparations are ready and it’s time for the App component to appear: First, the fateful Button:

<button onClick={getLuck}>
    {state.loading ? "View results" : "Check your horoscope"}
</button>
Copy the code

Then there is the component that displays the fate result:

      <div className="canvas">
        {state.data.map((item, index) = > (
          <div
            key={index}
            className={classnames(state.loading&&. ""coin-rotate","coin")}
          >
            <div
              className={classnames(
                "coin0"!state.loading && item= = =1&&. ""hide")} ></div>
            <div
              className={classnames(
                "coin1"!state.loading && item= = =0&&. ""hide")} ></div>
          </div>))} </div> {state.luck? .classNames ! ="" && !state.loading && (
        <div className={classnames("luck-bg center", state.luck?.mainStyle)} >{state.luck? .classNames && state.luck? .classNames.map((item, index) => (<div
                key={index}
                className={classnames("luck", item,"center")}
              ></div>
            ))}

          <div
            className={classnames(state.luck.banner, "banner","center")}
          ></div>
          <div className="blessing center">{state.luck? .destiny}</div>
      )}
    </div>
  );
}

Copy the code

Say what you want

In the previous step, you may have noticed that getGoodLuck takes the wish parameter, meaning the user can enter a wish. Fortune-telling, even if you are to go to the temple, others will ask you is for the future or for marriage, I was the college entrance examination, my mother went to the temple to calculate for me, for the college entrance examination, the result I was admitted. Haha, fortune-telling is sometimes useful as a psychological comfort, although I didn’t know it until after the college entrance examination.

Next, write an input box and ask the user to enter their request, such as “suddenly rich”, and then click button to start flipping coins. Of course, we need to make the input box a controlled component. First, define the state wish:

  const [wish, setWish] = useState("");
Copy the code

Of course, state is defined by Hook. If you and Eric also have a leader who insists on not using function components and hooks, take advantage of the New Year, quickly change.

<input
    className="name"
    type="text"
    value={name}
    placeholder="Say what you wish for."
    onChange={(e) = > {
      setName(e.target.value);
    }}
    onKeyUp={(e) = > {
      if (e.keyCode === 13) {
        getLuck();
      }
    }}
  />
Copy the code

If you’re curious about how to give a result based on your wishes, I actually have a big JSON file that you can search for data in. It’s like a fortune teller’s brain bank. There are too many specific codes, I will not post all of them. If you want to see the full set of codes, you can click the link at the end of this article to see github.

rich

Ok, so far, has been able to see the effect, in order to allow users to tell fortunes many times, I added a button to restart, of course, this and refresh the page is the same effect ~

Enter sudden wealth and see what happens ~

Of course, you can also try other inputs, such as single, skinny, promotion, etc

In addition to fortune-telling, this program can also be used as an introduction to React

Code address Experience address

Knowledge summary

In addition to the entertainment of fortune-telling, the knowledge of this project is as follows:

  1. Js basics, such as arrays, strings, regular matches, etc
  2. animation
  3. Equalize random numbers
  4. Hook the state use
  5. Configure less in the Create React app
  6. , etc.

Among them, the fifth is actually not related to this project, you can not configure ~