Skip to content

Commit

Permalink
Merge pull request #22 from tweag/blog/image-transition-react-native
Browse files Browse the repository at this point in the history
add image-transition blog post resources
  • Loading branch information
simeoncarstens authored Jun 27, 2024
2 parents d220806 + b97338a commit 81e30b2
Show file tree
Hide file tree
Showing 14 changed files with 23,965 additions and 0 deletions.
28 changes: 28 additions & 0 deletions image-transition/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/

# Native
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision



# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem
151 changes: 151 additions & 0 deletions image-transition/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { Canvas, Fill, ImageShader, Shader } from "@shopify/react-native-skia";
import { Dimensions, StyleSheet, View, Pressable, Alert } from "react-native";
import { AntDesign } from "@expo/vector-icons";
import { useAssets } from "./useAssets";
import { source } from "./transitions";
import {
runOnJS,
useDerivedValue,
useSharedValue,
withTiming,
} from "react-native-reanimated";
import { useCallback } from "react";

export default function App() {
const offset = useSharedValue(0);
const progressPrev = useSharedValue(1);
const progressNext = useSharedValue(0);
const isNext = useSharedValue(false);


const assets = useAssets();
const { width, height } = Dimensions.get("window");

const updateNext = useCallback((param: boolean) => {

isNext.value = param;
}, []);

const next = useCallback(() => {
offset.value += 1;
progressNext.value = 0;
}, []);

const prev = useCallback(() => {
offset.value -= 1;
progressPrev.value = 1;
}, []);

const handleClickNext = () => {

updateNext(true)
progressNext.value = withTiming(
1,
{
duration: 1000,
},
() => {
runOnJS(next)();
}
);
};

const handleClickPrevious = () => {
updateNext(false)
progressPrev.value = withTiming(
0,
{
duration: 1000,
},
() => {
runOnJS(prev)();
}
);
};

const getAsset = useCallback(
(index: number) => {
"worklet";
if (assets === null) {
return null;
}
return assets[((index % assets.length) + assets.length) % assets.length];
},
[assets]
);

const progress = useDerivedValue(() => {
return isNext.value ? progressNext.value : progressPrev.value;
});

const uniform = useDerivedValue(() => {
return {
progress: progress.value,
resolution: [width, height],
};
});

const image1 = useDerivedValue(() => {
return getAsset(isNext.value ? offset.value : offset.value - 1);
});

const image2 = useDerivedValue(() => {
return getAsset(isNext.value ? offset.value + 1 : offset.value);
});
if (!assets) {
return null;
}
return (
<View style={styles.container}>
<View style={styles.buttons}>
<Pressable onPress={handleClickPrevious} disabled={progressPrev.value > 0 && progressPrev.value< 1} style={styles.button}>
<AntDesign name="left" size={24} color="black" />
</Pressable>
<Pressable onPress={handleClickNext} style={styles.button}>
<AntDesign name="right" size={24} color="black" />
</Pressable>
</View>

<Canvas style={styles.container}>
<Fill>
<Shader source={source} uniforms={uniform}>
<ImageShader
fit="cover"
image={image1}
width={width}
height={height}
/>

<ImageShader
fit="cover"
image={image2}
width={width}
height={height}
/>
</Shader>
</Fill>
</Canvas>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
button: {
backgroundColor: "white",
alignItems: "center",
justifyContent: "center",
padding: 10,
borderRadius: 16,
},
buttons: {
position: "absolute",
bottom: 80,
right: 40,
zIndex: 10,
flexDirection: "row",
gap: 16,
},
});
7 changes: 7 additions & 0 deletions image-transition/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# How to run the app

- In the root directory of `image-transition`, run `npm install`, node_modules should now be present
- Download Expo Go on your android/ios device, See: https://expo.dev/go
- Then run `npm run start`, a QR code will appear on the terminal
- Scan the QR code with your device's camera, this will automatically load the app in Expo Go.
- Link to Expo Snack: https://snack.expo.dev/@wumz/image-transition?platform=ios
30 changes: 30 additions & 0 deletions image-transition/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"expo": {
"name": "image-transitionn",
"slug": "image-transitionn",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
Binary file added image-transition/assets/adaptive-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-transition/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-transition/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image-transition/assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions image-transition/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
Loading

0 comments on commit 81e30b2

Please sign in to comment.