I'm using react-native-web
to develop a web&mobile application. I've reached the point when I'd like to introduce better transitions between the screens, and for that reason I'd like to do shared element transitions like the one below:
Because I started with @react-navigation/stack
for my routing, I wanted to use a library that would support the same structure I have. It took me quite some time to get the react-navigation-shared-element
library working, but it has finally compiled. Unfortunately, the animations aren't looking like I wanted them to:
As you can see, there is no animation really. It simply switches the page. I've spent weeks on this issue attempting different config, libraries, and generally everything, and I have nearly given up and started looking for web-only libraries to split the code into two different versions.
Therefore, I kindly request assistance to get the code working with one library or, if you think there are better solutions, an alternative selection of web-only and mobile-only libraries which I could use to keep roughly the same codebase (for example by wrapping library components into something I can use in the code).
Here's the code I have for my current animation:
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createSharedElementStackNavigator, SharedElement} from 'react-navigation-shared-element';
import {View, TouchableOpacity, Text} from 'react-native';
const Stack = createSharedElementStackNavigator();
function A({navigation}) {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('B')}>GO</TouchableOpacity>
<SharedElement id={'shared'}>
<Text style={{position: 'absolute', top: 50, background: 'yellow'}}>Start screen</Text>
</SharedElement>
</View>
);
}
function B({navigation}) {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('A')}>GO</TouchableOpacity>
<SharedElement id={'shared'}>
<Text style={{position: 'absolute', top: 100, background: 'yellow'}}>Start screen</Text>
</SharedElement>
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name={'A'} component={A} />
<Stack.Screen
name={'B'}
component={B}
sharedElements={(route, otherRoute, showing) => {
return [
{
id: 'shared',
animation: 'move',
},
];
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
Here are the relevant libraries I am using:
"@react-navigation/native": "^6.0.2",
"@react-navigation/stack": "^6.0.7",
"react-native-shared-element": "^0.8.2",
"react-navigation-shared-element": "^3.1.3"
And, finally, here's my webpack
config, which I added it only to support the shared elements library, so I have no idea if it's good or not. I'm quite new to React, so I don't know if there are things like loaders or presets required to support the shared elements animations missing.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');
const appDirectory = path.resolve(__dirname);
const babelLoaderConfiguration = {
test: /\.js$/,
include: [
path.resolve(appDirectory, 'src'),
],
use: {
loader: 'babel-loader',
options: {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-web'],
},
},
};
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
esModule: false,
},
},
};
module.exports = {
entry: path.resolve(appDirectory, 'src', 'index.js'),
output: {
filename: 'bundle.web.js',
path: path.resolve(appDirectory, 'build'),
},
devtool: 'source-map',
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(appDirectory, 'public', 'index.html'),
filename: 'index.html',
}),
new Dotenv({
path: path.resolve(appDirectory, '.env'),
safe: true,
}),
],
resolve: {
alias: {
'react-native$': 'react-native-web',
},
extensions: ['.web.js', '.js'],
},
};
Try to use minus margin with useState in one component :
LIVE example - https://snack.expo.dev/8ZCuner6B