在react中,函数组件实现外卖点餐小球动画效果展示

第一步:获取小球要飞的盒子中

//获取小求要飞到那个盒子中
    const BOX = useRef();
    const GetBox =()=>BOX.current

定义的盒子

  <div className='footer'  ref={BOX}>
       <div className='six' >
           <Badge content={count1}>
               <Bill/>
           </Badge>
           ¥{num}.0<span className='span1'>配送费¥3.2</span>
       </div>
       <div className='menu' onClick={() => {
            navigate('/app/account')
        }}>去下单</div>
 </div>

第二步:创建小球 这里的创建小球函数接收两个参数 分别为 当我们点击添加按钮时候的X和Y轴坐标

 let createBall = (left,top)=>{

        let Ball = document.createElement('div');

        Ball.style.position         = 'absolute';
        Ball.style.left             = left + 'px';
        Ball.style.top              = (top-10) + 'px';
        Ball.style.width            = '20px';
        Ball.style.height           = '20px';
        Ball.style.borderRadius     = '50%';
        Ball.style.backgroundColor  = 'red';

        Ball.style.transition = 'left .6s linear,top .6s cubic-bezier(0.5,-0.5,1,1)';
        document.body.appendChild(Ball);

        setTimeout(()=>{
            Ball.style.left = GetBox().offsetLeft + GetBox().offsetWidth / 2 + 'px';
            Ball.style.top = GetBox().offsetTop + "px";
        },0)

        Ball.ontransitionend = function(){
            Ball.remove();
        }
        

    }
    
  

第三步:在添加方法中 我们传递一个ev事件对象 然后通过这个ev事件对象获取到当前点击的X轴Y轴坐标的值 并且传递给我们的创建小球函

 const Add = (e)=>{
        let x = e.clientX
        let y = e.clientY
        createBall(x,y)
    }

第五步:在点击的按钮调用这个add函数

<span onClick={(e)=>{
        Add(e)
        }}>¥{item.price}/份
        <Stepper 
             min={0}
             value={item.num}
             onChange={v => {
             let { data } = axios.put("/updatemenu", { _id: item._id, num: v })
                        getArr()
                        setValue9(v)
                        setPrice(item.price)
                 }} />
</span>

最后就OK了

总的代码如下:

import React, { useState, useEffect, useRef, useMemo } from 'react'
import { Bill } from '@react-vant/icons';
import { Sidebar, Stepper, Badge } from 'react-vant';
import { useNavigate } from 'react-router-dom';
import './Menu.scss';

import axios from 'axios';

axios.defaults.baseURL = 'http://locahost:3000';

export default function Menu() {
    //获取小求要飞到那个盒子中
    const BOX = useRef();
    const GetBox =()=>BOX.current

     
    let createBall = (left,top)=>{

        let Ball = document.createElement('div');

        Ball.style.position         = 'absolute';
        Ball.style.left             = left + 'px';
        Ball.style.top              = (top-10) + 'px';
        Ball.style.width            = '20px';
        Ball.style.height           = '20px';
        Ball.style.borderRadius     = '50%';
        Ball.style.backgroundColor  = 'red';

        Ball.style.transition = 'left .6s linear,top .6s cubic-bezier(0.5,-0.5,1,1)';
        document.body.appendChild(Ball);

        setTimeout(()=>{
            Ball.style.left = GetBox().offsetLeft + GetBox().offsetWidth / 2 + 'px';
            Ball.style.top = GetBox().offsetTop + "px";
        },0)

        Ball.ontransitionend = function(){
            Ball.remove();
        }
        

    }
    
    const Add = (e)=>{
        let x = e.clientX
        let y = e.clientY
        createBall(x,y)
    }

    const [active, setActive] = useState('660a5bf3dd5d7cc8b83b08e5');
    const navigate = useNavigate()
    const [value9, setValue9] = useState(0)
    const [price, setPrice] = useState(0)
    const [arr, setArr] = useState([])
    const [type, setType] = useState([])
    let num = useMemo(() => {
        let nums = 0
        return arr.reduce((a, item) => {
            return nums += item.num * item.price
        }, 0)
    }, [arr])

    let count1 = useMemo(()=>{
        return arr.reduce((a,item)=>{
            return a += item.num
        },0)
    },[arr])
    useEffect(() => {
        getArr()
        getType()
    }, [])


    let getArr = async () => {
        let { data } = await axios.get('/listmenu')
        setArr(data.menus)
    }
    let getType = async () => {
        let { data } = await axios.get('/listtype')
        setType(data.types)
    }

    return (
        <div id='nav'>
            <div>
                <div className='top1'> 外卖点餐</div>
                <div className='content'>
                    <div>
                        <b>徐先生私房菜(天河店)</b>
                        距离1.0km</div>
                    <div>
                        <button className='btn1'>堂食</button>
                        <button className='btn2'>外卖</button>
                    </div>

                </div>
            </div>
            <div className='menu-sidebar'>
                <Sidebar>
                    {
                        type.map(item =>
                            <Sidebar.Item contentStyle={{ backgroundColor: '#fff' }}
                                onClick={() => {
                                    setActive(item._id)
                                }} key={item._id} title={item.name}>
                                {
                                    arr.filter(item => item.cid === active).map(item =>
                                        <div key={item._id} className='box1'>
                                            <div>
                                                <img src={item.img} alt="" className='img1' />
                                            </div>
                                            <div className='right' >
                                                <b>{item.title}</b>
                                                <b className='org'>4.5折</b>
                                                <span onClick={(e)=>{
                                                    Add(e)
                                                        }}>¥{item.price}/份
                                                   <Stepper 
                                                        min={0}
                                                        value={item.num}
                                                        onChange={v => {
                                                            let { data } = axios.put("/updatemenu", { _id: item._id, num: v })
                                                            getArr()
                                                            setValue9(v)
                                                            setPrice(item.price)
                                                        }}
                                                        
                                                    />
                                                </span>
                                            </div>
                                        </div>)
                                }
                            </Sidebar.Item>
                        )}
                </Sidebar>
            </div>
            <div className='footer'  ref={BOX}>
                <div className='six' >
                    <Badge content={count1}>
                       <Bill/>
                    </Badge>
                    ¥{num}.0<span className='span1'>配送费¥3.2</span>
                </div>
                <div className='menu' onClick={() => {
                    navigate('/app/account')
                }}>去下单</div>
            </div>
        </div>
    )
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值