feat: 항해 종료 시 버튼을 꾹 눌러서 종료

This commit is contained in:
2026-02-14 21:28:17 +09:00
parent 166d04384f
commit 332c2c5996
9 changed files with 232 additions and 61 deletions

View File

@@ -15,6 +15,8 @@ import { saveCurrentVoyage, saveToHistory } from "@/shared/lib/store";
import { Voyage, VoyageStatus } from "@/shared/types";
const FINISH_HOLD_MS = 1000;
const HOLD_STAGE_ONE_MS = 100;
const HOLD_STAGE_ONE_PROGRESS = 0.2;
type FlightHudWidgetProps = {
voyage: Voyage | null;
@@ -70,28 +72,52 @@ export function FlightHudWidget({
router.push("/log");
};
const resetHold = () => {
const stopHoldLoop = () => {
if (holdRafRef.current !== null) {
cancelAnimationFrame(holdRafRef.current);
holdRafRef.current = null;
}
holdStartAtRef.current = null;
};
const resetHold = () => {
stopHoldLoop();
isHoldCompletedRef.current = false;
setHoldProgress(0);
};
const openDebriefByHold = () => {
isHoldCompletedRef.current = true;
stopHoldLoop();
setHoldProgress(1);
openDebriefModal();
resetHold();
requestAnimationFrame(() => {
resetHold();
openDebriefModal();
});
};
const tickHoldProgress = (timestamp: number) => {
if (holdStartAtRef.current === null) return;
const elapsed = timestamp - holdStartAtRef.current;
const nextProgress = Math.min(1, elapsed / FINISH_HOLD_MS);
const nextProgress = (() => {
if (elapsed <= HOLD_STAGE_ONE_MS) {
return Math.min(
HOLD_STAGE_ONE_PROGRESS,
(elapsed / HOLD_STAGE_ONE_MS) * HOLD_STAGE_ONE_PROGRESS,
);
}
const stageTwoElapsed = elapsed - HOLD_STAGE_ONE_MS;
const stageTwoDuration = FINISH_HOLD_MS - HOLD_STAGE_ONE_MS;
const stageTwoProgressRatio = Math.min(1, stageTwoElapsed / stageTwoDuration);
return Math.min(
1,
HOLD_STAGE_ONE_PROGRESS +
stageTwoProgressRatio * (1 - HOLD_STAGE_ONE_PROGRESS),
);
})();
setHoldProgress(nextProgress);
if (nextProgress >= 1) {
@@ -107,6 +133,7 @@ export function FlightHudWidget({
resetHold();
holdStartAtRef.current = performance.now();
setHoldProgress(0);
holdRafRef.current = requestAnimationFrame(tickHoldProgress);
};
@@ -191,7 +218,7 @@ export function FlightHudWidget({
>
<span
aria-hidden
className="absolute inset-0 origin-left rounded-full bg-indigo-400/45 transition-transform duration-75"
className="absolute inset-0 origin-left bg-indigo-400/45"
style={{ transform: `scaleX(${holdProgress})` }}
/>
<span className="relative z-10">