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

[Feat] : spring theme 추가 #399 #406

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
Binary file added public/cats/spring/sit.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added public/cats/spring/sit.webm
Empty file.
20 changes: 20 additions & 0 deletions public/create/springFlower.svg
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 public/preview/Spring.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/app/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function Create() {
const [isNext, setIsNext] = useState(false);
const [preview, setPreview] = useState(1);

const themelist = ['sul', 'night', 'peach', 'lilac', 'chris', 'mas'];
const themelist = ['spring', 'night', 'peach', 'lilac', 'sul'];

const handleTitleSwitch = (value: string) => {
setIsOff((prevIsOff) => (prevIsOff === value ? '' : value));
Expand All @@ -40,6 +40,8 @@ export default function Create() {
const data = {
theme: themelist[preview - 1],
title: `${title}`,
public: false,
// 백엔드와 규격을 맞추기위해 임시로 넣어둔 값
};
axiosPostBoard(data)
.then((res) => {
Expand Down
13 changes: 8 additions & 5 deletions src/app/personal/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
WriterButtonLayer,
} from '@/component/Personal';
import FirstContent from '@/component/Personal/FirstContent';
import SakuraAnimation from '@/component/Personal/SakuraAnimation';
import { useLogin } from '@/hooks/useLogin';
import useModal from '@/hooks/useModal';
import { useScroll } from '@/hooks/useScroll';
Expand All @@ -25,7 +26,7 @@ import { board } from '@/types/boards';
import { History } from '@/types/history';
import { personalPage } from '@/types/mixpanel';
import { noneTheme, themeState } from '@/types/theme';
import { chris, lilac, mas, night, peach, sul } from '@/types/theme';
import { chris, lilac, mas, night, peach, spring, sul } from '@/types/theme';
import { axiosGetBoard, axoisDeleteContents } from '@/utils/apiInterface';
import { confirm } from '@/utils/confirm';
import { defaultState } from '@/utils/theme/default';
Expand All @@ -43,8 +44,8 @@ export default function Personal({ params }: { params: { id: string } }) {
const { isHidden, setIsHidden } = useScroll();
const [checkedSet, setCheckedSet] = useState(new Set());
const [openModal, closeModal] = useModal();
const addHistory = ()=>{

const addHistory = () => {
const timestamp = () => {
var now = new Date();
now.setHours(now.getHours() + 9);
Expand All @@ -70,7 +71,7 @@ export default function Personal({ params }: { params: { id: string } }) {
title: title,
});
localStorage.setItem('history', JSON.stringify(historyArray));
}
};

useEffect(() => {
const token = localStorage.getItem('strcat_token');
Expand Down Expand Up @@ -202,8 +203,9 @@ export default function Personal({ params }: { params: { id: string } }) {
return (
<>
<div className={`${defaultState.background} min-h-full`}>
<div onClick={handleClickBackground}>
<div onClick={handleClickBackground} className="h-full w-full">
<SnowAnimation themeName={theme.name} />
<SakuraAnimation themeName={theme.name} />
<div className="z-text relative">
<FirstContent
boardLength={board[0].contents.length}
Expand Down Expand Up @@ -306,5 +308,6 @@ const getTheme = (themeName: string): themeState => {
if (themeName === 'peach') return peach;
if (themeName === 'lilac') return lilac;
if (themeName === 'sul') return sul;
if (themeName === 'spring') return spring;
return night;
};
1 change: 1 addition & 0 deletions src/component/Common/Icon/PhotoPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ const getColor = (color: string) => {
if (color === 'bg-strcat-lilac') return '#D7C4FF';
if (color === 'bg-strcat-chris') return '#246F50';
if (color === 'bg-strcat-mas') return '#DE6565';
if (color === 'bg-strcat-spring') return '#FFBACF';
};
8 changes: 4 additions & 4 deletions src/component/Create/ThemeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export default function ThemeSelect({
defaultState,
}: Props) {
return (
<div className="flex w-full flex-row">
<div className="flex w-full items-center justify-between">
{themes.map((theme) => (
<div
key={theme.id}
className="flex basis-1/5 flex-col items-center justify-center"
className="flex flex-col items-center justify-center"
>
<div
className={`${theme.bgStyle} h-[45px] w-[45px] rounded-full ${
Expand All @@ -32,14 +32,14 @@ export default function ThemeSelect({
}`}
onClick={() => setPreview(theme.id)}
>
<div className="flex justify-center items-center h-[43px] pt-[5px]">
<div className="flex justify-center items-center h-[43px]">
{theme.image && (
<Image
src={theme.image}
width={theme.name === '설날' ? 19 : 42}
height={theme.name === '설날' ? 21 : 43}
alt={theme.name}
className="z-10"
className={`${theme.name === '봄' ? '' : 'mt-[5px]'} z-10`}
/>
)}
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/component/Create/getThemes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ interface Theme {

export const getThemes = (...themelist: string[]): ThemeArray[] => {
const allThemes: Record<string, Theme> = {
spring: {
name: '봄',
image: '/create/springFlower.svg',
bgStyle: 'bg-strcat-spring',
preview: '/preview/spring.png',
},
sul: {
name: '설날',
image: '/create/sulHat.svg',
Expand Down
4 changes: 2 additions & 2 deletions src/component/Personal/BottomAnimationImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ export default function BottomAnimationImage({
<Image
alt={`sit${themeName}`}
src={`/cats/${themeName}/sit.gif`}
width={35}
width={themeName === 'spring' ? 60.73 : 35}
height={41}
className="w-[35px] h-[41px]"
className="min-w-[35px] h-[41px]"
priority
/>
</div>
Expand Down
66 changes: 66 additions & 0 deletions src/component/Personal/SakuraAnimation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { CSSProperties, useEffect, useMemo, useState } from 'react';

const SakuraFlakes = ({
style,
animation,
}: {
style: CSSProperties;
animation: string;
}) => {
/* 꽃잎 만들기. */
return (
<span
id="sakura"
style={style}
className={`${animation} absolute rounded-tl-[12px] rounded-br-[12px] rounded-bl-[1px] opacity-0 rounded-tr-[1px] bg-[#ffb6c1]`}
></span>
);
};

const random = (num: number) => {
return Math.floor(Math.random() * num);
};

const makeSakuraFlakes = () => {
// 50개의 꽃잎을 만들어서 배열에 담아서 반환
const arr = Array.from({ length: 100 });

return arr.map((_, i) => {
const animationDelay = `${random(16000)}ms`;
// 0초-40초 랜덤 딜레이
const size = `${random(10) + 5}px`;
// 5-15px 랜덤 사이즈
const startPosition = `${random(100)}%`;
// 0-100% 랜덤 시작 위치
const style = {
animationDelay: animationDelay,
left: startPosition,
width: size,
height: size,
};
const animation = i < 50 ? 'animate-sakura1' : 'animate-sakura2';
return <SakuraFlakes key={i} style={style} animation={animation} />;
});
};

export default function SakuraAnimation({ themeName }: { themeName: string }) {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
setLoaded(true);
}, [setLoaded]);
const sakuraFlakes = useMemo(() => makeSakuraFlakes(), []);

if (themeName !== 'spring') return;
return (
loaded && (
<div
id="sakura-container"
className="fixed flex h-full w-full max-w-md select-none justify-between"
>
<div id="sakura" className="absolute w-full h-full max-w-md">
{sakuraFlakes}
</div>
</div>
)
);
}
2 changes: 1 addition & 1 deletion src/types/boards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { content } from './content';
export interface board {
id: string;
title: string;
theme: 'night' | 'peach' | 'lilac' | 'chris' | 'mas' | 'sul';
theme: 'night' | 'peach' | 'lilac' | 'chris' | 'mas' | 'sul' | 'spring';
contents: content[];
}
9 changes: 9 additions & 0 deletions src/types/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
nightBg,
noneBg,
peachBg,
springBg,
sulBg,
} from '@/utils/theme/bgTheme';
import {
Expand All @@ -15,6 +16,7 @@ import {
nightText,
noneText,
peachText,
springText,
sulText,
textThemeState,
} from '@/utils/theme/textTheme';
Expand Down Expand Up @@ -61,6 +63,12 @@ export const sul: themeState = {
bgTheme: sulBg,
};

export const spring: themeState = {
name: 'spring',
textTheme: springText,
bgTheme: springBg,
};

export const noneTheme: themeState = {
name: '',
textTheme: noneText,
Expand All @@ -74,4 +82,5 @@ export const themeObj = {
chris: chris,
mas: mas,
sul: sul,
spring: spring,
};
6 changes: 6 additions & 0 deletions src/utils/theme/bgTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export const sulBg: bgThemeState = {
addRightCTA: 'bg-strcat-sul',
};

export const springBg: bgThemeState = {
highlight: 'bg-strcat-spring',
rightCTA: 'bg-strcat-spring',
addRightCTA: 'bg-strcat-spring',
};

export const noneBg: bgThemeState = {
highlight: '',
rightCTA: '',
Expand Down
7 changes: 7 additions & 0 deletions src/utils/theme/textTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ export const sulText: textThemeState = {
addRightCTA: 'text-default-black',
};

export const springText: textThemeState = {
writer: 'text-strcat-spring',
highlight: 'text-default-black',
rightCTA: 'text-default-black',
addRightCTA: 'text-default-black',
};

export const noneText: textThemeState = {
writer: '',
highlight: '',
Expand Down
37 changes: 37 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = {
'strcat-chris': '#246F50',
'strcat-mas': '#DE6565',
'strcat-sul': '#82CBFF',
'strcat-spring': '#FFBACF',
},
keyframes: {
slide: {
Expand Down Expand Up @@ -76,8 +77,44 @@ module.exports = {
from: { backgroundColor: 'rgba(0,0,0,0.8)' },
to: { backgroundColor: 'rgba(0,0,0,0)' },
},
sakuraSway1: {
'0%': { transform: 'rotate(-5deg))' },
'40%': { transform: 'rotate(28deg)' },
'100%': { transform: 'rotate(3deg)' },
},
sakuraSway2: {
'0%': { transform: 'rotate(10deg))' },
'40%': { transform: 'rotate(43deg)' },
'100%': { transform: 'rotate(15deg)' },
},
sakuraFalling1: {
'0%': {
opacity: 0,
top: '-10%',
transform: 'translateX(0) rotate(0deg)',
},
'10%': { opacity: 1 },
'100%': {
opacity: 1,
top: '100%',
transform: 'translateX(210px) rotateX(180deg) rotateY(360deg)',
},
},
sakuraFalling2: {
'0%': { opacity: 0, top: '-10%', transform: 'translateX(0)' },
'10%': { opacity: 1 },
'100%': {
opacity: 1,
top: '100%',
transform: 'translateX(-210px) rotateX(180deg) rotateY(360deg)',
},
},
},
animation: {
sakura1:
'sakuraSway1 2s linear 0s infinite, sakuraFalling1 10s 0s linear infinite',
sakura2:
'sakuraSway2 2s linear 0s infinite, sakuraFalling2 10s 0s linear infinite',
slide: 'slide 0.7s linear',
fadeIn: 'fadeIn 2s ease-in-out',
textFadeIn: 'textFadeIn 0.35s ease-in-out',
Expand Down