Skip to content

Commit

Permalink
fix: fixed scrolling on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
dohooo committed Sep 9, 2021
1 parent d74d1be commit d253b3c
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 95 deletions.
52 changes: 27 additions & 25 deletions example/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,37 @@ const pak = require('../package.json');
const root = path.resolve(__dirname, '..');

const modules = Object.keys({
...pak.peerDependencies,
...pak.peerDependencies,
});

module.exports = {
projectRoot: __dirname,
watchFolders: [root],
projectRoot: __dirname,
watchFolders: [root],

// We need to make sure that only one version is loaded for peerDependencies
// So we blacklist them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: blacklist(
modules.map(
(m) =>
new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
)
),
// We need to make sure that only one version is loaded for peerDependencies
// So we blacklist them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: blacklist(
modules.map(
(m) =>
new RegExp(
`^${escape(path.join(root, 'node_modules', m))}\\/.*$`
)
)
),

extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),
},
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),
},

transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
};
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@
"babel-preset-expo": "8.3.0",
"expo-cli": "^4.0.13",
"react-native-gesture-handler": "^1.10.3",
"react-native-reanimated": "^2.2.0"
"react-native-reanimated": "2.2.0"
}
}
8 changes: 4 additions & 4 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export default function App() {
mode="parallax"
width={width}
data={[
// { color: 'red' },
// { color: 'purple' },
// { color: 'blue' },
// { color: 'yellow' },
{ color: 'red' },
{ color: 'purple' },
{ color: 'blue' },
{ color: 'yellow' },
]}
parallaxScrollingScale={0.8}
onSnapToItem={(index) => {
Expand Down
42 changes: 21 additions & 21 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1171,8 +1171,8 @@

"@egjs/hammerjs@^2.0.17":
version "2.0.17"
resolved "https://registry.npm.taobao.org/@egjs/hammerjs/download/@egjs/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
integrity sha1-XcAq91pqBuTC2wICyuOMkmOJUSQ=
resolved "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124"
integrity sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==
dependencies:
"@types/hammerjs" "^2.0.36"

Expand Down Expand Up @@ -2301,8 +2301,8 @@

"@types/hammerjs@^2.0.36":
version "2.0.40"
resolved "https://registry.nlark.com/@types/hammerjs/download/@types/hammerjs-2.0.40.tgz#ded0240b6ea1ad7afc1e60374c49087aaea5dbd8"
integrity sha1-3tAkC26hrXr8HmA3TEkIeq6l29g=
resolved "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz#ded0240b6ea1ad7afc1e60374c49087aaea5dbd8"
integrity sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA==

"@types/html-minifier-terser@^5.0.0":
version "5.1.2"
Expand Down Expand Up @@ -4465,8 +4465,8 @@ cron-parser@^2.13.0:

cross-fetch@^3.0.4:
version "3.1.4"
resolved "https://registry.nlark.com/cross-fetch/download/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
integrity sha1-lyPzo6JHv4uJA586OAqSROj6Lzk=
resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==
dependencies:
node-fetch "2.6.1"

Expand Down Expand Up @@ -5950,8 +5950,8 @@ fbjs@^0.8.4:

fbjs@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/fbjs/download/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165"
integrity sha1-CQcGf7P1enj0XZXx6s/8rNYjwWU=
resolved "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165"
integrity sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==
dependencies:
cross-fetch "^3.0.4"
fbjs-css-vars "^1.0.0"
Expand Down Expand Up @@ -6729,8 +6729,8 @@ hmac-drbg@^1.0.1:

hoist-non-react-statics@^3.3.0:
version "3.3.2"
resolved "https://registry.npm.taobao.org/hoist-non-react-statics/download/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha1-7OCsr3HWLClpwuxZ/v9CpLGoW0U=
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"

Expand Down Expand Up @@ -8931,8 +8931,8 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:

mockdate@^3.0.2:
version "3.0.5"
resolved "https://registry.npm.taobao.org/mockdate/download/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
integrity sha1-eJvmht6zFJ598rZj0rxDkrwyhPs=
resolved "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==

moment-timezone@^0.5.31:
version "0.5.33"
Expand Down Expand Up @@ -9085,8 +9085,8 @@ nocache@^2.1.0:

[email protected]:
version "2.6.1"
resolved "https://registry.nlark.com/node-fetch/download/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI=
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==

node-fetch@^1.0.1:
version "1.7.3"
Expand Down Expand Up @@ -10784,19 +10784,19 @@ react-is@^17.0.1:

react-native-gesture-handler@^1.10.3:
version "1.10.3"
resolved "https://registry.npm.taobao.org/react-native-gesture-handler/download/react-native-gesture-handler-1.10.3.tgz#942bbf2963bbf49fa79593600ee9d7b5dab3cfc0"
integrity sha1-lCu/KWO79J+nlZNgDunXtdqzz8A=
resolved "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.10.3.tgz#942bbf2963bbf49fa79593600ee9d7b5dab3cfc0"
integrity sha512-cBGMi1IEsIVMgoox4RvMx7V2r6bNKw0uR1Mu1o7NbuHS6BRSVLq0dP34l2ecnPlC+jpWd3le6Yg1nrdCjby2Mw==
dependencies:
"@egjs/hammerjs" "^2.0.17"
fbjs "^3.0.0"
hoist-non-react-statics "^3.3.0"
invariant "^2.2.4"
prop-types "^15.7.2"

react-native-reanimated@^2.2.0:
[email protected]:
version "2.2.0"
resolved "https://registry.nlark.com/react-native-reanimated/download/react-native-reanimated-2.2.0.tgz#a6412c56b4e591d1f00fac949f62d0c72c357c78"
integrity sha1-pkEsVrTlkdHwD6yUn2LQxyw1fHg=
resolved "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.0.tgz#a6412c56b4e591d1f00fac949f62d0c72c357c78"
integrity sha512-lOJDd+5w1gY6DHGXG2jD1dsjzQmXQ2699HUc3IztvI2WP4zUT+UAA+zSG+5JiBS5DUnTL8YhhkmUQmr1KNGO5w==
dependencies:
"@babel/plugin-transform-object-assign" "^7.10.4"
fbjs "^3.0.0"
Expand Down Expand Up @@ -12012,8 +12012,8 @@ stream-shift@^1.0.0:

string-hash-64@^1.0.3:
version "1.0.3"
resolved "https://registry.npm.taobao.org/string-hash-64/download/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322"
integrity sha1-DetW31hnhkDbXEecy7tZeqoN4yI=
resolved "https://registry.npmjs.org/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322"
integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==

string-width@^1.0.1:
version "1.0.2"
Expand Down
83 changes: 43 additions & 40 deletions src/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,15 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';
import { CarouselItem } from './CarouselItem';
import { fillNum } from './fillNum';
import type { TMode } from './layouts';
import { ParallaxLayout } from './layouts/index';
import { useCarouselController } from './useCarouselController';
import { useComputedAnim } from './useComputedAnim';
import { useLoop } from './useLoop';
import { useComputedIndex } from './useComputedIndex';

export const _withTiming = (
num: number,
callback?: (isFinished: boolean) => void
) => {
'worklet';
return withTiming(
num,
{
duration: 250,
},
(isFinished) => {
!!callback && runOnJS(callback)(isFinished);
}
);
export const timingConfig = {
duration: 250,
};

export interface ICarouselProps<T extends unknown> {
Expand Down Expand Up @@ -211,70 +198,86 @@ function Carousel<T extends unknown = any>(
useAnimatedGestureHandler<PanGestureHandlerGestureEvent>(
{
onStart: (_, ctx: any) => {
if (ctx.lock) return;
ctx.startContentOffsetX = handlerOffsetX.value;
ctx.currentContentOffsetX = handlerOffsetX.value;
},
onActive: (e, ctx: any) => {
if (ctx.lock) return;
/**
* `onActive` and `onEnd` return different values of translationX!So that creates a bias!TAT
* */
ctx.translationX = e.translationX;
if (loop) {
handlerOffsetX.value =
ctx.startContentOffsetX +
Math.round(e.translationX);
ctx.currentContentOffsetX + e.translationX;
return;
}
handlerOffsetX.value = Math.max(
Math.min(
ctx.startContentOffsetX +
Math.round(e.translationX),
0
),
Math.min(ctx.currentContentOffsetX + e.translationX, 0),
-(data.length - 1) * width
);
},
onEnd: (e) => {
const intTranslationX = Math.round(e.translationX);
const sub = Math.abs(intTranslationX);
onEnd: (e, ctx: any) => {
if (ctx.lock) {
return;
}
const translationX = ctx.translationX;

function _withTimingCallback(num: number) {
return _withTiming(num, callComputedIndex);
ctx.lock = true;
return withTiming(num, timingConfig, (isFinished) => {
if (isFinished) {
ctx.lock = false;
}
runOnJS(callComputedIndex)(isFinished);
});
}

if (intTranslationX > 0) {
if (translationX > 0) {
/**
* If not loop no , longer scroll when sliding to the start.
* */
if (!loop && handlerOffsetX.value >= 0) {
return;
}

if (sub > width / 2) {
if (
Math.abs(translationX) + Math.abs(e.velocityX) >
width / 2
) {
handlerOffsetX.value = _withTimingCallback(
fillNum(
width,
handlerOffsetX.value + (width - sub)
)
handlerOffsetX.value + width - translationX
);
} else {
handlerOffsetX.value = _withTimingCallback(
fillNum(width, handlerOffsetX.value - sub)
handlerOffsetX.value - translationX
);
}
return;
}

if (intTranslationX < 0) {
if (translationX < 0) {
/**
* If not loop , no longer scroll when sliding to the end.
* */
if (
!loop &&
handlerOffsetX.value <= -(data.length - 1) * width
) {
return;
}

if (sub > width / 2) {
if (
Math.abs(translationX) + Math.abs(e.velocityX) >
width / 2
) {
handlerOffsetX.value = _withTimingCallback(
fillNum(
width,
handlerOffsetX.value - (width - sub)
)
handlerOffsetX.value - width - translationX
);
} else {
handlerOffsetX.value = _withTimingCallback(
fillNum(width, handlerOffsetX.value + sub)
handlerOffsetX.value - translationX
);
}
return;
Expand Down
10 changes: 6 additions & 4 deletions src/useCarouselController.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { _withTiming } from './Carousel';
import { timingConfig } from './Carousel';
import type Animated from 'react-native-reanimated';
import { useSharedValue } from 'react-native-reanimated';
import { useSharedValue, withTiming } from 'react-native-reanimated';

interface IOpts {
width: number;
Expand Down Expand Up @@ -35,8 +35,9 @@ export function useCarouselController(opts: IOpts): ICarouselController {
if (disable) return;
if (lock.value) return;
openLock();
handlerOffsetX.value = _withTiming(
handlerOffsetX.value = withTiming(
handlerOffsetX.value - width,
timingConfig,
(isFinished: boolean) => {
callback?.(isFinished);
closeLock(isFinished);
Expand All @@ -51,8 +52,9 @@ export function useCarouselController(opts: IOpts): ICarouselController {
if (disable) return;
if (lock.value) return;
openLock();
handlerOffsetX.value = _withTiming(
handlerOffsetX.value = withTiming(
handlerOffsetX.value + width,
timingConfig,
(isFinished: boolean) => {
callback?.(isFinished);
closeLock(isFinished);
Expand Down

0 comments on commit d253b3c

Please sign in to comment.