fix: i18n의 타입 수정
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { FLIGHT_STARFIELD_TUNING } from '@/shared/config/starfield';
|
import { FLIGHT_STARFIELD_TUNING } from "@/shared/config/starfield";
|
||||||
import { clamp, randomInRange } from '@/shared/lib/math/number';
|
import { clamp, randomInRange } from "@/shared/lib/math/number";
|
||||||
|
|
||||||
import { FlightStar } from '@/features/flight-starfield/model/types';
|
import { FlightStar } from "@/features/flight-starfield/model/types";
|
||||||
|
|
||||||
export const getFlightStarCount = (width: number, height: number) => {
|
export const getFlightStarCount = (width: number, height: number) => {
|
||||||
const isMobile = width < FLIGHT_STARFIELD_TUNING.mobileBreakpoint;
|
const isMobile = width < FLIGHT_STARFIELD_TUNING.mobileBreakpoint;
|
||||||
@@ -11,7 +11,9 @@ export const getFlightStarCount = (width: number, height: number) => {
|
|||||||
const max = isMobile
|
const max = isMobile
|
||||||
? FLIGHT_STARFIELD_TUNING.starCount.mobile.max
|
? FLIGHT_STARFIELD_TUNING.starCount.mobile.max
|
||||||
: FLIGHT_STARFIELD_TUNING.starCount.desktop.max;
|
: FLIGHT_STARFIELD_TUNING.starCount.desktop.max;
|
||||||
const byArea = Math.round((width * height) / FLIGHT_STARFIELD_TUNING.densityDivisor);
|
const byArea = Math.round(
|
||||||
|
(width * height) / FLIGHT_STARFIELD_TUNING.densityDivisor,
|
||||||
|
);
|
||||||
|
|
||||||
return clamp(byArea, min, max);
|
return clamp(byArea, min, max);
|
||||||
};
|
};
|
||||||
@@ -51,7 +53,8 @@ const createFlightSpeed = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createFlightVisualTier = () => {
|
const createFlightVisualTier = () => {
|
||||||
const highlight = Math.random() < FLIGHT_STARFIELD_TUNING.radius.highlightChance;
|
const highlight =
|
||||||
|
Math.random() < FLIGHT_STARFIELD_TUNING.radius.highlightChance;
|
||||||
const tailRoll = Math.random();
|
const tailRoll = Math.random();
|
||||||
const tailLength =
|
const tailLength =
|
||||||
tailRoll < FLIGHT_STARFIELD_TUNING.tail.pointChance
|
tailRoll < FLIGHT_STARFIELD_TUNING.tail.pointChance
|
||||||
@@ -95,7 +98,8 @@ const createFlightVisualTier = () => {
|
|||||||
const createFlightSpawnRadius = (width: number, height: number) => {
|
const createFlightSpawnRadius = (width: number, height: number) => {
|
||||||
const roll = Math.random();
|
const roll = Math.random();
|
||||||
const maxWideRadius = Math.min(
|
const maxWideRadius = Math.min(
|
||||||
Math.max(width, height) * FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxScaleOfViewport,
|
Math.max(width, height) *
|
||||||
|
FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxScaleOfViewport,
|
||||||
FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxAbsolute,
|
FLIGHT_STARFIELD_TUNING.spawnRadius.wideRange.maxAbsolute,
|
||||||
);
|
);
|
||||||
const ringOuter = Math.min(
|
const ringOuter = Math.min(
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
'use client';
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
import { projectFlightStar, createVanishingPoint } from '@/features/flight-starfield/lib/projection';
|
import {
|
||||||
|
createVanishingPoint,
|
||||||
|
projectFlightStar,
|
||||||
|
} from "@/features/flight-starfield/lib/projection";
|
||||||
import {
|
import {
|
||||||
createFlightStar,
|
createFlightStar,
|
||||||
createFlightVanishXJitter,
|
createFlightVanishXJitter,
|
||||||
getFlightStarCount,
|
getFlightStarCount,
|
||||||
shouldRecycleFlightStar,
|
shouldRecycleFlightStar,
|
||||||
} from '@/features/flight-starfield/model/starfieldModel';
|
} from "@/features/flight-starfield/model/starfieldModel";
|
||||||
import { FlightStar } from '@/features/flight-starfield/model/types';
|
import { FlightStar } from "@/features/flight-starfield/model/types";
|
||||||
import { clamp } from '@/shared/lib/math/number';
|
import { clamp } from "@/shared/lib/math/number";
|
||||||
import { getPrefersReducedMotionMediaQuery } from '@/shared/lib/motion/prefersReducedMotion';
|
import { getPrefersReducedMotionMediaQuery } from "@/shared/lib/motion/prefersReducedMotion";
|
||||||
|
|
||||||
export function FlightStarfieldCanvas({
|
export function FlightStarfieldCanvas({
|
||||||
vanishYOffset = -68,
|
vanishYOffset = -68,
|
||||||
@@ -30,7 +33,7 @@ export function FlightStarfieldCanvas({
|
|||||||
const canvas = canvasRef.current;
|
const canvas = canvasRef.current;
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
|
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext("2d");
|
||||||
if (!context) return;
|
if (!context) return;
|
||||||
|
|
||||||
let width = window.innerWidth;
|
let width = window.innerWidth;
|
||||||
@@ -102,7 +105,7 @@ export function FlightStarfieldCanvas({
|
|||||||
|
|
||||||
if (star.tailLength < 1 || movementLength < 0.001) {
|
if (star.tailLength < 1 || movementLength < 0.001) {
|
||||||
context.globalAlpha = visibleAlpha;
|
context.globalAlpha = visibleAlpha;
|
||||||
context.fillStyle = '#f8fbff';
|
context.fillStyle = "#f8fbff";
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.arc(toX, toY, star.radius, 0, Math.PI * 2);
|
context.arc(toX, toY, star.radius, 0, Math.PI * 2);
|
||||||
context.fill();
|
context.fill();
|
||||||
@@ -116,7 +119,7 @@ export function FlightStarfieldCanvas({
|
|||||||
const tailY = toY - directionY * star.tailLength;
|
const tailY = toY - directionY * star.tailLength;
|
||||||
|
|
||||||
const gradient = context.createLinearGradient(tailX, tailY, toX, toY);
|
const gradient = context.createLinearGradient(tailX, tailY, toX, toY);
|
||||||
gradient.addColorStop(0, 'rgba(248, 251, 255, 0)');
|
gradient.addColorStop(0, "rgba(248, 251, 255, 0)");
|
||||||
gradient.addColorStop(1, `rgba(248, 251, 255, ${visibleAlpha})`);
|
gradient.addColorStop(1, `rgba(248, 251, 255, ${visibleAlpha})`);
|
||||||
|
|
||||||
context.strokeStyle = gradient;
|
context.strokeStyle = gradient;
|
||||||
@@ -127,9 +130,15 @@ export function FlightStarfieldCanvas({
|
|||||||
context.stroke();
|
context.stroke();
|
||||||
|
|
||||||
context.globalAlpha = Math.min(1, visibleAlpha + 0.08);
|
context.globalAlpha = Math.min(1, visibleAlpha + 0.08);
|
||||||
context.fillStyle = '#f8fbff';
|
context.fillStyle = "#f8fbff";
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.arc(toX, toY, clamp(star.radius * 0.72, 0.6, 1.45), 0, Math.PI * 2);
|
context.arc(
|
||||||
|
toX,
|
||||||
|
toY,
|
||||||
|
clamp(star.radius * 0.72, 0.6, 1.45),
|
||||||
|
0,
|
||||||
|
Math.PI * 2,
|
||||||
|
);
|
||||||
context.fill();
|
context.fill();
|
||||||
context.globalAlpha = 1;
|
context.globalAlpha = 1;
|
||||||
};
|
};
|
||||||
@@ -144,9 +153,9 @@ export function FlightStarfieldCanvas({
|
|||||||
vp.y,
|
vp.y,
|
||||||
centerProtectRadius * 1.35,
|
centerProtectRadius * 1.35,
|
||||||
);
|
);
|
||||||
veil.addColorStop(0, 'rgba(160, 185, 235, 0.08)');
|
veil.addColorStop(0, "rgba(160, 185, 235, 0.08)");
|
||||||
veil.addColorStop(0.55, 'rgba(90, 114, 170, 0.03)');
|
veil.addColorStop(0.55, "rgba(90, 114, 170, 0.03)");
|
||||||
veil.addColorStop(1, 'rgba(0, 0, 0, 0)');
|
veil.addColorStop(1, "rgba(0, 0, 0, 0)");
|
||||||
|
|
||||||
context.fillStyle = veil;
|
context.fillStyle = veil;
|
||||||
context.fillRect(0, 0, width, height);
|
context.fillRect(0, 0, width, height);
|
||||||
@@ -161,14 +170,14 @@ export function FlightStarfieldCanvas({
|
|||||||
height / 2,
|
height / 2,
|
||||||
Math.max(width, height) * 0.95,
|
Math.max(width, height) * 0.95,
|
||||||
);
|
);
|
||||||
vignette.addColorStop(0, 'rgba(0, 0, 0, 0)');
|
vignette.addColorStop(0, "rgba(0, 0, 0, 0)");
|
||||||
vignette.addColorStop(1, 'rgba(0, 0, 0, 0.82)');
|
vignette.addColorStop(1, "rgba(0, 0, 0, 0.82)");
|
||||||
context.fillStyle = vignette;
|
context.fillStyle = vignette;
|
||||||
context.fillRect(0, 0, width, height);
|
context.fillRect(0, 0, width, height);
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawFrame = (moveStars: boolean) => {
|
const drawFrame = (moveStars: boolean) => {
|
||||||
context.fillStyle = 'rgba(2, 5, 10, 0.3)';
|
context.fillStyle = "rgba(2, 5, 10, 0.3)";
|
||||||
context.fillRect(0, 0, width, height);
|
context.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
drawCenterVeil();
|
drawCenterVeil();
|
||||||
@@ -254,8 +263,8 @@ export function FlightStarfieldCanvas({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
motionQuery.addEventListener('change', handleMotionChange);
|
motionQuery.addEventListener("change", handleMotionChange);
|
||||||
|
|
||||||
if (prefersReducedMotion || isPaused) {
|
if (prefersReducedMotion || isPaused) {
|
||||||
renderStatic();
|
renderStatic();
|
||||||
@@ -264,11 +273,16 @@ export function FlightStarfieldCanvas({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
window.removeEventListener("resize", handleResize);
|
||||||
motionQuery.removeEventListener('change', handleMotionChange);
|
motionQuery.removeEventListener("change", handleMotionChange);
|
||||||
stopAnimation();
|
stopAnimation();
|
||||||
};
|
};
|
||||||
}, [vanishYOffset, centerProtectRadius, isPaused]);
|
}, [vanishYOffset, centerProtectRadius, isPaused]);
|
||||||
|
|
||||||
return <canvas ref={canvasRef} className="fixed inset-0 z-0 bg-black pointer-events-none" />;
|
return (
|
||||||
|
<canvas
|
||||||
|
ref={canvasRef}
|
||||||
|
className="fixed inset-0 z-0 bg-black pointer-events-none"
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,11 +82,12 @@ const enMessages = {
|
|||||||
"status.reoriented": "Reoriented",
|
"status.reoriented": "Reoriented",
|
||||||
"status.aborted": "Aborted Early",
|
"status.aborted": "Aborted Early",
|
||||||
"status.in_progress": "In Progress",
|
"status.in_progress": "In Progress",
|
||||||
} as const;
|
} satisfies Record<string, string>;
|
||||||
|
|
||||||
type I18nMessages = typeof enMessages;
|
type MessageKey = keyof typeof enMessages;
|
||||||
|
type I18nMessages = Record<MessageKey, string>;
|
||||||
|
|
||||||
const koMessages: I18nMessages = {
|
const koMessages = {
|
||||||
"layout.nav.log": "항해일지",
|
"layout.nav.log": "항해일지",
|
||||||
"layout.nav.settings": "설정",
|
"layout.nav.settings": "설정",
|
||||||
"layout.nav.language": "언어",
|
"layout.nav.language": "언어",
|
||||||
@@ -155,9 +156,9 @@ const koMessages: I18nMessages = {
|
|||||||
"status.reoriented": "🧭 방향 재설정",
|
"status.reoriented": "🧭 방향 재설정",
|
||||||
"status.aborted": "🚨 조기 귀환",
|
"status.aborted": "🚨 조기 귀환",
|
||||||
"status.in_progress": "진행 중",
|
"status.in_progress": "진행 중",
|
||||||
};
|
} satisfies I18nMessages;
|
||||||
|
|
||||||
const jaMessages: I18nMessages = {
|
const jaMessages = {
|
||||||
"layout.nav.log": "航海ログ",
|
"layout.nav.log": "航海ログ",
|
||||||
"layout.nav.settings": "設定",
|
"layout.nav.settings": "設定",
|
||||||
"layout.nav.language": "言語",
|
"layout.nav.language": "言語",
|
||||||
@@ -226,15 +227,17 @@ const jaMessages: I18nMessages = {
|
|||||||
"status.reoriented": "🧭 方針再設定",
|
"status.reoriented": "🧭 方針再設定",
|
||||||
"status.aborted": "🚨 早期帰還",
|
"status.aborted": "🚨 早期帰還",
|
||||||
"status.in_progress": "進行中",
|
"status.in_progress": "進行中",
|
||||||
};
|
} satisfies I18nMessages;
|
||||||
|
|
||||||
|
const normalizedEnMessages: I18nMessages = enMessages;
|
||||||
|
|
||||||
export const I18N_MESSAGES: Record<Locale, I18nMessages> = {
|
export const I18N_MESSAGES: Record<Locale, I18nMessages> = {
|
||||||
ko: koMessages,
|
ko: koMessages,
|
||||||
en: enMessages,
|
en: normalizedEnMessages,
|
||||||
ja: jaMessages,
|
ja: jaMessages,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type I18nKey = keyof I18nMessages;
|
export type I18nKey = MessageKey;
|
||||||
|
|
||||||
export type TranslationParams = Record<string, string | number>;
|
export type TranslationParams = Record<string, string | number>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user