Skip to content
Snippets Groups Projects
Commit 0898f6d5 authored by 화균 김's avatar 화균 김
Browse files

feat: add animate & transitions

parent 15c44682
Branches
No related tags found
No related merge requests found
......@@ -8,7 +8,7 @@ export async function GET() {
} catch (error) {
console.error('Error in sentence API:', error);
return NextResponse.json(
{ error: '문장을 불러오는데 실패했습니다.' },
{ result: false,error: '문장을 불러오는데 실패했습니다.' },
{ status: 500 }
);
}
......
......@@ -6,6 +6,7 @@ import * as S from '@/style/App.style';
// hooks
import { useBookInfo } from "@/hooks/useBookInfo";
import { useDelayState } from "@/hooks/useDelayState";
// components
import ScrollArea from "@/components/ScrollArea";
......@@ -16,6 +17,7 @@ import LinkButton from "@/components/LinkButton";
export default function Home() {
const [loading, error, book_info] = useBookInfo();
const delay_loading = useDelayState(loading, 200);
const [scroll, setScroll] = useState(0);
const button_link = useMemo(() => {
......@@ -27,9 +29,15 @@ export default function Home() {
<S.StyledSection>
<S.TopLogo src="/ajoulib_logo_4x.png" alt="AjouLib Logo" />
<PageTitleArea scroll={scroll}/>
<ScrollArea book_info={book_info} onScroll={setScroll}/>
<LinkButton scroll={scroll} href={button_link}/>
<StyleElements scroll={scroll}/>
<S.LoadingCharacterContainer className={!loading ? "fading" : ""}>
<S.LoadingCharacter src="/ajoulib_reading_chito.png" alt="AjouLib Chito"/>
</S.LoadingCharacterContainer>
<ScrollArea
book_info={!delay_loading ? book_info : null} onScroll={setScroll}
className={!loading ? "visibling" : ""}
/>
<LinkButton scroll={scroll} href={button_link}/>
<StyleElements scroll={scroll}/>
</S.StyledSection>
</S.AppSection>
</S.GlobalSection>;
......
import { useState, useEffect, useRef } from "react";
import { useState, useEffect, useRef, HTMLAttributes } from "react";
// style
import * as S from "./style";
......@@ -15,9 +15,9 @@ import TextArea from "@/components/TextArea";
type ScrollAreaProps = {
book_info: BookInfo | null;
onScroll: (v: number) => void;
}
} & Omit<HTMLAttributes<HTMLTableSectionElement>, "onScroll">;
const ScrollArea: React.FC<ScrollAreaProps> = ({ book_info, onScroll }) => {
const ScrollArea: React.FC<ScrollAreaProps> = ({ book_info, onScroll, ...props }) => {
const [scroll, handleScroll] = useScrollState();
......@@ -28,6 +28,7 @@ const ScrollArea: React.FC<ScrollAreaProps> = ({ book_info, onScroll }) => {
return <S.ScrollAreaWrap
onScroll={handleScroll}
style={{marginTop: `-${Math.min(scroll/2, 30)}%`}}
{...props}
>
<IntroArea topRate={scroll} info={book_info}/>
<TextArea topRate={scroll} sentence={book_info?.sentence || ""}/>
......
......@@ -8,6 +8,19 @@ export const ScrollAreaWrap = styled.section`
overflow-y: auto;
opacity: 0;
transform: scale(0.9);
transition: opacity .2s cubic-bezier(0, 1, 1, 1);
&.visibling {
opacity: 1;
transform: scale(1);
}
&::-webkit-scrollbar {
display: none;
}
@media (min-height: 760px) {
margin-top: 0 !important;
}
......
import { useEffect } from "react";
import { useState } from "react";
export const useDelayState = (initialState: any, delay: number) => {
const [state, setState] = useState(initialState);
useEffect(() => {
setTimeout(() => setState(initialState), delay);
}, [initialState, delay]);
return state;
};
\ No newline at end of file
import styled from "styled-components";
import { breathe, breathe_out } from "./App.transition";
export const GlobalSection = styled.section`
width: 100vw;
......@@ -24,6 +25,45 @@ export const AppSection = styled.section`
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
@media screen and (max-width: 650px) {
width: 100%;
height: 100%;
border-radius: 0;
}
`;
export const LoadingCharacterContainer = styled.section`
width: 12rem;
height: 12rem;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 1;
transition: opacity .2s cubic-bezier(0, 1, 1, 1);
&.fading {
opacity: 0;
}
`;
export const LoadingCharacter = styled.img`
width: 12rem;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: ${breathe} 1.5s cubic-bezier(0, 1, 1, 1) infinite;
transition: opacity 2s ease-in-out, animation 0.2s ease-out;
z-index: 1;
`;
export const StyledSection = styled.section`
......
import { keyframes } from "styled-components";
export const breathe = keyframes`
0% {
transform: translate(-50%, -50%) scale(0.9);
opacity: 0.3;
}
50% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(0.9);
opacity: 0.3;
}
`;
export const breathe_out = keyframes`
99% {
transform: translate(-50%, -50%) scale(0.9);
opacity: 0;
}
100% {
display: none;
}
`;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment