react数字滚动-兼容特殊字符

90 阅读1分钟

image.png

类似这种效果

import React, { PureComponent } from 'react';
import style from './NumberScroller.scss';

// 枚举数字
const numList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// 正则剔除非数字
const digitRegexp = /\d/;

class NumberScroller extends PureComponent {
    constructor(props) {
        super(props);
    }
    state = {
        transformY: 0,
    }
    componentDidMount() {
        const numberWrapper = document.getElementById('number-wrapper');
        if (numberWrapper) {
            this.setState({
                transformY: numberWrapper.getBoundingClientRect().height
            });
        }
    }

    render() {
        const { numberString } = this.props;
        const { transformY } = this.state;
        const unitNumList = numberString.toString().split('');

        return <div className={style['number-scroller']}
                    id="number-wrapper">
            {unitNumList.map((stringItem, index) => (
                <div
                    key={index}
                    className={style[digitRegexp.test(stringItem) ? 'number-wrapper' : 'space-wrapper']}
                >
                    {/* 展示数字 */}
                    {digitRegexp.test(stringItem)
                        && <span
                            className={style.list}
                            style={{
                                transform: `translate(-50%, -${Number(stringItem) * transformY}px)`,
                                transitionDelay: `${index * 150}ms`
                            }}>
                            {numList.map((num, i) => {
                                return (<span key={i * 10 + 1} className={style.item}>
                                    {num}
                                </span>);
                            })}
                        </span>
                    }
                    {/* 展示其它字符 */ }
                    {!digitRegexp.test(stringItem)
                        && <span className={style.item}>
                            {stringItem}
                        </span>
                    }
                </div>
            ))}
        </div>;
    }
}

export default NumberScroller;

样式

.number-scroller {
    position: relative;
    display: flex;
    align-items: center;
    transform: translateY(8px);
    .space-wrapper,
    .number-wrapper {
        position: relative;
        width: 30px;
        height: 48px;
        padding: 10px 0;
        // box-sizing: border-box;
        line-height: 48px;
        text-align: center;
        overflow: hidden;
        .list {
            position: absolute;
            top: 0;
            left: 50%;
            // transform: translateX(-50%);
            display: flex;
            flex-direction: column;
            align-items: center;
            transform: translate(-50%, 0);
            transition: transform 0.5s;
        }
        .item {
            display: inline-block;
            width: 30px;
            height: 48px;
            padding: 10px 0;
            // box-sizing: border-box;
            font-size: 48px;
            font-weight: bold;
            color: #ffffff;
        }
    }
    .space-wrapper {
        width: 14px;
        transform: translate(0, -7px);
        .item {
            width: 14px;
        }
    }
}

简单粗暴,不懂可以私信