基于react hook的红包雨动画

文章目录

  • 前言
  • 一、html
  • 二、css
  • 三、ts
  • 实现效果


前言

红包雨动画,下面的盒子不断移动接住红包


提示:以下是本篇文章正文内容,下面案例可供参考

一、html

 
div>
div> div>

二、css

.wrap,
.box {
     
    position : relative;
    width    : 100vw;
    max-width: 480px;
    height   : 100vh;
}

.box img {
     
    display : block;
    position: absolute;
}

.drops {
     
    animation: drops 1.5s ease-in both;
}

@keyframes drops {
     
    from {
     
        top    : -10vh;
        opacity: 0;
    }

    20% {
     
        opacity: 1;
    }

    85% {
     
        opacity: 1;
    }

    to {
     
        opacity: 0;
        top    : 100vh;
    }
}

.foot {
     
    position: absolute;
    width   : 100%;
    bottom  : 0;
    left    : 0;
    overflow: hidden;
}

.bj {
     
    position: absolute;
    left    : 0;
    bottom  : 0;
    width   : 100%;
}

.redPacket {
     
    position  : relative;
    bottom    : 0;
    left      : 0;
    width     : 60%;
    height    : 50px;
    transition: left .2s linear;
}

三、ts

    const boxRef: any = useRef(null);
    const redRef: any = useRef(null);
    let timer1: any;
    let timer2: any;
    const [left, setLeft] = useState<number>(0);

    useEffect(() => {
     
        init(0);
        return () => {
     
             clearTimeout(timer1);
             clearTimeout(timer2);
        }
    }, []);

    const createRandomNum = (minNum: number, maxNum: number) => {
     
        return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum);
    }
    
    const init = useCallback(
        (num: number) => {
     
            if (boxRef && boxRef.current && redRef && redRef.current) {
     
                const box = boxRef.current;
                const red = redRef.current;
                const is_HB = num % 5 === 0;
                const ranWidth = is_HB ? 60 : createRandomNum(30, 40); //此随机数用来设置红包的宽度。
                const ranLeft = createRandomNum(0, box.offsetWidth - ranWidth); //用来设置红包的left值。
                const ranRotate = createRandomNum(-45, 45); //设置红包的rotate值。
                const img = document.createElement('img');

                let turnLeft = ranLeft - (red.offsetWidth / 3);//底部盆子的位移距离
                //位移不超出盒子边界
                turnLeft < 0 && (turnLeft = 0);
                turnLeft > (box.offsetWidth - red.offsetWidth) && (turnLeft = (box.offsetWidth - red.offsetWidth));

                img.style.left = `${
       ranLeft}px`;
                img.style.width = `${
       ranWidth}px`;
                img.style.transform = `rotate(${
       ranRotate}deg)`;
                img.src = createRandomNum(0, 1) === 0 ? Hb1 : Hb2;
                box.appendChild(img);
                img.classList.add(style["drops"]);
                let det = timer2 = setTimeout(() => {
     //动画结束后删除节点
                    clearTimeout(det);
                    box.removeChild(img);
                }, 2000);
                let timer = timer1 = setTimeout(() => {
      clearTimeout(timer); is_HB && setLeft(turnLeft); init(num + 1); }, 10);
            }
        },
        [],
    )

实现效果

你可能感兴趣的:(css3,animation,react)