import type { Style, EasingType } from 'leviar'; import type { AssetKeysOf } from '../types/config'; import type { CameraEffectPreset } from './camera'; export type OverlayPreset = 'caption' | 'title' | 'whisper'; /** 텍스트 오버레이 항목 */ export interface OverlayTextEntry { kind: 'text'; /** 오버레이 고유 이름 */ name: string; text: string; preset: OverlayPreset; } /** 이미지 오버레이 항목 */ export interface OverlayImageEntry { kind: 'image'; /** 오버레이 고유 이름 */ name: string; /** 에셋 키 또는 파일 경로 */ src: string; /** * 화면 내 가로 위치 (0~1, 0=좌, 0.5=중앙, 1=우). * `canvasToLocal`을 통해 월드 좌표로 변환됩니다. */ x: number; /** * 화면 내 세로 위치 (0~1, 0=상, 0.5=중앙, 1=하). * `canvasToLocal`을 통해 월드 좌표로 변환됩니다. */ y: number; /** 이미지 너비(px). 미지정 시 화면 너비의 50% */ width?: number; /** 이미지 높이(px). 미지정 시 자동 */ height?: number; /** 화면 맞춤 방식 (cover | contain | stretch). 기본값: 'contain' */ fit?: 'cover' | 'contain' | 'stretch'; /** z-index. 미지정 시 Z_INDEX.OVERLAY_CAPTION */ zIndex?: number; /** 불투명도 (0~1). 기본값: 1 */ opacity?: number; } export type OverlayEntry = OverlayTextEntry | OverlayImageEntry; /** 텍스트 오버레이를 표시하거나 숨긴다 */ export type OverlayTextCmd = { /** 수행할 동작입니다. (표시) */ action: 'show'; /** 오버레이 고유 이름. 중복된 name은 transition 처리됩니다. */ name: string; /** 화면에 표시할 텍스트입니다. */ text: string; /** * 텍스트 오버레이의 스타일 프리셋입니다. * 기본값: 'caption' */ preset?: OverlayPreset; /** 전환 애니메이션의 지속 시간(ms)입니다. */ duration?: number; /** 애니메이션의 이징 함수 이름입니다. */ ease?: EasingType; } | { /** 수행할 동작입니다. (숨기기) */ action: 'hide'; /** 오버레이 고유 이름. */ name: string; /** 전환 애니메이션의 지속 시간(ms)입니다. */ duration?: number; /** 애니메이션의 이징 함수 이름입니다. */ ease?: EasingType; }; /** 이미지 오버레이를 표시하거나 숨긴다 */ export type OverlayImageCmd = { /** 수행할 동작입니다. (표시) */ action: 'show'; /** 오버레이 고유 이름. 중복된 name은 transition 처리됩니다. */ name: string; /** 화면에 표시할 이미지 에셋 키입니다. */ src: AssetKeysOf; /** * 이미지 가로 위치 (0~1). (image 전용) * 기본값: 0.5 (중앙) */ x?: number; /** * 이미지 세로 위치 (0~1). (image 전용) * 기본값: 0.5 (중앙) */ y?: number; /** 이미지 너비(px) */ width?: number; /** 이미지 높이(px) */ height?: number; /** 이미지 화면 맞춤 방식 (기본값: 'contain') */ fit?: 'cover' | 'contain' | 'stretch'; /** 이미지 z-index */ zIndex?: number; /** 이미지 불투명도 (0~1). 기본값: 1 */ opacity?: number; /** 전환 애니메이션의 지속 시간(ms)입니다. */ duration?: number; /** 애니메이션의 이징 함수 이름입니다. */ ease?: EasingType; } | { /** 수행할 동작입니다. (숨기기) */ action: 'hide'; /** 오버레이 고유 이름. */ name: string; /** 전환 애니메이션의 지속 시간(ms)입니다. */ duration?: number; /** 애니메이션의 이징 함수 이름입니다. */ ease?: EasingType; }; export interface OverlaySchema { /** @internal name → 오버레이 항목 맵 */ _overlays: Record; /** @internal 최근 전환 애니메이션 지속 시간 (ms) */ _lastDuration?: number; /** @internal 최근 전환 애니메이션 이징 함수 이름 */ _lastEase?: string; /** 텍스트 오버레이 기본 스타일 오버라이드 */ textStyle?: Partial