Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add animated cascade demo #138

Merged
merged 30 commits into from
May 28, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
cyan testing text etc
Christopher David committed May 27, 2023

Verified

This commit was signed with the committer’s verified signature.
nickvergessen Joas Schilling
commit 36238795eb735c0c699c3b0da38a18bc43848c77
2 changes: 1 addition & 1 deletion app/components/BackgroundGradient.tsx
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ const BackgroundGradient: React.FC<BackgroundGradientProps> = React.memo(({ widt
>
<SweepGradient
c={vec((width + canvasPadding) / 2, (height + canvasPadding) / 2)}
colors={["cyan", "magenta", "yellow", "cyan"]}
colors={["cyan", "rgb(0,248,248)", "rgb(0,248,248)", "cyan"]}
/>
<BlurMask blur={skValue} style={"solid"} />
</RoundedRect>
109 changes: 109 additions & 0 deletions app/screens/SkiaDemoScreen-cyan.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { StatusBar } from "expo-status-bar"
import React from "react"
import { Dimensions, StyleSheet, View } from "react-native"
import { Gesture, GestureDetector, GestureHandlerRootView } from "react-native-gesture-handler"
import Animated, {
Extrapolate,
interpolate,
useAnimatedStyle,
useSharedValue,
withTiming,
} from "react-native-reanimated"
import { BackgroundGradient } from "../components/BackgroundGradient"
import { Canvas, Text, useFont, Fill } from "@shopify/react-native-skia"
import { customFontsToLoad } from "app/theme"

const { width: SCREEN_WIDTH } = Dimensions.get("window")
const HEIGHT = 256
const WIDTH = SCREEN_WIDTH * 0.9

const CARD_HEIGHT = HEIGHT - 5
const CARD_WIDTH = WIDTH - 5

function App() {
const rotateX = useSharedValue(0)
const rotateY = useSharedValue(0)
const font = useFont(customFontsToLoad.protomolecule, 24)

const gesture = Gesture.Pan()
.onBegin((event) => {
rotateX.value = withTiming(
interpolate(event.y, [0, CARD_HEIGHT], [10, -10], Extrapolate.CLAMP),
)
rotateY.value = withTiming(
interpolate(event.x, [0, CARD_WIDTH], [-10, 10], Extrapolate.CLAMP),
)
})
.onUpdate((event) => {
// topLeft (10deg, -10deg)
// topRight (10deg, 10deg)
// bottomRight (-10deg, 10deg)
// bottomLeft (-10deg, -10deg)

rotateX.value = interpolate(event.y, [0, CARD_HEIGHT], [10, -10], Extrapolate.CLAMP)
rotateY.value = interpolate(event.x, [0, CARD_WIDTH], [-10, 10], Extrapolate.CLAMP)
})
.onFinalize(() => {
rotateX.value = withTiming(0)
rotateY.value = withTiming(0)
})

const rStyle = useAnimatedStyle(() => {
const rotateXvalue = `${rotateX.value}deg`
const rotateYvalue = `${rotateY.value}deg`

return {
transform: [
{
perspective: 300,
},
{ rotateX: rotateXvalue },
{ rotateY: rotateYvalue },
],
}
}, [])

return (
<View style={styles.container}>
<StatusBar style="light" />
<BackgroundGradient width={WIDTH} height={HEIGHT} />
<GestureDetector gesture={gesture}>
<Animated.View
style={[
{
height: CARD_HEIGHT,
width: CARD_WIDTH,
backgroundColor: "black",
position: "absolute",
borderRadius: 20,
zIndex: 300,
},
rStyle,
]}
>
<Canvas style={{ position: "absolute", left: 30, bottom: 20, zIndex: 400 }}>
<Fill color="cyan" />
<Text text="Incoming message:" font={font} x={0} y={30} color="cyan" />
</Canvas>
</Animated.View>
</GestureDetector>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "black",
},
})

export const SkiaDemoScreen = () => {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<App />
</GestureHandlerRootView>
)
}
143 changes: 143 additions & 0 deletions app/screens/SkiaDemoScreen-eh.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { StatusBar } from "expo-status-bar"
import React from "react"
import { Dimensions, StyleSheet, View } from "react-native"
import { Gesture, GestureDetector, GestureHandlerRootView } from "react-native-gesture-handler"
import Animated, {
Extrapolate,
interpolate,
useAnimatedStyle,
useSharedValue,
withTiming,
} from "react-native-reanimated"
import { BackgroundGradient } from "../components/BackgroundGradient"

const { width: SCREEN_WIDTH } = Dimensions.get("window")
const HEIGHT = 256
const WIDTH = SCREEN_WIDTH * 0.9

const CARD_HEIGHT = HEIGHT - 5
const CARD_WIDTH = WIDTH - 5

function App() {
const rotateX = useSharedValue(0)
const rotateY = useSharedValue(0)

const gesture = Gesture.Pan()
.onBegin((event) => {
rotateX.value = withTiming(
interpolate(event.y, [0, CARD_HEIGHT], [10, -10], Extrapolate.CLAMP),
)
rotateY.value = withTiming(
interpolate(event.x, [0, CARD_WIDTH], [-10, 10], Extrapolate.CLAMP),
)
})
.onUpdate((event) => {
// topLeft (10deg, -10deg)
// topRight (10deg, 10deg)
// bottomRight (-10deg, 10deg)
// bottomLeft (-10deg, -10deg)

rotateX.value = interpolate(event.y, [0, CARD_HEIGHT], [10, -10], Extrapolate.CLAMP)
rotateY.value = interpolate(event.x, [0, CARD_WIDTH], [-10, 10], Extrapolate.CLAMP)
})
.onFinalize(() => {
rotateX.value = withTiming(0)
rotateY.value = withTiming(0)
})

const rStyle = useAnimatedStyle(() => {
const rotateXvalue = `${rotateX.value}deg`
const rotateYvalue = `${rotateY.value}deg`

return {
transform: [
{
perspective: 300,
},
{ rotateX: rotateXvalue },
{ rotateY: rotateYvalue },
],
}
}, [])

return (
<View style={styles.container}>
<StatusBar style="light" />
<BackgroundGradient width={WIDTH} height={HEIGHT} />
<GestureDetector gesture={gesture}>
<Animated.View
style={[
{
height: CARD_HEIGHT,
width: CARD_WIDTH,
backgroundColor: "black",
position: "absolute",
borderRadius: 20,
zIndex: 300,
},
rStyle,
]}
>
<View
style={{
position: "absolute",
bottom: "10%",
left: "10%",
flexDirection: "row",
}}
>
<View
style={{
height: 50,
aspectRatio: 1,
borderRadius: 25,
backgroundColor: "#272F46",
}}
/>
<View
style={{
flexDirection: "column",
marginLeft: 10,
justifyContent: "space-around",
}}
>
<View
style={{
height: 20,
width: 80,
borderRadius: 25,
backgroundColor: "#272F46",
}}
/>
<View
style={{
height: 20,
width: 80,
borderRadius: 25,
backgroundColor: "#272F46",
}}
/>
</View>
</View>
</Animated.View>
</GestureDetector>
</View>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "black",
},
})

export const SkiaDemoScreen = () => {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<App />
</GestureHandlerRootView>
)
}