From d623844447529a516de4ff4e3afa0a821bb9284d Mon Sep 17 00:00:00 2001 From: Nishan Date: Sat, 11 Dec 2021 10:27:48 +0530 Subject: [PATCH 1/3] add docs for attaching handler with reanimated --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 7de0dc4d..11239648 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,43 @@ requestAnimationFrame(() => refPagerView.current?.setPage(index)); | :--------------------------------------------------------------------: | :-------------------------------------------------------------------------: | | ViewPager | ViewPager | +## Reanimated +- You can attach `onPageScroll` with reanimated event handler. + +```jsx +// 1. Define the handler +function usePageScrollHandler(handlers, dependencies) { + const {context, doDependenciesDiffer} = useHandler(handlers, dependencies); + const subscribeForEvents = ['onPageScroll']; + + return useEvent( + event => { + 'worklet'; + const {onPageScroll} = handlers; + if (onPageScroll && event.eventName.endsWith('onPageScroll')) { + onPageScroll(event, context); + } + }, + subscribeForEvents, + doDependenciesDiffer, + ); +} + +// 2. Attach the event handler +import { PagerView } from "react-native-pager-view"; +import Animated from "react-native-reanimated"; +const AnimatedPagerView = Animated.createAnimatedComponent(PagerView); + +const pageScrollHandler = usePageScrollHandler({ + onPageScroll: e => { + 'worklet'; + offset.value = e.offset; + console.log(e.offset, e.position); + }, +}); + + +``` ## License MIT From 553839f184c58593e25ac972be00d57a72abf123 Mon Sep 17 00:00:00 2001 From: Nishan Date: Tue, 4 Jan 2022 13:03:52 +0530 Subject: [PATCH 2/3] feat: add reanimated onpagescroll example --- example/android/app/build.gradle | 2 +- .../reactnativepagerview/MainApplication.java | 7 ++ example/babel.config.js | 1 + example/ios/Podfile.lock | 36 ++++++++-- example/package.json | 2 +- example/src/App.tsx | 5 ++ example/src/ReanimatedOnPageScrollExample.tsx | 56 ++++++++++++++++ example/yarn.lock | 66 +++++++++++++++++-- 8 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 example/src/ReanimatedOnPageScrollExample.tsx diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 7c69a693..91f3e4fb 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -76,7 +76,7 @@ import com.android.build.OutputFile */ project.ext.react = [ - enableHermes: false, // clean and rebuild if changing + enableHermes: true, // clean and rebuild if changing entryFile: "index.js", ] diff --git a/example/android/app/src/main/java/com/example/reactnativepagerview/MainApplication.java b/example/android/app/src/main/java/com/example/reactnativepagerview/MainApplication.java index f02225af..9cba7ac6 100644 --- a/example/android/app/src/main/java/com/example/reactnativepagerview/MainApplication.java +++ b/example/android/app/src/main/java/com/example/reactnativepagerview/MainApplication.java @@ -11,6 +11,8 @@ import java.lang.reflect.InvocationTargetException; import java.util.List; import com.reactnativepagerview.PagerViewPackage; +import com.facebook.react.bridge.JSIModulePackage; // <- add +import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add public class MainApplication extends Application implements ReactApplication { @@ -35,6 +37,11 @@ protected List getPackages() { protected String getJSMainModuleName() { return "index"; } + + @Override + protected JSIModulePackage getJSIModulePackage() { + return new ReanimatedJSIModulePackage(); // <- add + } }; @Override diff --git a/example/babel.config.js b/example/babel.config.js index adea77bd..3c49f73b 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -13,5 +13,6 @@ module.exports = { }, }, ], + 'react-native-reanimated/plugin', ], }; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 009d734e..65de1a58 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -185,7 +185,7 @@ PODS: - React-cxxreact (= 0.63.4) - React-jsi (= 0.63.4) - React-jsinspector (0.63.4) - - react-native-pager-view (5.4.8): + - react-native-pager-view (5.4.9): - React-Core - react-native-safe-area-context (3.2.0): - React-Core @@ -253,8 +253,34 @@ PODS: - React - RNGestureHandler (1.10.3): - React-Core - - RNReanimated (1.13.3): + - RNReanimated (2.3.1): + - DoubleConversion + - FBLazyVector + - FBReactNativeSpec + - Folly + - glog + - RCTRequired + - RCTTypeSafety + - React + - React-callinvoker - React-Core + - React-Core/DevSupport + - React-Core/RCTWebSocket + - React-CoreModules + - React-cxxreact + - React-jsi + - React-jsiexecutor + - React-jsinspector + - React-RCTActionSheet + - React-RCTAnimation + - React-RCTBlob + - React-RCTImage + - React-RCTLinking + - React-RCTNetwork + - React-RCTSettings + - React-RCTText + - ReactCommon/turbomodule/core + - Yoga - RNScreens (2.18.1): - React-Core - Yoga (1.14.0) @@ -382,7 +408,7 @@ SPEC CHECKSUMS: React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31 React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949 React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a - react-native-pager-view: c44c385eb20f0733c53685456fb9eb8d8469a1bb + react-native-pager-view: 3ee7d4c7697fb3ef788346e834a60cca97ed8540 react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79 React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336 React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b @@ -396,10 +422,10 @@ SPEC CHECKSUMS: ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211 - RNReanimated: 514a11da3a2bcc6c3dfd9de32b38e2b9bf101926 + RNReanimated: 5b5df752f76020971549cb57aa6371dac6895b9e RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6 PODFILE CHECKSUM: ff595481d97548cf6367f753d945ef2a7fc1f818 -COCOAPODS: 1.10.1 +COCOAPODS: 1.11.2 diff --git a/example/package.json b/example/package.json index 032914d9..47b8e10c 100644 --- a/example/package.json +++ b/example/package.json @@ -23,7 +23,7 @@ "react-native": "0.63.4", "react-native-animated-pagination-dots": "^0.1.51", "react-native-gesture-handler": "^1.9.0", - "react-native-reanimated": "^1.13.2", + "react-native-reanimated": "^2.3.1", "react-native-safe-area-context": "^3.1.9", "react-native-screens": "^2.16.1", "react-native-tab-view": "^3.1.1" diff --git a/example/src/App.tsx b/example/src/App.tsx index 3d982c14..edcff364 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -17,6 +17,7 @@ import TabBarIconExample from './tabView/TabBarIconExample'; import CustomIndicatorExample from './tabView/CustomIndicatorExample'; import CustomTabBarExample from './tabView/CustomTabBarExample'; import CoverflowExample from './tabView/CoverflowExample'; +import ReanimatedOnPageScrollExample from './ReanimatedOnPageScrollExample'; const examples = [ { component: BasicPagerViewExample, name: 'Basic Example' }, @@ -42,6 +43,10 @@ const examples = [ { component: TabBarIconExample, name: 'TabBarIconExample' }, { component: CustomIndicatorExample, name: 'CustomIndicatorExample' }, { component: CustomTabBarExample, name: 'CustomTabBarExample' }, + { + component: ReanimatedOnPageScrollExample, + name: 'Reanimated onPageScroll example', + }, { component: CoverflowExample, name: 'CoverflowExample' }, ]; diff --git a/example/src/ReanimatedOnPageScrollExample.tsx b/example/src/ReanimatedOnPageScrollExample.tsx new file mode 100644 index 00000000..5e137d9d --- /dev/null +++ b/example/src/ReanimatedOnPageScrollExample.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { View, StyleSheet, Text } from 'react-native'; +import PagerView from 'react-native-pager-view'; +import Animated, { useHandler, useEvent } from 'react-native-reanimated'; + +const AnimatedPager = Animated.createAnimatedComponent(PagerView); + +export function usePagerScrollHandler(handlers: any, dependencies?: any) { + const { context, doDependenciesDiffer } = useHandler(handlers, dependencies); + const subscribeForEvents = ['onPageScroll']; + + return useEvent( + (event) => { + 'worklet'; + const { onPageScroll } = handlers; + if (onPageScroll && event.eventName.endsWith('onPageScroll')) { + onPageScroll(event, context); + } + }, + subscribeForEvents, + doDependenciesDiffer + ); +} + +export default () => { + const handler = usePagerScrollHandler({ + onPageScroll: (e: any) => { + 'worklet'; + console.log(e.offset, e.position); + }, + }); + + return ( + + + First page + + + Second page + + + Third page + + + ); +}; + +const styles = StyleSheet.create({ + pagerView: { + flex: 1, + }, +}); diff --git a/example/yarn.lock b/example/yarn.lock index 4ebd6c5e..e3bf5b4f 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -165,6 +165,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== +"@babel/helper-plugin-utils@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== + "@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" @@ -517,6 +522,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-transform-object-assign@^7.10.4": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.16.7.tgz#5fe08d63dccfeb6a33aa2638faf98e5c584100f8" + integrity sha512-R8mawvm3x0COTJtveuoqZIjNypn2FjfvXZr4pSQ8VhEFBuQGBz4XhHasZtHXjgXU4XptZ4HtGof3NoYc93ZH9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-object-super@^7.0.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" @@ -1204,6 +1216,11 @@ resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.39.tgz#4be64bbacf3813c79c0dab895c6b0fdc7d5e513f" integrity sha512-lYR2Y/tV2ujpk/WyUc7S0VLI0a9hrtVIN9EwnrNo5oSEJI2cK2/XrgwOQmXLL3eTulOESvh9qP6si9+DWM9cOA== +"@types/invariant@^2.2.35": + version "2.2.35" + resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" + integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" @@ -4338,6 +4355,11 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" @@ -4808,6 +4830,11 @@ mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" +mockdate@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" + integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ== + moment@^2.19.3: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" @@ -5444,6 +5471,11 @@ react-devtools-core@^4.6.0: shell-quote "^1.6.1" ws "^7" +react-freeze@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/react-freeze/-/react-freeze-1.0.0.tgz#b21c65fe1783743007c8c9a2952b1c8879a77354" + integrity sha512-yQaiOqDmoKqks56LN9MTgY06O0qQHgV4FUrikH357DydArSZHQhl0BJFqGKIZoTqi8JizF9Dxhuk1FIZD6qCaw== + react-is@^16.12.0, react-is@^16.13.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -5477,12 +5509,18 @@ react-native-iphone-x-helper@^1.3.0: resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010" integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg== -react-native-reanimated@^1.13.2: - version "1.13.3" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.13.3.tgz#fb0e1d582c8866015140f2159e147ffe6e798a3a" - integrity sha512-i714H24dv6ncpFO7/SZ0PfAMbvjgVbF8Ow2NPtowoZAz8osS54DmTMrkgJ9Za+uEku/s0AEaxqiXG2Xgntvv2g== +react-native-reanimated@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.3.1.tgz#c7abad48f9e6c84610b0d5e270088ecd61750382" + integrity sha512-nzjVqwkB8eeyPKT2KoiA9EEz17ZMFSGMoOTC17Z9b5nE2Z4ZHjHM5EKhY0TlwzXFUuJAE9PhOfxF0wIO/maZSA== dependencies: - fbjs "^1.0.0" + "@babel/plugin-transform-object-assign" "^7.10.4" + "@types/invariant" "^2.2.35" + invariant "^2.2.4" + lodash.isequal "^4.5.0" + mockdate "^3.0.2" + react-native-screens "^3.4.0" + string-hash-64 "^1.0.3" react-native-safe-area-context@^3.1.9: version "3.2.0" @@ -5494,6 +5532,14 @@ react-native-screens@^2.16.1: resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.18.1.tgz#47b9991c6f762d00d0ed3233e5283d523e859885" integrity sha512-r5WZLpmx2hHjC1RgMdPq5YpSU9tEhBpUaZ5M1SUtNIONyiLqQVxabhRCINdebIk4depJiIl7yw2Q85zJyeX6fw== +react-native-screens@^3.4.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.10.1.tgz#2634a1a17380c559a06de391e4969ae72c4365ff" + integrity sha512-ZF/XHnRsuinvDY1XiCWLXxoUoSf+NgsAes2SZfX9rFQQcv128zmh/+19SSavGrSf6rQNzqytEMdRGI6yr4Gbjw== + dependencies: + react-freeze "^1.0.0" + warn-once "^0.1.0" + react-native-svg@^12.1.0: version "12.1.0" resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.1.0.tgz#acfe48c35cd5fca3d5fd767abae0560c36cfc03d" @@ -6230,6 +6276,11 @@ strict-uri-encode@^2.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= +string-hash-64@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322" + integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw== + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -6761,6 +6812,11 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" +warn-once@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.1.0.tgz#4f58d89b84f968d0389176aa99e0cf0f14ffd4c8" + integrity sha512-recZTSvuaH/On5ZU5ywq66y99lImWqzP93+AiUo9LUwG8gXHW+LJjhOd6REJHm7qb0niYqrEQJvbHSQfuJtTqA== + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" From 71e422b142a2eef61d715f31bcc03669de877ca4 Mon Sep 17 00:00:00 2001 From: Nishan Date: Tue, 4 Jan 2022 13:21:34 +0530 Subject: [PATCH 3/3] feat: add reanimated onpagescroll example --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 11239648..d0e94d98 100644 --- a/README.md +++ b/README.md @@ -193,8 +193,13 @@ requestAnimationFrame(() => refPagerView.current?.setPage(index)); | :--------------------------------------------------------------------: | :-------------------------------------------------------------------------: | | ViewPager | ViewPager | -## Reanimated -- You can attach `onPageScroll` with reanimated event handler. +## Reanimated onPageScroll handler + +An example can be found [here](https://github.com/callstack/react-native-pager-view/blob/master/example/src/ReanimatedOnPageScrollExample.tsx) + +#### Instructions + +To attach reanimated handler with `onPageScroll` follow the below steps. ```jsx // 1. Define the handler