This is the sixth day of my participation in the Novembermore Challenge.The final text challenge in 2021
introduce
Singles’ Day is coming, I don’t know if you have done shopping mall projects, most of which are boring and rigid adding and subtracted quantities, with strong homogeneity. Let’s make a React component for shopping cards in this issue, so as to add some user experience. Of course, this article is for beginners and creative flow, technical experts please take a detour.
First kangkang we finished the effect:
As we can see, every time you click add or subtract the number, there will be a dynamic effect that produces a total sum. When you return to 0, reduce again, the number of 0 will magnify and remind the user that I am already 0, do not subtract further. In this way, although there is no hint, just through animation does not express to the user. So let’s start implementing it.
The body of the
1. Basic logic
React Hook react Hook
import './style.scss';
import { useState, useEffect, useRef } from "react"
function BuyCard(props) {
const { src, price } = props;
const [num, setNum] = useState(0);
const [total, setTotal] = useState(0);
const totalRef = useRef(null);
const amountRef = useRef(null)
useEffect(() => {
setTotal(num * price)
}, [num, price])
function handleAdd() {
setNum(num + 1)
}
function handleMinus() {
setNum(num - 1)
}
return (
<div className="buy-card">
<img src={src} alt="" />
<div className="buy-info">
<div className="buy-title"><label>PRICE:</label><span>$</span><span>{price}</span></div>
<div className="buy-title"><label>TOTAL:</label><span>$</span><span ref={totalRef}>{total}</span></div>
<div className="btns">
<button className="minus btn" onClick={handleMinus}>-</button>
<p className="amount"><span ref={amountRef}>{num}</span></p>
<button className="add btn" onClick={handleAdd}>+</button>
</div>
</div>
</div>
);
}
export default BuyCard;
Copy the code
We expect to import pictures and prices from the outside world. If it is really development, there should be quantity and other information. This time, we will not expose the quantity to facilitate the viewing effect. Click plus or minus to change the quantity, and the change will change the total price by useEffect execution.
Of course, we can’t see it yet, but we need to write some styles, very simple card styles, so I won’t go into details here:
.buy-card{
width: 200px;
height: 300px;
background-color: #ffffff;
box-sizing: border-box;
box-shadow: 1px 1px 10px rgba(0.0.0.1);
border-radius: 5px;
border: 2px dashed #c33;
padding-top: 10px;
transition:.2s all;
&:hover{
box-shadow: 1px 1px 12px rgba(0.0.0.3); } & >img{
width: 150px;
height: 150px;
display: block;
margin: 0 auto;
}
.btns{
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
.btn{
border: 0;
cursor: pointer;
border-radius: 50%;
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
color: white;
&.add{
background-color: rgb(118.201.98);
}
&.minus{
background-color: rgb(233.93.88); }}.amount{
width: 50px;
text-align: center;
height: 24px;
line-height: 24px;
border-bottom: 1px solid rgb(73.73.72);
margin: 0 10px;
span{
font-size: 18px;
font-weight: bold;
width: 100%;
height: 24px;
display: block;
line-height: 24px; }}}.buy-info{
width:100%;
box-sizing: border-box;
padding: 15px;
font-family: 'Courier New', Courier, monospace;
.buy-title{
margin-bottom: 13px;
font-size: 16px;
font-weight: bold;
height: 24px;
line-height: 24px;
border-bottom: 1px solid rgb(73.73.72);
label{
margin-right: 5px; }}}}Copy the code
Now we can reference it in app.js and see the style.
import BuyCard from "./components/buyCard"
const f0 = require("./assets/food0.png")
function App() {
return (
<div className="App">
<div className="cards">
<BuyCard price="100" src={f0.default} />
</div>
</div>
);
}
Copy the code
2. Cumulative and touch zero animation
We have many solutions to realize these two animations. Today, we will take animejs as the best solution. Animejs can realize various web animations freely and smoothly. Now let’s use it for the effect.
import anime from "animejs"
function BuyCard(props) {
// ...
useEffect(() => {
anime({
targets: totalRef.current,
textContent: [total, num * price],
round: 1,
easing: 'easeOutCirc',
duration: 300,
complete() {
setTotal(num * price)
}
});
}, [num, price])
// ...
}
Copy the code
This is the cumulative animation. After you get the DOM element that you want to change, let it change it in textContent. You can set the slow, period, etc., but remember that in React, you don’t just change it like you would normally do with a DOM. In React, you can change the total value. Otherwise, you will not get the value in React, and you will start animation from 0 every time.
function handleMinus() { if(num===0){ return anime({ targets: amountRef.current, easing: 'linear', duration: 400, scale: [{value: 1.6}, {value: 1}]}); } setNum(num - 1) }Copy the code
The following zero animation is much easier. We block it every time the number reaches zero if it decreases further, and use animejs to change the scale property to a smaller animation to indicate that the number cannot be negative.
That’s all I have to say, isn’t it easy to do online demos.
conclusion
React Hook is a combination of Animejs, react Hook and Animejs. Even a small card can add a lot of things, such as add and subtract to zero sound trigger, add some fun animations to products, and many other extensions. Wait for you to play ~