From cb775c977e7e19a48fc9d0d37f6f5c247cf350ad Mon Sep 17 00:00:00 2001 From: BangDori <44726494+BangDori@users.noreply.github.com> Date: Mon, 13 May 2024 21:35:31 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=EC=95=84=EC=9D=B4=ED=8F=B0=20?= =?UTF-8?q?=EA=B0=80=EB=A1=9C=20=EB=AA=A8=EB=93=9C=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#54)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 아이폰 사이즈 동적 조정 훅 수정 * feat: 유틸리티 버튼 위치 수정 * feat: 아이폰 회전 기능 추가 --- .../layout/iPhone/hooks/useDynamicSize.tsx | 47 ------------ .../layout/iPhone/hooks/useUtilityIPhone.tsx | 74 +++++++++++++++++++ src/app/layout/iPhone/ui/IPhoneLayout.scss | 7 +- src/app/layout/iPhone/ui/IPhoneLayout.tsx | 7 +- 4 files changed, 83 insertions(+), 52 deletions(-) delete mode 100644 src/app/layout/iPhone/hooks/useDynamicSize.tsx create mode 100644 src/app/layout/iPhone/hooks/useUtilityIPhone.tsx diff --git a/src/app/layout/iPhone/hooks/useDynamicSize.tsx b/src/app/layout/iPhone/hooks/useDynamicSize.tsx deleted file mode 100644 index 977b503..0000000 --- a/src/app/layout/iPhone/hooks/useDynamicSize.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { useEffect, useRef } from 'react'; - -const IPHONE_MIN_SIZE = 60; -const IPHONE_MAX_SIZE = 100; - -/** - * iPhone 레이아웃의 크기를 동적으로 변경하는 훅입니다. - * @param initialSize 초기 사이즈 - * @returns iPhone 레이아웃의 참조와 사이즈 변경 핸들러 - */ -export const useDynamicSize = (initialSize: number = 80) => { - const iPhoneSizeRef = useRef(initialSize); - const iPhoneLayoutRef = useRef(null); - - useEffect(() => { - document.documentElement.style.setProperty( - '--iphone-size', - `${initialSize}%`, - ); - }, []); - - const changeStyle = () => { - if (iPhoneLayoutRef.current) { - iPhoneLayoutRef.current.style.height = `${iPhoneSizeRef.current}%`; - document.documentElement.style.setProperty( - '--iphone-size', - `${iPhoneSizeRef.current}%`, - ); - } - }; - - const handleSizeUp = () => { - if (iPhoneSizeRef.current >= IPHONE_MAX_SIZE) return; - - iPhoneSizeRef.current += 1; - changeStyle(); - }; - - const handleSizeDown = () => { - if (iPhoneSizeRef.current <= IPHONE_MIN_SIZE) return; - - iPhoneSizeRef.current -= 1; - changeStyle(); - }; - - return { iPhoneLayoutRef, handleSizeUp, handleSizeDown }; -}; diff --git a/src/app/layout/iPhone/hooks/useUtilityIPhone.tsx b/src/app/layout/iPhone/hooks/useUtilityIPhone.tsx new file mode 100644 index 0000000..8e56c0c --- /dev/null +++ b/src/app/layout/iPhone/hooks/useUtilityIPhone.tsx @@ -0,0 +1,74 @@ +import { useEffect, useRef } from 'react'; + +const IPHONE_MIN_SIZE = 60; +const IPHONE_INIT_SIZE = 80; +const IPHONE_MAX_SIZE = 100; + +const IPHONE_PROTRAIT_MODE = 0; // 세로 모드 +const IPHONE_LANDSCAPE_MODE = -90; // 가로 모드 + +/** + * iPhone 레이아웃의 크기를 동적으로 변경하는 훅입니다. + * @returns iPhone 레이아웃의 참조와 사이즈 변경 핸들러 + */ +export const useUtilityIPhone = () => { + const iPhoneSizeRef = useRef(IPHONE_INIT_SIZE); + const iPhoneModeRef = useRef(IPHONE_PROTRAIT_MODE); + const iPhoneLayoutRef = useRef(null); + + useEffect(() => { + document.documentElement.style.setProperty( + '--iphone-size', + `${IPHONE_INIT_SIZE}%`, + ); + + document.documentElement.style.setProperty( + '--iphone-mode', + `${IPHONE_PROTRAIT_MODE}deg`, + ); + }, []); + + const changeStyle = () => { + if (iPhoneLayoutRef.current) { + iPhoneLayoutRef.current.style.height = `${iPhoneSizeRef.current}%`; + document.documentElement.style.setProperty( + '--iphone-size', + `${iPhoneSizeRef.current}%`, + ); + } + }; + + const handleSizeUp = () => { + if (iPhoneSizeRef.current >= IPHONE_MAX_SIZE) return; + + iPhoneSizeRef.current += 1; + changeStyle(); + }; + + const handleSizeDown = () => { + if (iPhoneSizeRef.current <= IPHONE_MIN_SIZE) return; + + iPhoneSizeRef.current -= 1; + changeStyle(); + }; + + const handleRotate = () => { + if (iPhoneModeRef.current === IPHONE_PROTRAIT_MODE) { + // 가로 모드로 변경 + iPhoneModeRef.current = IPHONE_LANDSCAPE_MODE; + document.documentElement.style.setProperty( + '--iphone-mode', + `${IPHONE_LANDSCAPE_MODE}deg`, + ); + } else { + // 세로 모드로 변경 + iPhoneModeRef.current = IPHONE_PROTRAIT_MODE; + document.documentElement.style.setProperty( + '--iphone-mode', + `${IPHONE_PROTRAIT_MODE}deg`, + ); + } + }; + + return { iPhoneLayoutRef, handleRotate, handleSizeUp, handleSizeDown }; +}; diff --git a/src/app/layout/iPhone/ui/IPhoneLayout.scss b/src/app/layout/iPhone/ui/IPhoneLayout.scss index f639b07..5ab09c4 100644 --- a/src/app/layout/iPhone/ui/IPhoneLayout.scss +++ b/src/app/layout/iPhone/ui/IPhoneLayout.scss @@ -25,6 +25,9 @@ /* 아이폰 이미지의 비율 설정 */ aspect-ratio: 256 / 538; height: var(--iphone-size); + rotate: var(--iphone-mode); + + transition: rotate 1.5s; .iPhone-status { /* children의 크기를 아이폰 화면 크기에 맞게 설정 */ @@ -55,7 +58,7 @@ .iPhone-utility-container { position: absolute; left: 50%; - bottom: 2%; + bottom: calc(2% + (var(--iphone-size) - 80%) * 0.025); transform: translateX(-50%); display: flex; @@ -63,7 +66,7 @@ gap: 24px; .size-down-btn, - .retry-btn, + .rotation-btn, .size-up-btn { width: 40px; height: 40px; diff --git a/src/app/layout/iPhone/ui/IPhoneLayout.tsx b/src/app/layout/iPhone/ui/IPhoneLayout.tsx index c18a0e3..0ae508b 100644 --- a/src/app/layout/iPhone/ui/IPhoneLayout.tsx +++ b/src/app/layout/iPhone/ui/IPhoneLayout.tsx @@ -5,13 +5,14 @@ import { Outlet } from 'react-router-dom'; -import { useDynamicSize } from '../hooks/useDynamicSize'; +import { useUtilityIPhone } from '../hooks/useUtilityIPhone'; import iPhoneStatus from '/assets/image/iPhone_status.png'; import './IPhoneLayout.scss'; export const IPhoneLayout = () => { - const { iPhoneLayoutRef, handleSizeDown, handleSizeUp } = useDynamicSize(); + const { iPhoneLayoutRef, handleSizeDown, handleRotate, handleSizeUp } = + useUtilityIPhone(); return (
@@ -25,7 +26,7 @@ export const IPhoneLayout = () => { -