Skip to content

Commit

Permalink
chore: add react-native-svg circle to replace background view
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhom committed Mar 1, 2020
1 parent 32b43de commit 2d56530
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 142 deletions.
81 changes: 34 additions & 47 deletions example/android/app/app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,48 @@
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="SELECTED_BUILD_VARIANT" value="release" />
<option name="ASSEMBLE_TASK_NAME" value="assembleRelease" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileReleaseSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
<task>generateReleaseSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/build/generated/res/resValues/debug" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/build/generated/res/react/release;file://$MODULE_DIR$/build/generated/res/resValues/release" />
<option name="TEST_RES_FOLDERS_RELATIVE_PATH" value="" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes" />
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" />
<output url="file://$MODULE_DIR$/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes" />
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/releaseUnitTest/compileReleaseUnitTestJavaWithJavac/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/react/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/release" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/release/compileReleaseAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/release" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/release/compileReleaseRenderscript/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/react/release" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/release" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/release" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/release" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/release/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/release/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/release/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/release/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/release/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/release/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/release/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testRelease/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
Expand Down Expand Up @@ -101,6 +88,7 @@
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp-urlconnection:3.12.1@jar" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.12.1@jar" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.15.0@jar" level="project" />
<orderEntry type="library" name="Gradle: __local_aars__:./../node_modules/hermes-engine/android/hermes-release.aar:unspecified@jar" level="project" />
<orderEntry type="library" name="Gradle: com.facebook.react:react-native:0.61.5@aar" level="project" />
<orderEntry type="library" name="Gradle: androidx.appcompat:appcompat:1.0.2@aar" level="project" />
<orderEntry type="library" name="Gradle: androidx.fragment:fragment:1.0.0@aar" level="project" />
Expand Down Expand Up @@ -137,10 +125,9 @@
<orderEntry type="library" name="Gradle: com.facebook.fresco:nativeimagefilters:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.facebook.fresco:nativeimagetranscoder:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline-okhttp3:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: org.webkit:android-jsc:r245459@aar" level="project" />
<orderEntry type="module" module-name="react-native-gesture-handler" />
<orderEntry type="module" module-name="react-native-reanimated" />
<orderEntry type="module" module-name="react-native-safe-area-context" />
<orderEntry type="module" module-name="react-native-svg" />
<orderEntry type="module" module-name="android-react-native-gesture-handler" />
<orderEntry type="module" module-name="android-react-native-reanimated" />
<orderEntry type="module" module-name="android-react-native-safe-area-context" />
<orderEntry type="module" module-name="android-react-native-svg" />
</component>
</module>
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ import com.android.build.OutputFile

project.ext.react = [
entryFile: "index.js",
enableHermes: false, // clean and rebuild if changing
enableHermes: true, // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"
Expand Down
2 changes: 1 addition & 1 deletion example/android/example.iml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
1 change: 1 addition & 0 deletions example/index.tsx → example/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'react-native-gesture-handler';
import { AppRegistry } from 'react-native';
import App from './src/App';
import { name as appName } from './app.json';
Expand Down
1 change: 0 additions & 1 deletion example/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ module.exports = {
]),

extraNodeModules: modules.reduce((acc, name) => {
console.log(path.join(__dirname, 'node_modules', name));
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@
"scripts": {
"typescript": "tsc --noEmit",
"lint": "eslint --ext .js,.ts,.tsx .",
"prepare": "bob build",
"build": "bob build",
"example": "yarn --cwd example",
"bootstrap": "yarn example && yarn && cd example/ios && pod install",
"release": "release-it"
},
"dependencies": {
"react-native-redash": "^9.6.0"
"react-native-redash": "^9.6.0",
"react-native-svg": "^11.0.1"
},
"devDependencies": {
"@commitlint/cli": "^8.3.5",
Expand All @@ -54,14 +55,16 @@
"react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0",
"react-native-svg": "^11.0.1",
"release-it": "^12.6.2",
"typescript": "^3.8.3"
},
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.7.0"
"react-native-reanimated": "^1.7.0",
"react-native-svg": "^11.0.1"
},
"husky": {
"hooks": {
Expand Down
42 changes: 14 additions & 28 deletions src/PaperOnboarding.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import React, { useMemo, useCallback } from 'react';
import { View, Dimensions } from 'react-native';
import { View, Dimensions, StatusBar, Platform } from 'react-native';
import { horizontalPanGestureHandler, ReText } from 'react-native-redash';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
interpolate,
add,
concat,
block,
call,
} from 'react-native-reanimated';
import { withSpring } from './withSpring';
import Animated, { interpolate, add, concat } from 'react-native-reanimated';
import { withTiming } from './withTiming';
import {
PaperOnboardingItemType,
PaperOnboardingSafeAreaInsetsType,
Expand All @@ -27,13 +21,12 @@ interface PaperOnboardingProps {
export const PaperOnboarding = (props: PaperOnboardingProps) => {
// props
const { data, safeInsets: _safeInsets, indicatorSize = 40 } = props;

const safeInsets = useMemo<PaperOnboardingSafeAreaInsetsType>(
() => ({
top: _safeInsets?.top || 50,
bottom: _safeInsets?.bottom || 50,
left: _safeInsets?.left || 50,
right: _safeInsets?.right || 50,
top: _safeInsets?.top ?? 50,
bottom: _safeInsets?.bottom ?? 50,
left: _safeInsets?.left ?? 50,
right: _safeInsets?.right ?? 50,
}),
[_safeInsets]
);
Expand All @@ -48,8 +41,10 @@ export const PaperOnboarding = (props: PaperOnboardingProps) => {

const screenDimensions = useMemo(
() => ({
width: Dimensions.get('screen').width,
height: Dimensions.get('screen').height,
width: Dimensions.get('window').width,
height:
Dimensions.get('window').height -
(Platform.OS === 'android' ? StatusBar.currentHeight ?? 0 : 0),
}),
[]
);
Expand All @@ -60,11 +55,12 @@ export const PaperOnboarding = (props: PaperOnboardingProps) => {
);

// animations
const currentIndex = withSpring({
const currentIndex = withTiming({
value: translationX,
velocity: velocityX,
state: state,
size: data.length,
screenWidth: screenDimensions.width,
});

const animatedIndicatorsContainerPosition = add(
Expand Down Expand Up @@ -118,17 +114,7 @@ export const PaperOnboarding = (props: PaperOnboardingProps) => {
indicatorSize={indicatorSize}
safeInsets={safeInsets}
/>
<View style={styles.debugContainer}>
<Animated.Code>
{() =>
block([
call(
[currentIndex, concat(`currentIndex: `, currentIndex)],
args => console.log(`currentIndex: ${args[0]}, ${args[1]}`)
),
])
}
</Animated.Code>
<View style={styles.debugContainer} pointerEvents="none">
<ReText
style={styles.text}
text={concat(`translationX: `, translationX)}
Expand Down
67 changes: 30 additions & 37 deletions src/page/PaperOnboardingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React, { useMemo } from 'react';
import { Text } from 'react-native';
import Animated from 'react-native-reanimated';
import { Svg, Circle } from 'react-native-svg';
import Animated, { add } from 'react-native-reanimated';
import {
PaperOnboardingItemType,
PaperOnboardingSafeAreaInsetsType,
PaperOnboardingScreenDimensions,
} from '../types';
import { styles } from './styles';

const { interpolate, sub, Extrapolate } = Animated;
const { interpolate, Extrapolate } = Animated;
const AnimatedCircle = Animated.createAnimatedComponent(Circle);

interface PaperOnboardingPageProps {
index: number;
Expand All @@ -33,10 +35,15 @@ export const PaperOnboardingPage = (props: PaperOnboardingPageProps) => {
} = props;

// memo
const pageBackgroundExtendedSize = useMemo(
() => screenDimensions.height * 2,
const backgroundExtendedSize = useMemo(
() => screenDimensions.height,
// () => 40,
[screenDimensions]
);
const backgroundBottomPosition = useMemo(
() => screenDimensions.height - indicatorSize / 2 - safeInsets.bottom,
[screenDimensions, indicatorSize, safeInsets]
);

// animations
const animatedContentOpacity = interpolate(currentIndex, {
Expand All @@ -61,15 +68,16 @@ export const PaperOnboardingPage = (props: PaperOnboardingPageProps) => {
extrapolate: Extrapolate.CLAMP,
});

const animatedBackgroundScale = interpolate(currentIndex, {
const animatedBackgroundSize = interpolate(currentIndex, {
inputRange: [index - 1, index],
outputRange: [0, 1],
outputRange: [0, backgroundExtendedSize],
extrapolate: Extrapolate.CLAMP,
});

const animatedBackgroundLeftPosition = sub(
const animatedBackgroundLeftPosition = add(
animatedIndicatorsContainerPosition,
pageBackgroundExtendedSize / 2 - indicatorSize / 2 - index * indicatorSize
indicatorSize / 2,
index * indicatorSize
);

// styles
Expand Down Expand Up @@ -116,37 +124,22 @@ export const PaperOnboardingPage = (props: PaperOnboardingPageProps) => {
[animatedImageTopPosition]
);

const backgroundStyle = useMemo(
() => [
styles.background,
{
backgroundColor: item.color,
width: pageBackgroundExtendedSize,
height: pageBackgroundExtendedSize,
borderRadius: pageBackgroundExtendedSize,
top:
screenDimensions.height -
indicatorSize / 2 -
pageBackgroundExtendedSize / 2 -
safeInsets.bottom,
left: animatedBackgroundLeftPosition,
transform: [{ scale: animatedBackgroundScale }],
},
],
[
item,
animatedBackgroundLeftPosition,
animatedBackgroundScale,
screenDimensions,
pageBackgroundExtendedSize,
safeInsets,
indicatorSize,
]
);

return (
<Animated.View style={styles.container}>
<Animated.View style={backgroundStyle} />
<Svg
style={styles.background}
width={screenDimensions.width}
height={screenDimensions.height}
needsOffscreenAlphaCompositing={true}
renderToHardwareTextureAndroid={true}
>
<AnimatedCircle
cx={animatedBackgroundLeftPosition}
cy={backgroundBottomPosition}
r={animatedBackgroundSize}
fill={item.color}
/>
</Svg>
<Animated.View style={contentContainerStyle}>
{item.image && (
<Animated.View style={imageContainerStyle}>
Expand Down
2 changes: 1 addition & 1 deletion src/page/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ export const styles = StyleSheet.create({
fontSize: 18,
},
background: {
position: 'absolute',
...StyleSheet.absoluteFillObject,
},
});

0 comments on commit 2d56530

Please sign in to comment.