zillow / react-slider

Accessible, CSS agnostic, slider component for React.
https://zillow.github.io/react-slider
MIT License
892 stars 231 forks source link

Scaling function #40

Closed dmitry closed 5 years ago

dmitry commented 9 years ago

It would be nice to have scaling function, like in this project: https://github.com/seatgeek/react-slider

I would go with the similar interface as https://github.com/seatgeek/react-slider has:

scalingFunction

A function that takes two arguments, the first representing the x-position of the slider and the second the width of the slider. Use this to control the mapping of the domain of numbers the slider represents onto the range of pixel locations of the slider. By default, this is set to the non-linear

function(x, constantBase) {
    return Math.pow(x, 2) / Math.pow(constantBase, 2);
}

and

inverseScalingFunction

A function that should be the inverse of the operation of the scalingFunction. By default, it is set to:

function(x, constantBase) {
    return Math.sqrt(x) / Math.sqrt(constantBase);
}
raulmatei commented 9 years ago

+1

LoicUV commented 9 years ago

+1 has any of you come up with a solution since june @dmitry @raulmatei ?

dmitry commented 9 years ago

@alexmugford how does this related to the #40?

alexmugford commented 9 years ago

@dmitry sorry, misunderstood the scaling being requested!

mauricesvay commented 9 years ago

:+1:

joshwcomeau commented 8 years ago

Is this something that the authors would be willing to accept a PR for? I'd happily implement the scaling function if it's something the authors would like to have in their project.

lukashlavacka commented 8 years ago

I have implemented something similar to this using the existing code. I achieved it by separating the internal value and display value. I wanted to implement exponential scaling. So lets imagine I want only to have values 1, 2, 4, 8, ..., 1024. In this case I would hold in state the "internal" value (0, ..., 10) and calculate the rest on the fly:

var ExpSlider = React.createFactory(React.createClass({
    transformFromUI(value){
        return Math.pow(2, value)
    },
    transformToUI(value){
        return Math.log(value) / Math.log(2)
    },
    handleChange(value) {
        this.setState({
            value: value
        })

        this.props.handleChange(this.transformFromUI(value));
    },
    getInitialState() {
        return {
            value: this.tranformToUI(this.props.min)
        }
    },
    getDefaultProps(){
        min: 1,
        max: 1024,
        value: 1
    },
    componentWillReceiveProps(nextProps){
        this.setState({ value: this.transformToUI(nextProps.value) })
    },
    render() {
        return (
            <ReactSlider
                value={this.state.value}
                min={this.tranformToUI(this.props.min)}
                max={this.tranformToUI(this.props.max)}
                onChange={this.handleChange}
            >
                <div>{this.tranformToUI(this.state.value)}</div>
            </ReactSlider>
        );
    }
}))

With this approach you can create slider with 100 values between 0.0 and 1.0 just by dividing and multiplying by 100 and using Math.floor or similar scaling and step you want.

Please excuse any issues as I did not have time to to create an example. But something similar works quite well in my code.

stevenpetryk commented 8 years ago

I agree with @lukashlavacka's solution. A scaling function doesn't really need to be present in this plugin since you can just calculate that elsewhere.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.