Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: incorrect first frame when keyboard was resized (#316)
## 📜 Description Fixed incorrect first frame (when keyboard was resized). ## 💡 Motivation and Context If we use `progress` directly for interpolation we may encounter a situation when animation looks junky. It happens because first frame is not calculated properly when we interpolate value. First of all let's define how `progress` value is calculated across platforms when keyboard is resized: - on iOS it'll be always `1` because keyboard changes size immediately; - on Android prior to Android 11 we'll have intermediate values; - on Android 11+ we don't have intermediate values, but to make it more consistent across platforms I added a transition; So to sum it up: on iOS `progress` is always `1` when keyboard gets resized. On Android it will change the value, and the calculation algorithm looks like: take latest keyboard frame and new final frame -> divide current to new (in this case we always assure that final `progress` value will be `1`. However if we do interpolation directly on `progress` value we may encounter some issues. Let's say keyboard changes size from `0` to `200` and we do interpolation from `0` to `230` (`+30` to final keyboard frame). Then keyboard gets resized from `200` to `220`. In this case we'll interpolate from `0` to `250`. And initial frame will be 200 / 220 * 250 = 227 (but previous value was 220, so we will see a jump from 220 and 227). To overcome this problem I added `useKeyboardInterpolation` hook. It fixes this problem by changing interpolation approach. Basically when keyboard appears/disappears it uses the same approach as `progress`-based interpolation. However when it comes to keyboard resizing it detects this moment and changes interpolation rules: instead of using a provided range it will use latest interpolated value as the beginning of `inputRange`, so in our case discussed above new interpolation will be: ```tsx { inputRange: [200, 220] outputRange: [230, 250] } ``` In this case we will not have a jump and animation will be smooth. Closes #315 ## 📢 Changelog ### JS - added `useKeyboardInterpolation` hook; - use `useKeyboardInterpolation` hook in `KeyboardAvoidingView`/`KeyboardStickyView`; ## 🤔 How Has This Been Tested? Tested manually on Pixel 7 Pro. ## 📸 Screenshots (if appropriate): |Before|After| |------|------| |<video src="https://private-user-images.githubusercontent.com/22820318/294164887-081cfd0d-e308-43de-b946-79c47c9fe9a0.mp4">|<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/68109c4b-d17c-40a1-876d-a74fad158efe">| |<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/93a783c9-3db2-41c8-9b92-7f307399729e">|<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/13bfb5c2-c1bf-47b5-9a84-a7d2ff5cd6a3">| ## 📝 Checklist - [x] CI successfully passed
- Loading branch information