From 915540d23717f440c4c9023293ebcd84d746f2c2 Mon Sep 17 00:00:00 2001 From: chirag04 Date: Wed, 15 Jul 2015 07:57:25 -0700 Subject: [PATCH] [transform] add perspective property to transform Summary: ![matrixflip](https://cloud.githubusercontent.com/assets/1509831/8701143/607b069c-2b10-11e5-9c54-8b9767e74e16.gif) cc @sahrens @vjeux Closes https://github.com/facebook/react-native/pull/1980 Github Author: chirag04 --- Examples/UIExplorer/TransformExample.js | 215 ++++++++++++++++----- Examples/UIExplorer/UIExplorerList.js | 1 + Libraries/StyleSheet/TransformPropTypes.js | 1 + Libraries/StyleSheet/precomputeStyle.js | 3 + Libraries/Utilities/MatrixMath.js | 4 + 5 files changed, 180 insertions(+), 44 deletions(-) diff --git a/Examples/UIExplorer/TransformExample.js b/Examples/UIExplorer/TransformExample.js index 9e848c3a5..7da9eb5ac 100644 --- a/Examples/UIExplorer/TransformExample.js +++ b/Examples/UIExplorer/TransformExample.js @@ -1,61 +1,85 @@ /** - * Copyright 2004-present Facebook. All Rights Reserved. + * The examples provided by Facebook are for non-commercial testing and + * evaluation purposes only. * - * @providesModule TransformExample + * Facebook reserves all rights not expressly granted. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL + * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; -var React = require('React'); +var React = require('react-native'); var { + Animated, StyleSheet, + Text, View, } = React; -var TimerMixin = require('react-timer-mixin'); -var UIExplorerBlock = require('./UIExplorerBlock'); -var UIExplorerPage = require('./UIExplorerPage'); - -var TransformExample = React.createClass({ - - mixins: [TimerMixin], - +var Flip = React.createClass({ getInitialState() { return { - interval: this.setInterval(this._update, 800), - pulse: false, + theta: new Animated.Value(45), }; }, + componentDidMount() { + this._animate(); + }, + + _animate() { + this.state.theta.setValue(0); + Animated.timing(this.state.theta, { + toValue: 360, + duration: 5000, + }).start(this._animate); + }, + render() { return ( - - - - - - - - - - - - - + + + + This text is flipping great. + + + + + On the flip side... + + + ); - }, - - _update() { - this.setState({ - pulse: !this.state.pulse, - }); - }, - + } }); var styles = StyleSheet.create({ + container: { + height: 500, + }, box1: { left: 0, backgroundColor: 'green', @@ -88,7 +112,7 @@ var styles = StyleSheet.create({ }, box3step1: { left: 0, - backgroundColor: '#ffb6c1', // lightpink + backgroundColor: 'lightpink', height: 50, position: 'absolute', top: 0, @@ -99,7 +123,7 @@ var styles = StyleSheet.create({ }, box3step2: { left: 0, - backgroundColor: '#ff69b4', //hotpink + backgroundColor: 'hotpink', height: 50, opacity: 0.5, position: 'absolute', @@ -113,7 +137,7 @@ var styles = StyleSheet.create({ }, box3step3: { left: 0, - backgroundColor: '#ff1493', // deeppink + backgroundColor: 'deeppink', height: 50, opacity: 0.5, position: 'absolute', @@ -129,7 +153,7 @@ var styles = StyleSheet.create({ }, box4: { left: 0, - backgroundColor: '#ff8c00', // darkorange + backgroundColor: 'darkorange', height: 50, position: 'absolute', top: 0, @@ -141,7 +165,7 @@ var styles = StyleSheet.create({ width: 100, }, box5: { - backgroundColor: '#800000', // maroon + backgroundColor: 'maroon', height: 50, position: 'absolute', right: 0, @@ -155,7 +179,110 @@ var styles = StyleSheet.create({ {scale: 2}, ], }, + flipCardContainer: { + marginVertical: 40, + flex: 1, + alignSelf: 'center', + }, + flipCard: { + width: 200, + height: 200, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'blue', + backfaceVisibility: 'hidden', + }, + flipText: { + width: 90, + fontSize: 20, + color: 'white', + fontWeight: 'bold', + } }); - -module.exports = TransformExample; +exports.title = 'Transforms'; +exports.description = 'View transforms'; +exports.examples = [ + { + title: 'Perspective', + description: 'perspective: 850, rotateX: Animated.timing(0 -> 360)', + render(): ReactElement { return ; } + }, + { + title: 'Translate, Rotate, Scale', + description: "translateX: 100, translateY: 50, rotate: '30deg', scaleX: 2, scaleY: 2", + render() { + return ( + + + + ); + } + }, + { + title: 'Scale, Translate, Rotate, ', + description: "scaleX: 2, scaleY: 2, translateX: 100, translateY: 50, rotate: '30deg'", + render() { + return ( + + + + ); + } + }, + { + title: 'Rotate', + description: "rotate: '30deg'", + render() { + return ( + + + + ); + } + }, + { + title: 'Rotate, Scale', + description: "rotate: '30deg', scaleX: 2, scaleY: 2", + render() { + return ( + + + + ); + } + }, + { + title: 'Rotate, Scale, Translate ', + description: "rotate: '30deg', scaleX: 2, scaleY: 2, translateX: 100, translateY: 50", + render() { + return ( + + + + ); + } + }, + { + title: 'Translate, Scale, Rotate', + description: "translate: [200, 350], scale: 2.5, rotate: '-0.2rad'", + render() { + return ( + + + + ); + } + }, + { + title: 'Translate, Rotate, Scale', + description: "translate: [-50, 35], rotate: '50deg', scale: 2", + render() { + return ( + + + + ); + } + } +]; diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js index 217797e26..20edd13b0 100644 --- a/Examples/UIExplorer/UIExplorerList.js +++ b/Examples/UIExplorer/UIExplorerList.js @@ -80,6 +80,7 @@ if (Platform.OS === 'ios') { require('./AlertIOSExample'), require('./AppStateIOSExample'), require('./AsyncStorageExample'), + require('./TransformExample'), require('./BorderExample'), require('./CameraRollExample.ios'), require('./NetInfoExample'), diff --git a/Libraries/StyleSheet/TransformPropTypes.js b/Libraries/StyleSheet/TransformPropTypes.js index 06728d0b7..c5ea9cea3 100644 --- a/Libraries/StyleSheet/TransformPropTypes.js +++ b/Libraries/StyleSheet/TransformPropTypes.js @@ -16,6 +16,7 @@ var ReactPropTypes = require('ReactPropTypes'); var TransformPropTypes = { transform: ReactPropTypes.arrayOf( ReactPropTypes.oneOfType([ + ReactPropTypes.shape({perspective: ReactPropTypes.number}), ReactPropTypes.shape({rotate: ReactPropTypes.string}), ReactPropTypes.shape({rotateX: ReactPropTypes.string}), ReactPropTypes.shape({rotateY: ReactPropTypes.string}), diff --git a/Libraries/StyleSheet/precomputeStyle.js b/Libraries/StyleSheet/precomputeStyle.js index 0e166e1c4..3f1955b4a 100644 --- a/Libraries/StyleSheet/precomputeStyle.js +++ b/Libraries/StyleSheet/precomputeStyle.js @@ -58,6 +58,9 @@ function _precomputeTransforms(style: Object): Object { case 'matrix': MatrixMath.multiplyInto(result, result, value); break; + case 'perspective': + _multiplyTransform(result, MatrixMath.reusePerspectiveCommand, [value]); + break; case 'rotateX': _multiplyTransform(result, MatrixMath.reuseRotateXCommand, [_convertToRadians(value)]); break; diff --git a/Libraries/Utilities/MatrixMath.js b/Libraries/Utilities/MatrixMath.js index 0550eb187..c6a26ea82 100755 --- a/Libraries/Utilities/MatrixMath.js +++ b/Libraries/Utilities/MatrixMath.js @@ -65,6 +65,10 @@ var MatrixMath = { matrixCommand[10] = z; }, + reusePerspectiveCommand: function(matrixCommand, p) { + matrixCommand[11] = -1 / p; + }, + reuseScaleXCommand(matrixCommand, factor) { matrixCommand[0] = factor; },