From 7459fc674e4982965ef4ad1a039c4d2363c8493e Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 01:17:04 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat=20:=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../farminglog/src/pages/game/index.styled.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/apps/farminglog/src/pages/game/index.styled.ts b/apps/farminglog/src/pages/game/index.styled.ts index c2800578..ee9cd97f 100644 --- a/apps/farminglog/src/pages/game/index.styled.ts +++ b/apps/farminglog/src/pages/game/index.styled.ts @@ -121,4 +121,42 @@ export const StartButton = styled.button` transform: scale(1.05); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); } +`; + +// 랜딩 페이지용 배경 히어로 +export const LandingHero = styled.div<{ + $bgDesktop: string; + $bgMobile?: string; +}>` + width: 100%; + height: 59760px; + + + background: ${({ $bgDesktop }) => `url(${$bgDesktop}) center / cover no-repeat`}; + + + // 모바일에선 잘모르겠음 일단 때리쳐! + @media (max-width: 768px) { + aspect-ratio: 750 / 2237; + background-image: ${({ $bgDesktop, $bgMobile }) => + `url(${($bgMobile && $bgMobile.length > 0) ? $bgMobile : $bgDesktop})`}; + background-size: cover; + background-position: center; + } +`; + +export const UpButton = styled.div` + position: fixed; + bottom: 100px; + right: 100px; + width: 150px; + height: 150px; + border-radius: 50%; + cursor: pointer; +`; + +export const UpButtonImage = styled.img` + width: 150px; + height: 150px; + object-fit: fill; `; \ No newline at end of file From 7908d71b193afe63dbe29d03078b6282b73ca9cb Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 01:17:16 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/farminglog/src/pages/game/index.tsx | 32 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/apps/farminglog/src/pages/game/index.tsx b/apps/farminglog/src/pages/game/index.tsx index 92d41b93..d2bfb01a 100644 --- a/apps/farminglog/src/pages/game/index.tsx +++ b/apps/farminglog/src/pages/game/index.tsx @@ -1,17 +1,28 @@ import React, { useState } from 'react'; // useState를 import 합니다. import { UnityWebGL } from '../../components/UnityWebGL'; -import { GameContainer, GameTitle, StartButton, StartContainer } from './index.styled.ts'; +import useMediaQueries from "@/hooks/useMediaQueries"; +import { GameContainer, StartButton, StartContainer, LandingHero, UpButton, UpButtonImage } from './index.styled.ts'; + const Game: React.FC = () => { const [isGameStarted, setIsGameStarted] = useState(false); - + const [isLanding, setIsLanding] = useState(true); + const { isMobile } = useMediaQueries(); + const landingImage = 'https://farmsystem-bucket.s3.ap-northeast-2.amazonaws.com/game/DetailGameLanding.png'; + const upButtonImage = 'https://farmsystem-bucket.s3.ap-northeast-2.amazonaws.com/game/UpGameButton.png'; const handleStartGame = () => { setIsGameStarted(true); }; + const handleScrollTop = () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; return ( +
- 🌱 Grow My Farm + {/** isGameStarted 값에 따라 조건부로 렌더링. */} {isGameStarted ? ( @@ -27,6 +38,21 @@ const Game: React.FC = () => { )} + + {!isMobile && ( + setIsLanding(false)} + > + + )} + {( !isMobile && isLanding && + + + )} + +
); }; From 99a628b692de0603b0fed2a01902ef7993ac788e Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 21:14:58 +0900 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=EB=9E=9C=EB=94=A9=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/farminglog/src/pages/game/index.styled.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/farminglog/src/pages/game/index.styled.ts b/apps/farminglog/src/pages/game/index.styled.ts index ee9cd97f..1c6f4a0a 100644 --- a/apps/farminglog/src/pages/game/index.styled.ts +++ b/apps/farminglog/src/pages/game/index.styled.ts @@ -129,10 +129,12 @@ export const LandingHero = styled.div<{ $bgMobile?: string; }>` width: 100%; + max-width: 1200px; + margin: 0 auto; height: 59760px; - background: ${({ $bgDesktop }) => `url(${$bgDesktop}) center / cover no-repeat`}; + background: ${({ $bgDesktop }) => `url(${$bgDesktop}) center / contain no-repeat`}; // 모바일에선 잘모르겠음 일단 때리쳐! @@ -140,7 +142,7 @@ export const LandingHero = styled.div<{ aspect-ratio: 750 / 2237; background-image: ${({ $bgDesktop, $bgMobile }) => `url(${($bgMobile && $bgMobile.length > 0) ? $bgMobile : $bgDesktop})`}; - background-size: cover; + background-size: contain; background-position: center; } `; From 3db2b91d2b79f805ae6b3bffc870d036b542225d Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 21:26:17 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20=EC=82=AC=EC=9D=B4=EC=A6=88=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/farminglog/src/pages/game/index.styled.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/farminglog/src/pages/game/index.styled.ts b/apps/farminglog/src/pages/game/index.styled.ts index 1c6f4a0a..2772d704 100644 --- a/apps/farminglog/src/pages/game/index.styled.ts +++ b/apps/farminglog/src/pages/game/index.styled.ts @@ -128,10 +128,9 @@ export const LandingHero = styled.div<{ $bgDesktop: string; $bgMobile?: string; }>` - width: 100%; - max-width: 1200px; + width: 1200px; margin: 0 auto; - height: 59760px; + height: 35000px; background: ${({ $bgDesktop }) => `url(${$bgDesktop}) center / contain no-repeat`}; @@ -149,8 +148,8 @@ export const LandingHero = styled.div<{ export const UpButton = styled.div` position: fixed; - bottom: 100px; - right: 100px; + bottom: 70px; + right: 70px; width: 150px; height: 150px; border-radius: 50%; From 058e0de0f0597453bea72f04326d34b6dc998a81 Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 21:49:49 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=ED=98=84=EC=9E=AC=20=EB=B7=B0=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=ED=8C=90=EB=8B=A8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=9B=85=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/farminglog/src/hooks/useTallPage.ts | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 apps/farminglog/src/hooks/useTallPage.ts diff --git a/apps/farminglog/src/hooks/useTallPage.ts b/apps/farminglog/src/hooks/useTallPage.ts new file mode 100644 index 00000000..50c31eb6 --- /dev/null +++ b/apps/farminglog/src/hooks/useTallPage.ts @@ -0,0 +1,77 @@ +import { useEffect, useState } from "react"; + +/** + * 문서 전체 높이(가 임계값을 넘는지 감지하는 훅입니다 + * 기본 임계값 3000px이며, 리사이즈/레이아웃 변경에 반응 + */ +export default function useTallPage(threshold: number = 3000): boolean { + const [isTall, setIsTall] = useState(false); + + useEffect(() => { + const getPageHeight = () => document.documentElement.scrollHeight; + + // 동일 프레임 내 여러번 호출 방지 + let rafId: number | null = null; + const evaluate = () => { + if (rafId != null) return; + rafId = window.requestAnimationFrame(() => { + rafId = null; + setIsTall(getPageHeight() > threshold); + }); + }; + + // 최초 1회 평가 + evaluate(); + + let ro: ResizeObserver | null = null; + let bodyRo: ResizeObserver | null = null; + let mo: MutationObserver | null = null; + + // 레이아웃 변화에 반응함 + if (typeof ResizeObserver !== "undefined") { + ro = new ResizeObserver(() => { + evaluate(); + }); + ro.observe(document.documentElement); + + // body 높이 변화도 감지함 + if (document.body) { + bodyRo = new ResizeObserver(() => { + evaluate(); + }); + bodyRo.observe(document.body); + } + } else { + // fallback 윈도우 리사이즈 시 반응함 + window.addEventListener("resize", evaluate); + } + + // DOM 변동에 반응함 + if (typeof MutationObserver !== "undefined" && document.body) { + mo = new MutationObserver(() => { + evaluate(); + }); + mo.observe(document.body, { + subtree: true, + childList: true, + attributes: false, + }); + } + + // 추가 이벤트: 방향 전환 등 + window.addEventListener("orientationchange", evaluate); + + return () => { + if (ro) ro.disconnect(); + if (bodyRo) bodyRo.disconnect(); + if (mo) mo.disconnect(); + else window.removeEventListener("resize", evaluate); + window.removeEventListener("orientationchange", evaluate); + if (rafId != null) cancelAnimationFrame(rafId); + }; + }, [threshold]); + + return isTall; +} + + From 119de2214abc1d54b5706f1aaf1689ca9581d261 Mon Sep 17 00:00:00 2001 From: dongmin0204 Date: Tue, 30 Sep 2025 21:50:19 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=ED=98=84=EC=9E=AC=20=EB=B7=B0=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=ED=8C=90=EB=8B=A8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=9B=85=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EC=9C=84=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/farminglog/src/pages/game/index.tsx | 36 +++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/apps/farminglog/src/pages/game/index.tsx b/apps/farminglog/src/pages/game/index.tsx index d2bfb01a..7f55c24d 100644 --- a/apps/farminglog/src/pages/game/index.tsx +++ b/apps/farminglog/src/pages/game/index.tsx @@ -1,15 +1,18 @@ -import React, { useState } from 'react'; // useState를 import 합니다. +import { useEffect, useRef, useState } from 'react'; // useState를 import 합니다. import { UnityWebGL } from '../../components/UnityWebGL'; import useMediaQueries from "@/hooks/useMediaQueries"; +import useTallPage from "@/hooks/useTallPage"; import { GameContainer, StartButton, StartContainer, LandingHero, UpButton, UpButtonImage } from './index.styled.ts'; const Game: React.FC = () => { const [isGameStarted, setIsGameStarted] = useState(false); - const [isLanding, setIsLanding] = useState(true); const { isMobile } = useMediaQueries(); const landingImage = 'https://farmsystem-bucket.s3.ap-northeast-2.amazonaws.com/game/DetailGameLanding.png'; const upButtonImage = 'https://farmsystem-bucket.s3.ap-northeast-2.amazonaws.com/game/UpGameButton.png'; + const isTallPage = useTallPage(3000); + const gameContainerRef = useRef(null); + const [isGameContainerInView, setIsGameContainerInView] = useState(false); const handleStartGame = () => { setIsGameStarted(true); }; @@ -17,11 +20,31 @@ const Game: React.FC = () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }; + useEffect(() => { + if (isMobile) return; + if (!gameContainerRef.current) return; + + const observer = new IntersectionObserver( + (entries) => { + const entry = entries[0]; + setIsGameContainerInView(entry.isIntersecting); + }, + { + root: null, + rootMargin: '0px', + threshold: 0.1, + } + ); + + observer.observe(gameContainerRef.current); + return () => observer.disconnect(); + }, [isMobile]); + return (
- + {/** isGameStarted 값에 따라 조건부로 렌더링. */} @@ -39,16 +62,15 @@ const Game: React.FC = () => { )} - {!isMobile && ( + {(!isMobile) && ( setIsLanding(false)} > )} - {( !isMobile && isLanding && - + {(!isMobile && isTallPage && !isGameContainerInView) && ( + )}