{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/react-native/issues/2045","labels_url":"https://api.github.com/repos/facebook/react-native/issues/2045/labels{/name}","comments_url":"https://api.github.com/repos/facebook/react-native/issues/2045/comments","events_url":"https://api.github.com/repos/facebook/react-native/issues/2045/events","html_url":"https://github.com/facebook/react-native/pull/2045","id":95879342,"number":2045,"title":"Add `Animated.Formula` class to create values driven by multiple animated values ","user":{"login":"lelandrichardson","id":1885623,"avatar_url":"https://avatars.githubusercontent.com/u/1885623?v=3","gravatar_id":"","url":"https://api.github.com/users/lelandrichardson","html_url":"https://github.com/lelandrichardson","followers_url":"https://api.github.com/users/lelandrichardson/followers","following_url":"https://api.github.com/users/lelandrichardson/following{/other_user}","gists_url":"https://api.github.com/users/lelandrichardson/gists{/gist_id}","starred_url":"https://api.github.com/users/lelandrichardson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lelandrichardson/subscriptions","organizations_url":"https://api.github.com/users/lelandrichardson/orgs","repos_url":"https://api.github.com/users/lelandrichardson/repos","events_url":"https://api.github.com/users/lelandrichardson/events{/privacy}","received_events_url":"https://api.github.com/users/lelandrichardson/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/facebook/react-native/labels/CLA%20Signed","name":"CLA Signed","color":"e7e7e7"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2015-07-19T02:50:01Z","updated_at":"2015-12-09T19:21:42Z","closed_at":"2015-12-09T19:21:42Z","pull_request":{"url":"https://api.github.com/repos/facebook/react-native/pulls/2045","html_url":"https://github.com/facebook/react-native/pull/2045","diff_url":"https://github.com/facebook/react-native/pull/2045.diff","patch_url":"https://github.com/facebook/react-native/pull/2045.patch"},"body":"This PR exposes a new `Animated.Formula` constructor that creates a derived Animated value that can be driven by combinations of other animated values.\r\n\r\n`value.interpolate(...)` works really well for manipulated a single animated value arithmetically by constants, but it doesn't handle (as far as I know) combining multiple animated values together.\r\n\r\nFor example, if I wanted to animate based off of a \"distance\" calculation, that would involve two animated values that I would have to multiply in ways `.interpolate()` doesn't allow:\r\n\r\n```js\r\nvar distance = new Animated.Formula([x,y], (a,b) => Math.sqrt(a*a + b*b));\r\n```\r\n\r\nAn working example would be:\r\n\r\n\r\n```js\r\n/**\r\n * Sample React Native App\r\n * https://github.com/facebook/react-native\r\n */\r\n'use strict';\r\n\r\nvar React = require('react-native');\r\nvar {\r\n    AppRegistry,\r\n    StyleSheet,\r\n    View,\r\n    Animated,\r\n    PanResponder\r\n    } = React;\r\nvar Dimensions = require('Dimensions');\r\nvar Easing = require('Easing');\r\nvar Interpolation = require('Interpolation');\r\nvar { width, height } = Dimensions.get('window');\r\n\r\nvar AnimatedFormulaExample = React.createClass({\r\n\r\n    getInitialState() {\r\n        var x = new Animated.Value(0);\r\n        var y = new Animated.Value(0);\r\n        return {\r\n            x,\r\n            y,\r\n            distance: new Animated.Formula([x,y], (a,b) => Math.sqrt(a*a + b*b))\r\n        };\r\n    },\r\n\r\n    componentWillMount() {\r\n        this.responder = PanResponder.create({\r\n            onStartShouldSetPanResponder: () => true,\r\n            onMoveShouldSetPanResponder: () => true,\r\n            onPanResponderMove: Animated.event([null, { dx: this.state.x, dy: this.state.y }]),\r\n            onPanResponderRelease: (_, { vx, vy }) => {\r\n                var { x, y } = this.state;\r\n                Animated.spring(x, {\r\n                    toValue: 0,\r\n                    velocity: vx\r\n                }).start();\r\n                Animated.spring(y, {\r\n                    toValue: 0,\r\n                    velocity: vy\r\n                }).start();\r\n            }\r\n        });\r\n    },\r\n\r\n    render: function () {\r\n\r\n        var { x, y, distance } = this.state;\r\n\r\n        return (\r\n            <View\r\n                style={styles.container}\r\n                {...this.responder.panHandlers}>\r\n                <Animated.View\r\n                    style={[styles.handle, {\r\n                        transform: [\r\n                            { translateX: x },\r\n                            { translateY: y }\r\n                        ],\r\n                        opacity: distance.interpolate({\r\n                            inputRange: [0, 300, 301],\r\n                            outputRange: [1, 0.5, 0.5]\r\n                        })\r\n                    }]}\r\n                    />\r\n            </View>\r\n        );\r\n    }\r\n});\r\n\r\n\r\nvar styles = StyleSheet.create({\r\n    container: {\r\n        flex: 1,\r\n        justifyContent: 'flex-start',\r\n        alignItems: 'center',\r\n        backgroundColor: '#2e2f31',\r\n        padding: 30\r\n    },\r\n    handle: {\r\n        position: 'absolute',\r\n        top: (width - 200) / 2,\r\n        left: (height - 200) / 2,\r\n        width: 200,\r\n        height: 200,\r\n        borderRadius: 100,\r\n        backgroundColor: 'blue',\r\n    }\r\n});\r\n\r\nAppRegistry.registerComponent('AnimatedFormulaExample', () => AnimatedFormulaExample);\r\n```\r\n\r\nIf you think this is worth pulling in, I will be happy to write a couple of tests and add to the documentation as part of the PR.\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/facebook/react-native/issues/comments/163363359","html_url":"https://github.com/facebook/react-native/pull/2045#issuecomment-163363359","issue_url":"https://api.github.com/repos/facebook/react-native/issues/2045","id":163363359,"user":{"login":"lelandrichardson","id":1885623,"avatar_url":"https://avatars.githubusercontent.com/u/1885623?v=3","gravatar_id":"","url":"https://api.github.com/users/lelandrichardson","html_url":"https://github.com/lelandrichardson","followers_url":"https://api.github.com/users/lelandrichardson/followers","following_url":"https://api.github.com/users/lelandrichardson/following{/other_user}","gists_url":"https://api.github.com/users/lelandrichardson/gists{/gist_id}","starred_url":"https://api.github.com/users/lelandrichardson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lelandrichardson/subscriptions","organizations_url":"https://api.github.com/users/lelandrichardson/orgs","repos_url":"https://api.github.com/users/lelandrichardson/repos","events_url":"https://api.github.com/users/lelandrichardson/events{/privacy}","received_events_url":"https://api.github.com/users/lelandrichardson/received_events","type":"User","site_admin":false},"created_at":"2015-12-09T19:21:42Z","updated_at":"2015-12-09T19:21:42Z","body":"Closing since the multiple/add APIs are being added now."}}