diff --git a/front/public/models/heart.glb b/front/public/models/heart.glb new file mode 100644 index 0000000..9fe460c Binary files /dev/null and b/front/public/models/heart.glb differ diff --git a/front/public/models/star.glb b/front/public/models/star.glb new file mode 100644 index 0000000..9655689 Binary files /dev/null and b/front/public/models/star.glb differ diff --git a/front/public/models/water.glb b/front/public/models/water.glb new file mode 100644 index 0000000..f3c1400 Binary files /dev/null and b/front/public/models/water.glb differ diff --git a/front/src/components/Msg/ListMsg.tsx b/front/src/components/Msg/ListMsg.tsx index 6337ade..f1f1bc3 100644 --- a/front/src/components/Msg/ListMsg.tsx +++ b/front/src/components/Msg/ListMsg.tsx @@ -79,8 +79,7 @@ const StyledDeleteButton = styled.button``; const ListMsg = (props: MsgProps): JSX.Element => { const navigate = useNavigate(); - const { setSnowBallData, setUserData, userData, snowBallData } = - useContext(SnowBallContext); + const { setSnowBallData, setUserData } = useContext(SnowBallContext); const deleteMsg = () => { axios diff --git a/front/src/components/SnowGlobeCanvas/SnowGlobeCanvas.tsx b/front/src/components/SnowGlobeCanvas/SnowGlobeCanvas.tsx index 1f631c5..211298b 100644 --- a/front/src/components/SnowGlobeCanvas/SnowGlobeCanvas.tsx +++ b/front/src/components/SnowGlobeCanvas/SnowGlobeCanvas.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useRef } from 'react'; +import { useContext, useRef } from 'react'; import { OrbitControls } from '@react-three/drei'; import { Canvas } from '@react-three/fiber'; import * as THREE from 'three'; @@ -13,10 +13,7 @@ const SnowGlobeCanvas = () => { const glassRadius = 7; const glassPosition = new THREE.Vector3(0, glassRadius / 2, 0); const { snowBallData } = useContext(SnowBallContext); - // // debugger; - useEffect(() => { - console.log(snowBallData, 'test'); - }, [snowBallData]); + const snows = Array.from({ length: 100 }, (_, i) => ( { model={Math.floor(Math.random() * 3)} /> )); - // console.log(snowBallData, 'test'); const decos = snowBallData.message_list.map((message, index) => { return ( { /> ); }); - + const sentiments = snowBallData.message_list.map((message, i) => ( + + )); return ( @@ -96,6 +99,7 @@ const SnowGlobeCanvas = () => { /> {snows} {decos} + {sentiments} diff --git a/front/src/components/SnowGlobeCanvas/models/Emoji.tsx b/front/src/components/SnowGlobeCanvas/models/Emoji.tsx new file mode 100644 index 0000000..5ca9a66 --- /dev/null +++ b/front/src/components/SnowGlobeCanvas/models/Emoji.tsx @@ -0,0 +1,84 @@ +import { useRef } from 'react'; +import { useFrame } from '@react-three/fiber'; +import { useGLTF } from '@react-three/drei'; +import * as THREE from 'three'; +import { SENTIMENT_MODEL } from '@constants'; + +interface SnowProps { + centerPosition: THREE.Vector3; + rangeRadius: number; + sentiment: string; +} + +const randomizePosition = ( + target: THREE.Mesh, + centerPosition: THREE.Vector3, + radius: number +) => { + //변경필요 + target.position.set( + centerPosition.x - 3 + Math.random() * 6, + centerPosition.y + radius + Math.random() * radius * 2, + centerPosition.z - 3 + Math.random() * 6 + ); +}; + +const fallingAnimate = ( + target: THREE.Mesh, + speed: number, + centerPosition: THREE.Vector3, + radius: number +) => { + if (target.position.y <= -1) { + randomizePosition(target, centerPosition, radius); + //const newScale = 0.2 + Math.random() * 0.5; + //target.scale.set(newScale, newScale, newScale); + } + target.position.y -= speed; +}; + +const rotateAnimate = (target: THREE.Mesh, speed: number) => { + target.rotation.y += speed; +}; + +const visibleInRange = ( + target: THREE.Mesh, + centerPosition: THREE.Vector3, + radius: number +) => { + target.visible = + target.position.distanceTo(centerPosition) > radius ? false : true; +}; + +const Emoji: React.FC = ({ + centerPosition, + rangeRadius, + sentiment +}) => { + const snowRef = useRef(null); + const position = new THREE.Vector3( + centerPosition.x - rangeRadius + Math.random() * rangeRadius * 2, + centerPosition.y + rangeRadius + Math.random() * rangeRadius * 2, + centerPosition.z - rangeRadius + Math.random() * rangeRadius * 2 + ); + const index = sentiment === 'positive' ? 1 : sentiment === 'neutral' ? 2 : 3; + const snow = useGLTF(SENTIMENT_MODEL[index].fileName).scene.clone(); + + snow.scale.set(0.7, 0.7, 0.7); + snow.position.set(position.x, position.y, position.z); + snow.rotation.y = Math.random(); + + useFrame((_, delta) => { + const snow = snowRef.current; + const speed = 2 * delta; + if (snow) { + fallingAnimate(snow, speed, centerPosition, rangeRadius); + rotateAnimate(snow, speed); + visibleInRange(snow, centerPosition, rangeRadius - 1); + } + }); + + return ; +}; + +export default Emoji; diff --git a/front/src/components/SnowGlobeCanvas/models/index.tsx b/front/src/components/SnowGlobeCanvas/models/index.tsx index 74ab3da..25a63fb 100644 --- a/front/src/components/SnowGlobeCanvas/models/index.tsx +++ b/front/src/components/SnowGlobeCanvas/models/index.tsx @@ -5,3 +5,4 @@ export { default as Ground } from './Ground'; export { default as MainDeco } from './MainDeco'; export { default as Snow } from './Snow'; export { default as Raycaster } from './Raycaster'; +export { default as Emoji } from './Emoji'; diff --git a/front/src/components/Song/Song.tsx b/front/src/components/Song/Song.tsx index b141898..25dfc72 100644 --- a/front/src/components/Song/Song.tsx +++ b/front/src/components/Song/Song.tsx @@ -39,6 +39,7 @@ const Song = () => { return ( diff --git a/front/src/constants/deco.tsx b/front/src/constants/deco.tsx index 07ba3b3..1ec0a97 100644 --- a/front/src/constants/deco.tsx +++ b/front/src/constants/deco.tsx @@ -1,3 +1,19 @@ +export const SENTIMENT_MODEL = [ + { name: '선물상자', fileName: '/models/ribbonBox.glb', img: 'ribbonBox.png' }, + { + name: '긍정', + fileName: '/models/heart.glb' + }, + { + name: '보통', + fileName: '/models/star.glb' + }, + { + name: '부정', + fileName: '/models/water.glb' + } +]; + export const DECO = [ { name: '선물상자', fileName: '/models/ribbonBox.glb', img: 'ribbonBox.png' }, { diff --git a/front/src/constants/index.tsx b/front/src/constants/index.tsx index 2734975..42e5361 100644 --- a/front/src/constants/index.tsx +++ b/front/src/constants/index.tsx @@ -1 +1 @@ -export { DECO, MAIN, MSG_COLOR, BOTTOM } from './deco'; +export { SENTIMENT_MODEL, DECO, MAIN, MSG_COLOR, BOTTOM } from './deco'; diff --git a/front/src/mockdata.json b/front/src/mockdata.json index 5bf74a6..8bb7c47 100644 --- a/front/src/mockdata.json +++ b/front/src/mockdata.json @@ -20,7 +20,9 @@ "opened": null, "sender": "박민수", "snowball_id": 1, - "user_id": 1 + "user_id": 1, + "sentiment": "positive", + "confidence": 100 }, { "content": "메리크리스마스~\n 내년에도 사이좋게 지내자!!.", @@ -34,7 +36,9 @@ "opened": null, "sender": "김찬우", "snowball_id": 1, - "user_id": 1 + "user_id": 1, + "sentiment": "positive", + "confidence": 100 } ] }, diff --git a/front/src/pages/Main/Main.tsx b/front/src/pages/Main/Main.tsx index 1a0a9fc..aa79b70 100644 --- a/front/src/pages/Main/Main.tsx +++ b/front/src/pages/Main/Main.tsx @@ -54,19 +54,19 @@ const Main = () => { const leftArrowRef = useRef(null); const rightArrowRef = useRef(null); - const saveCookie = () => { - const cookieToken = import.meta.env.VITE_APP_COOKIE_TOKEN; - const cookieName = 'access_token'; - const cookieValue = cookieToken; - const today = new Date(); - const expire = new Date(); - const secure = true; - expire.setDate(today.getDate() + 1); - document.cookie = `${cookieName}=${cookieValue}; expires=${expire.toUTCString()}; secure=${secure}; path=/`; - }; + // const saveCookie = () => { + // const cookieToken = import.meta.env.VITE_APP_COOKIE_TOKEN; + // const cookieName = 'access_token'; + // const cookieValue = cookieToken; + // const today = new Date(); + // const expire = new Date(); + // const secure = true; + // expire.setDate(today.getDate() + 1); + // document.cookie = `${cookieName}=${cookieValue}; expires=${expire.toUTCString()}; secure=${secure}; path=/`; + // }; useEffect(() => { - saveCookie(); + //saveCookie(); axios .get('/api/user', { withCredentials: true // axios 쿠키 값 전달 @@ -77,7 +77,6 @@ const Main = () => { const snowballData = res.data.main_snowball as SnowBallData; setSnowBallData(snowballData); setUserData(userData); - console.log('wow'); if ( userData.nickname === null || userData.snowball_count === 0 || diff --git a/front/src/pages/Main/MainButtonBox.tsx b/front/src/pages/Main/MainButtonBox.tsx index e8ff385..cbf517d 100644 --- a/front/src/pages/Main/MainButtonBox.tsx +++ b/front/src/pages/Main/MainButtonBox.tsx @@ -39,6 +39,10 @@ const screenTime = ( ); } }); + const a = document.getElementById('musicController'); + if (a) { + a.style.display = 'none'; + } setTimeout(() => { setScreen(true); @@ -46,7 +50,9 @@ const screenTime = ( setTimeout(() => { setScreen(false); - + if (a) { + a.style.display = 'block'; + } refs.forEach(ref => { if (ref.current) { ref.current.style.setProperty('animation', 'none'); diff --git a/front/src/pages/Visit/SnowBallProvider.tsx b/front/src/pages/Visit/SnowBallProvider.tsx index f593a99..c18047d 100644 --- a/front/src/pages/Visit/SnowBallProvider.tsx +++ b/front/src/pages/Visit/SnowBallProvider.tsx @@ -1,4 +1,4 @@ -import React, { useState, createContext, useEffect } from 'react'; +import React, { useState, createContext } from 'react'; import mockData from '@mock'; interface SnowBallContextType { @@ -42,6 +42,8 @@ interface Message { sender: string | undefined; snowball_id: number; user_id: number; + sentiment: string; + confidence: number; } const SnowBallContext = createContext({ @@ -58,20 +60,6 @@ const SnowBallProvider: React.FC<{ children: React.ReactNode }> = ({ mockData.snowball_data ); const [userData, setUserData] = useState(mockData.user_data); - // const { user } = useParams(); - // useEffect(() => { - // axios(`/api/user/${user}`) - // .then(res => { - // setSnowBallData(res.data.main_snowball as SnowBallData); - // setUserData(res.data.user as UserData); - // }) - // .catch(e => { - // //없는 유저 조회시 wrong page로 보내버리기 - // console.error(e); - // navigate('*'); - // }); - // }, []); - return ( { - const cookieToken = import.meta.env.VITE_APP_COOKIE_TOKEN; - const cookieName = 'access_token'; - const cookieValue = cookieToken; - const today = new Date(); - const expire = new Date(); - const secure = true; - expire.setDate(today.getDate() + 1); - document.cookie = `${cookieName}=${cookieValue}; expires=${expire.toUTCString()}; secure=${secure}; path=/`; -}; - -const IsLogin: React.FC<{ children: ReactNode }> = ({ children }) => { - const navigate = useNavigate(); - const [url, setUrl] = React.useState(''); - const { snowBallData, setSnowBallData, setUserData } = - useContext(SnowBallContext); - console.log('1.', snowBallData); - useEffect(() => { - saveCookie(); - if (url === '') { - axios - .get('/api/user', { - withCredentials: true // axios 쿠키 값 전달 - }) - .then(res => { - if (res.status === 200) { - const data = res.data; - setSnowBallData(data.main_snowball as SnowBallData); - setUserData(data.user as UserData); - console.log(data); - - if (data.user.nickname === null) { - setUrl('/make'); - navigate(url); - } else if ( - data.user.nickname !== null && - data.main_snowball === null - ) { - setUrl('/make/snowball'); - navigate(url); - } - } - }) - .catch(err => { - console.error(err); - navigate('*'); - }); - } - }, [url, navigate]); - - return <>{children}; -}; - -export default IsLogin; diff --git a/front/src/router/IsSnowballData.tsx b/front/src/router/IsSnowballData.tsx index 5db541d..a4c1e8e 100644 --- a/front/src/router/IsSnowballData.tsx +++ b/front/src/router/IsSnowballData.tsx @@ -43,7 +43,7 @@ const IsSnowballData: React.FC<{ children: ReactNode }> = ({ children }) => { } }) .catch(err => { - console.log(err); + console.error(err); navigate('*'); }); } diff --git a/front/src/router/index.tsx b/front/src/router/index.tsx index d924a82..8834769 100644 --- a/front/src/router/index.tsx +++ b/front/src/router/index.tsx @@ -1,2 +1 @@ -export { default as IsLogin } from './IsLogin'; export { default as IsSnowballData } from './IsSnowballData';