From ab80001c905dbfb9354232c7a6c7e887736642b5 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Mon, 1 Jul 2019 02:31:28 -0700 Subject: [PATCH] Reset sMatrixDecompositionContext before applying transformations (#25438) Summary: Prior to this commit React Native on Android was not properly setting the transform's scale properly correctly when setting it to 0. In order to properly set one would need to use values close to 0, like 0.0001. This was happing due to BaseViewManager sharing sMatrixDecompositionContext across all views in a React Native app. In some cases the decomposeMatrix() method from the MatrixMathHelper would return early and not set any new values in sMatrixDecompositionContext (this is, the new transform values) and since this is a shared object the BaseViewManager would set the transform values from the a previous transform. In order to prevent this issue, before setting the new transform values always reset the sMatrixDecompositionContext values. ## Changelog [Android] [Fixed] - Reset sMatrixDecompositionContext before applying transformations Pull Request resolved: https://github.com/facebook/react-native/pull/25438 Test Plan: Run the code below on an Android device/emulator and you should see the following results: ### Android without the patch - current implementation Notice that the scale 0 is not properly applied to the last rectangle and the second rectangle does not animate properly. ![android-not-working](https://user-images.githubusercontent.com/984610/60400418-d29e0500-9b49-11e9-8006-63d6956d3a44.gif) ### Android with the patch Everything works fine ![android-working](https://user-images.githubusercontent.com/984610/60400420-d5005f00-9b49-11e9-9025-f11a9ee62414.gif) ### iOS - current implementation Everything works fine ![ios-working](https://user-images.githubusercontent.com/984610/60400421-d6ca2280-9b49-11e9-9d81-608780c69936.gif) ```javascript /** * Sample React Native App * https://github.com/facebook/react-native * * format * flow */ import React from 'react'; import { Animated, Button, StyleSheet, View, Text, SafeAreaView } from 'react-native'; const HorizontalContainer = ({ children, title }) => ( {children} {title} ); const App = () => { const animValue1 = React.useRef(new Animated.Value(1)).current; const animValue2 = React.useRef(new Animated.Value(1)).current; const onStartAnim = React.useCallback(() => { animValue1.setValue(0); animValue2.setValue(0); Animated.sequence([ Animated.timing(animValue1, { toValue: 1, duration: 300, useNativeDriver: true, }), Animated.timing(animValue2, { toValue: 1, delay: 700, duration: 300, useNativeDriver: true, }) ]).start(); }, [animValue1, animValue2]); return (