Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculated values #41

Open
savelichalex opened this issue Jun 28, 2016 · 3 comments
Open

Calculated values #41

savelichalex opened this issue Jun 28, 2016 · 3 comments

Comments

@savelichalex
Copy link

savelichalex commented Jun 28, 2016

What are you guys thinking about calculated values? Something like Behaviors in FRP terms or spreadsheet-like dataflow.

Main question is why do we need them?

Ok - let's explain we have transitions between scenes, and main value for all transition is progress - this is value changed by time for 0 to 1. In scene we want to change text opacity and some position.

const Scene = (width, height, progress) =>
    <View style={{position: "absolute",
                           height: height,
                           width: width,
                           backgroundColor "blue"}}
        <Text style={{fontSize: 16,
                      opacity: progress < 0.5 ? (1 - (progress * 2)) : 0,
                      marginLeft: progress < 0.5 ? (progress * 2 * 250 * -1) : 0}} />
    </View>

But I want to use calculated values, smth like this:

class AnimatedCell {
    constructor() {
        this._subscribers = [];
    }

    push(value) {
       this._subscribers.forEach(next => next.call(null, value));
    }

    subscribe(next) {
       this._subscribers.push(next);
    }
}

const bind = (cell, fn) => {
    const newCell = new AnimatedCell();
    cell.subscribe(val => newCell.push(fn.call(null, val))
}

const bindToAnimated = (cell, initialValue) =>
    const newAnimated = new AnimatedValue(initialValue || 0);
    cell.subscribe(val => newAnimated.setValue(val));
    return newAnimated;
}

And use it in scene:

const Scene = (width, height, progress) => {
    const opacity = bind(progress, progress => progress < 0.5 ? (1 - (progress * 2)) : 0);
    const marginLeft = bind(progress, progress => progress < 0.5 ? (progress * 2 * 250 * -1) : 0);
    return (
    <View style={{position: "absolute",
                           height: height,
                           width: width,
                           backgroundColor "blue"}}
        <Text style={{fontSize: 16,
                          opacity: bindToAnimated(opacity, 1),
                          marginLeft: bindToAnimated(marginLeft, 0)}} />
    </View>
    );
}

Every time when progress is changed, opacity and margin-left recalculated and refresh Animated.
What do you think?

@savelichalex
Copy link
Author

If you guys familiar with ClojureScript you can see it in action on my experiment with react native navigation https://github.com/savelichalex/experiment-navigation-react-native/tree/cell-proposal

@gre
Copy link
Contributor

gre commented Jun 28, 2016

I also think being able to implement this bind() make Animated more powerful and interesting (myself, I prefer to call it map() but whatever). Also allow to extend Animated in third party library.

I remember we had a discussion here in the past: animatedjs/interactive-docs#5

is this ~ the same topic or am I out of subject?

I think the main problem we evoked, is that it is hard for React Native to implement Animations in an another thread (like in ObjC / Java side) if animated object are not serializable, which is the case when you use newValue = bind(value, aJSFunction) .

@savelichalex
Copy link
Author

Yeah, this is possible to extend in third party library, but maybe we can create smth interesting if it'll be in core. I'm trying to say, that we also can extend behavior of few core methods. For example if Animated.timing get computed value, then they just push on it and update all dependent values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants