dearfrankg / react-odometer

react-odometer React component
8 stars 6 forks source link

Digits option, support for non numeric characters and animation type #1

Open petertenhoor opened 7 years ago

petertenhoor commented 7 years ago

Hi there.

I'm currently building a React application which uses multiple odometers with dynamic values. I have given your package a shot but ran into a few issues:

Besides those issues, I really like the way you have written this component. The performance is great and it's the only Odometer out there that works with serverside rendering.

I'd like to hear your opinion!

dearfrankg commented 7 years ago

Hello, regarding your points:

1) It could auto detect the starting number but if that number is 5 how many digits should the odometer contain? That's why you need to tell it.

2) that sounds like a nice option

3) that sounds like a nice option

I'll see what I can do.

petertenhoor commented 7 years ago

Nice to hear that you're planning to update the repository!

Meanwhile i've done some customizations to make the react-odometer work within my project. I still need to refactor it but perhaps you can use some parts of it:

Odometer.js:

import React from 'react'
import {number, string} from "prop-types";

import Digit from './Digit'

const Odometer = ({number, speed = 500, size = 72, seperatorSteps = 3, seperatorCharacter = ','}) => {

    //remove minus sign
    let chars = number.toString().replace('-', '')

    //cast chars to array of chars
    chars = chars.split('')

    const odometerStyle = {
        fontSize: `${size}px`,
        lineHeight: `${size}px`,
        display: "inline-block"
    }

    const seperatorStyle = {
        display: "block",
        float: "left"
    }

    const odometerContainerStyle = {
        display: "inline-block",
        position: "relative"
    }

    return (
        <div style={odometerStyle}>

            {chars.map((digit, i) => {
                //create empty array to save seperator indexes in
                const seperatorIndexes = []

                //get total amount of digits
                const digitLength = chars.length

                //calculate amount of needed seperators
                const amountOfNeededSeperators = (digitLength / seperatorSteps)

                //push seperator indexes into array
                for (let i = 0; i < amountOfNeededSeperators; i++) {
                    seperatorIndexes.push(digitLength - (seperatorSteps * i))
                }

                if (seperatorIndexes.indexOf(i) > -1 && i !== digitLength - 1) {
                    //return digit with seperator
                    return (
                        <div style={odometerContainerStyle} key={i}>
                            <span style={seperatorStyle}>{seperatorCharacter}</span>
                            <Digit size={size} digit={digit} speed={speed}/>
                        </div>
                    )
                } else {
                    //return digit without seperator
                    return (
                        <div style={odometerContainerStyle} key={i}>
                            <Digit size={size} digit={digit} speed={speed}/>
                        </div>
                    )
                }
            })}

        </div>
    )
}

Odometer.propTypes = {
    number: number.isRequired,
    seperatorSteps: number,
    speed: number,
    size: number,
    seperatorCharacter: string
}

export default Odometer

Digit.js:


import React from "react"
import {number, string} from "prop-types";

const Digit = ({digit, speed, size}) => {

    const digitContainerStyle = {
        height: `${size}px`,
        display: "inline-block",
        width: `${size / 1.8}px`,
        overflow: "hidden"
    }

    const digitStyle = {
        animationName: `slide${digit}`,
        transform: `translateY(-${digit}em)`,
        transition: `transform ${speed}ms cubic-bezier(0, 0, 0.2, 1)`
    }

    return (
        <div style={digitContainerStyle}>
            <div style={digitStyle}>
                0 1 2 3 4 5 6 7 8 9 0
            </div>
        </div>
    )
}

Digit.propTypes = {
    digit: string.isRequired,
    speed: number.isRequired,
    size: number.isRequired
}

export default Digit

Example usage in react component:

<Odometer number={5000000} size={100} seperatorSteps={3} seperatorCharacter=","/>