Skip to content

Instantly share code, notes, and snippets.

@tanner-west
Created September 18, 2023 11:16
Show Gist options
  • Save tanner-west/4093c8c251eada8edcaaa65cde8f3db9 to your computer and use it in GitHub Desktop.
Save tanner-west/4093c8c251eada8edcaaa65cde8f3db9 to your computer and use it in GitHub Desktop.
import "react-native-gesture-handler";
import Animated, {
withTiming,
LayoutAnimationsValues,
FadeIn,
} from "react-native-reanimated";
import { StatusBar } from "expo-status-bar";
import {
SafeAreaView,
StyleSheet,
Text,
TouchableOpacity,
View,
TextInput,
useWindowDimensions,
} from "react-native";
import { getRandomElement } from "../util";
import { useState } from "react";
import * as Crypto from "expo-crypto";
interface ISquare {
id: string;
height: number;
width: number;
backgroundColor: string;
text: string;
}
const colors = ["#7D82B8", "#B7E3CC", "#C4FFB2", "#D6F7A3"];
const paragraphs = [
"buy milk",
"visit grandma",
"walk dog",
"@useRNRocket",
"check twitter",
"write poem",
"finish novel",
"cook dinner",
"clean kitchen",
"pay taxes",
"take out trash",
];
const Note = ({
id,
backgroundColor,
height,
width,
text,
}: {
id: string;
backgroundColor: string;
height: number;
width: number;
text: string;
}) => {
const layoutTransition = (values: LayoutAnimationsValues) => {
"worklet";
return {
animations: {
originX: withTiming(values.targetOriginX, { duration: 250 }),
originY: withTiming(values.targetOriginY, { duration: 250 }),
},
initialValues: {
originX: values.currentOriginX,
originY: values.currentOriginY,
},
};
};
return (
<Animated.View
key={id}
style={[styles.noteContainer, { backgroundColor, height, width }]}
layout={layoutTransition}
entering={FadeIn.duration(800)}
>
<Text style={styles.noteText}>{text}</Text>
</Animated.View>
);
};
export default function LayoutScreen() {
const { width } = useWindowDimensions();
const elementDimensions = width * 0.4;
const [squares, setSquares] = useState<ISquare[]>([]);
const [text, setText] = useState("");
const onAddSquare = () => {
const nextColor = getRandomElement(colors);
setSquares([
{
height: elementDimensions,
width: elementDimensions,
backgroundColor: nextColor,
text: text,
id: Crypto.randomUUID(),
},
...squares,
]);
setText(getRandomElement(paragraphs));
};
return (
<SafeAreaView style={styles.container}>
<StatusBar style="light" />
<Animated.View style={styles.squareContainer}>
{squares.map(({ id, height, width, backgroundColor, text }, index) => (
<Note
key={id}
id={id}
height={height}
width={width}
backgroundColor={backgroundColor}
text={text}
/>
))}
</Animated.View>
<View style={{ justifyContent: "center", flex: 1, alignItems: "center" }}>
<TextInput
onKeyPress={({ nativeEvent: { key: keyValue } }) => {
console.log(keyValue);
}}
autoCapitalize="none"
autoCorrect={false}
onChangeText={(text) => setText(text)}
value={text}
style={[
styles.textInput,
{
width: width - 30,
},
]}
/>
</View>
<TouchableOpacity onPress={onAddSquare} style={styles.button}>
<Text style={{ color: "#444444", fontSize: 36 }}>Save Note</Text>
</TouchableOpacity>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
inputContainer: {
borderColor: "black",
borderWidth: 1,
borderStyle: "dotted",
margin: 15,
justifyContent: "center",
},
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#282B28",
},
text: {
fontSize: 48,
fontWeight: "bold",
},
indicator: {
height: 20,
width: 20,
borderColor: "black",
borderWidth: 1,
backgroundColor: "black",
position: "absolute",
left: 15,
},
squareContainer: { flex: 6, paddingLeft: 15, flexWrap: "wrap" },
textInput: {
flex: 1,
backgroundColor: "white",
fontSize: 36,
textAlign: "center",
color: "#444444",
padding: 15,
},
button: {
flex: 1,
backgroundColor: "#D6F7A3",
margin: 15,
justifyContent: "center",
alignContent: "center",
alignItems: "center",
borderRadius: 30,
},
noteContainer: {
margin: 5,
justifyContent: "center",
alignItems: "center",
},
noteText: {
padding: 10,
color: "#444444",
fontWeight: "bold",
fontSize: 24,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment