【react】实现一个动画增长的函数,并封装成简易组件

效果图如下:
在这里插入图片描述
js有很多库都可以做到,当然最简单的还是自己写一个,体积最小,使用最灵活。

下面是用ts写的方法以及组件

countUp.ts

/** 数字增长动画 */

/**
 * @param {DOM} dom 要渲染的dom节点
 * @param {number} start 数字初始值 默认为0
 * @param {number} target 数字目标值
 * @param {number} delay 在多少ms内增长至目标值,默认1000ms,不少于200ms
 */

export const countsUp = (dom: HTMLElement, start = 0, target: number, delay = 1000) => {

    if (delay < 200) {
        throw new Error('The renderer timing of transition animition must be greater than 200 ms.');
    }

    // 默认多少ms内增长一次
    const defaultStepTime = 50;
    // 总共需要多少次增长能达到目标值
    const defaultSteps = Math.ceil(delay / defaultStepTime);
    // 每次应该增长的值
    const stepCount = (target - start) / defaultSteps;

    // 计算target的小数位数,初始为0,即默认没有小数位
    let precision = 0;
    // 如果target存在小数位 就计算出小数位,更新precision的值
    if (Math.ceil(target) !== Math.floor(target)) {
        const reg = /\.(.*)$/g;
        const lice = reg.exec(target + '');
        precision = lice[1].length;
    }
    
    let timer = 0;
    let currentCount = start;

    timer = window.setInterval(() => {
        currentCount += stepCount;
        if (currentCount >= target) {
            dom.innerHTML = target + '';
            clearInterval(timer);
            return;
        }
        // 数字增长时,保持和target同样的精度去计算
        // 防止出现0.1 + 0.2 = 0.30000000000001的情况
        // 因为它会造成DOM结构的混乱
        dom.innerHTML = currentCount.toFixed(precision);
    }, defaultStepTime)
}

简易组件CounterAnimation.tsx

import { countsUp } from '@/utils/countsUp';
import { FC, useRef, useEffect } from 'react';

type PropType = {
    target: number // 接收目标值
}

const CounterAnimation: FC<PropType> = (props: PropType) => {

    const { target } = props;
    const counterRef = useRef(null);

    useEffect(() => { 

		// 调用数字动画函数
        counterRef.current && countsUp(counterRef.current, 0, target);

        return () => {
            counterRef.current = null;
        }
    }, [])

    return <span ref={counterRef}></span>
}

export default CounterAnimation;

哪里需要用到就把组件引入,然后传入目标值target即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值