728x90
반응형
안녕하세요. 짭짭이 입니다.
간단하게 작업한 것을 작성하도록 하겠습니다.
색에 대해 도와 주는 Helper API
interface Colors {
white: string;
black: string;
grayBG: string;
neutral: (opacity: number) => string;
}
interface FontWeights {
// Define font weight properties here if needed
medium: "500";
semibold: "600";
bold: "700";
}
interface Radius {
// Define radius properties here if needed
xs: number;
sm: number;
md: number;
lg: number;
xl: number;
}
interface Theme {
colors: Colors;
fontWeights: FontWeights;
radius: Radius;
}
export const theme: Theme = {
colors: {
white: "#fff",
black: "#000",
grayBG: "#e5e5e5",
neutral: (opacity) => `rgba(10, 10, 10, ${opacity})`,
},
fontWeights: {
medium: "500",
semibold: "600",
bold: "700",
},
radius: {
xs: 10,
sm: 12,
md: 14,
lg: 16,
xl: 18,
}
}
Dimension API를 사용하여 화면 크기를 가져와서 percentage로 계산해주는 API
import {Dimensions} from 'react-native';
//window로 부터 width와 height를 가져온다. 그리고 이것을 devicewidth와 deviceHeight로 저장한다.
const {width: devicewidth, height: deviceHeight} = Dimensions.get('window');
export const wp = (percentage: number) => {
const value = (percentage * devicewidth) / 100;
return value;
}
export const hp = (percentage: number) => {
const value = (percentage * deviceHeight) / 100;
return value;
}
RootLayout에 Auth 파일들에 대해서 Header를 가리도록 설정
<Stack screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen name='(auth)' options={ () => {
return {
headerShown: false
}
}}/>
<Stack.Screen name='(main)' />
<Stack.Screen name='(room)' />
</Stack>
<StatusBar style="auto" />
LinearGradient를 아래 명령어로 설치
npx expo install expo-linear-gradient
<LinearGradient
colors={['rgba(255,255,255,0)', 'rgba(255,255,255,0.5)', 'white', 'white']}
style={styles.gradiant}
start={{x:0.5, y:0}}
end={{x:0.5, y: 0.8}} />
해당 컴포넌트에 color는 Gradient가 시작 될 때 색의 순서이다. 점점 하양색으로 이동하는 것이다.
그리고 start는 시작점이다. X가 0이라면 가장 좌측, Y가 0이라면 가장 상단. 1은 반대로 생각하면 된다.
Animated 컴포넌트는 아래와 같이 사용했다.
import Animated, { FadeInDown } from 'react-native-reanimated';
https://docs.swmansion.com/react-native-reanimated/
React Native Reanimated
A powerful animation library that makes it easy to create smooth animations and interactions that run in the UI thread.
docs.swmansion.com
<Animated.View entering={FadeInDown.duration(1000)} style={{flex: 1}}>
.....
<View style={styles.contentContainer}>
<Animated.Text entering={FadeInDown.delay(400).springify()} style={styles.title}>Pixels</Animated.Text>
<Animated.Text entering={FadeInDown.delay(500).springify()} style={styles.punchline}>Every Pixel Tells a Story</Animated.Text>
<Animated.View entering={FadeInDown.delay(600).springify()} style={styles.startButton}>
<Pressable>
<Text style={styles.startText}>Start Explore</Text>
</Pressable>
</Animated.View>
</View>
</Animated.View>
이렇게 Animated에 View, Text에 entering으로 원하는 Animation을 쉽게 줄 수 있다.
import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet, Image, Pressable } from 'react-native';
import { Link, router } from 'expo-router';
import { wp, hp } from '@/helper/common';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, { FadeInDown } from 'react-native-reanimated';
import { theme } from '@/constants/theme';
export default function AuthRootPage() {
return (
<View style={styles.container}>
<Image style={styles.bgImage} source={require('../../assets/images/welcome.png')} resizeMode='cover' />
<Animated.View entering={FadeInDown.duration(1000)} style={{flex: 1}}>
<LinearGradient
colors={['rgba(255,255,255,0)', 'rgba(255,255,255,0.5)', 'white', 'white']}
style={styles.gradiant}
start={{x:0.5, y:0}}
end={{x:0.5, y: 0.8}} />
<View style={styles.contentContainer}>
<Animated.Text entering={FadeInDown.delay(400).springify()} style={styles.title}>Pixels</Animated.Text>
<Animated.Text entering={FadeInDown.delay(500).springify()} style={styles.punchline}>Every Pixel Tells a Story</Animated.Text>
<Animated.View entering={FadeInDown.delay(600).springify()} style={styles.startButton}>
<Pressable>
<Text style={styles.startText}>Start Explore</Text>
</Pressable>
</Animated.View>
</View>
</Animated.View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
bgImage: {
width: wp(100),
height: hp(100),
position: 'absolute',
},
gradiant: {
width: wp(100),
height: hp(65),
bottom: 0,
position: 'absolute',
},
contentContainer: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
gap: 14
},
title: {
fontSize: hp(7),
color: theme.colors.neutral(0.9),
fontWeight: theme.fontWeights.bold
},
punchline: {
fontSize: hp(2),
letterSpacing: 1,
marginBottom: 10,
fontWeight: theme.fontWeights.medium
},
startButton: {
marginBottom: 50,
backgroundColor: theme.colors.neutral(0.9),
padding: 15,
paddingHorizontal: 90,
borderRadius: theme.radius.xl,
borderCurve: 'continuous'
},
startText: {
color: theme.colors.white,
fontWeight: theme.fontWeights.medium,
letterSpacing: 1,
fontSize: hp(3)
}
});
728x90
반응형
댓글