@luna-editor/engine 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Player.d.ts +1 -1
- package/dist/Player.js +527 -85
- package/dist/api/conversationBranch.d.ts +4 -0
- package/dist/api/conversationBranch.js +83 -0
- package/dist/components/BackgroundLayer.d.ts +19 -0
- package/dist/components/BackgroundLayer.js +218 -0
- package/dist/components/ClickWaitIndicator.d.ts +10 -0
- package/dist/components/ClickWaitIndicator.js +31 -0
- package/dist/components/ConversationBranchBox.d.ts +2 -0
- package/dist/components/ConversationBranchBox.js +29 -0
- package/dist/components/DialogueBox.js +16 -1
- package/dist/components/FontSettingsPanel.d.ts +10 -0
- package/dist/components/FontSettingsPanel.js +30 -0
- package/dist/components/FullscreenTextBox.d.ts +6 -0
- package/dist/components/FullscreenTextBox.js +70 -0
- package/dist/components/GameScreen.d.ts +1 -0
- package/dist/components/GameScreen.js +363 -81
- package/dist/components/PluginComponentProvider.d.ts +2 -2
- package/dist/components/PluginComponentProvider.js +3 -3
- package/dist/components/TimeWaitIndicator.d.ts +15 -0
- package/dist/components/TimeWaitIndicator.js +17 -0
- package/dist/contexts/AudioContext.d.ts +14 -0
- package/dist/contexts/AudioContext.js +14 -0
- package/dist/contexts/DataContext.d.ts +4 -1
- package/dist/contexts/DataContext.js +82 -13
- package/dist/hooks/useBacklog.js +3 -0
- package/dist/hooks/useConversationBranch.d.ts +16 -0
- package/dist/hooks/useConversationBranch.js +125 -0
- package/dist/hooks/useFontLoader.d.ts +23 -0
- package/dist/hooks/useFontLoader.js +153 -0
- package/dist/hooks/useFullscreenText.d.ts +17 -0
- package/dist/hooks/useFullscreenText.js +120 -0
- package/dist/hooks/usePlayerLogic.d.ts +10 -3
- package/dist/hooks/usePlayerLogic.js +115 -18
- package/dist/hooks/usePluginEvents.d.ts +4 -1
- package/dist/hooks/usePluginEvents.js +16 -11
- package/dist/hooks/usePreloadImages.js +27 -7
- package/dist/hooks/useSoundPlayer.d.ts +15 -0
- package/dist/hooks/useSoundPlayer.js +209 -0
- package/dist/hooks/useTypewriter.d.ts +6 -2
- package/dist/hooks/useTypewriter.js +42 -6
- package/dist/hooks/useVoice.js +7 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +3 -1
- package/dist/plugin/PluginManager.d.ts +66 -2
- package/dist/plugin/PluginManager.js +352 -79
- package/dist/sdk.d.ts +184 -22
- package/dist/sdk.js +27 -2
- package/dist/types.d.ts +303 -4
- package/dist/utils/branchBlockConverter.d.ts +2 -0
- package/dist/utils/branchBlockConverter.js +21 -0
- package/dist/utils/branchNavigator.d.ts +14 -0
- package/dist/utils/branchNavigator.js +55 -0
- package/dist/utils/facePositionCalculator.js +0 -1
- package/dist/utils/variableManager.d.ts +18 -0
- package/dist/utils/variableManager.js +159 -0
- package/package.json +1 -1
- package/dist/components/ConversationLogUI.d.ts +0 -2
- package/dist/components/ConversationLogUI.js +0 -115
- package/dist/hooks/useConversationLog.d.ts +0 -14
- package/dist/hooks/useConversationLog.js +0 -82
- package/dist/hooks/useUIVisibility.d.ts +0 -9
- package/dist/hooks/useUIVisibility.js +0 -19
- package/dist/plugin/luna-react.d.ts +0 -41
- package/dist/plugin/luna-react.js +0 -99
package/dist/sdk.d.ts
CHANGED
|
@@ -1,9 +1,38 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BackgroundData, BacklogEntry, BranchChoiceHistory, Character, ConversationBranchState, DisplayedCharacter, EntityState, ScenarioBlock, ScenarioBlockType, WorkFont } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* ブロックオプションの定義
|
|
5
|
+
* プラグインがシナリオブロックに追加できるカスタムオプションを定義
|
|
6
|
+
*/
|
|
7
|
+
export interface BlockOptionDefinition {
|
|
8
|
+
/** オプションのキー(プラグイン固有のプレフィックス推奨: "myplugin_option_name") */
|
|
9
|
+
key: string;
|
|
10
|
+
/** 表示名 */
|
|
11
|
+
name: string;
|
|
12
|
+
/** 対象のブロックタイプ(nullまたは未指定で全タイプ対象) */
|
|
13
|
+
targetBlockTypes?: ScenarioBlockType[] | null;
|
|
14
|
+
/** オプションの入力タイプ */
|
|
15
|
+
type: "select" | "text" | "number" | "boolean";
|
|
16
|
+
/** select型の場合の選択肢 */
|
|
17
|
+
options?: BlockOptionChoice[];
|
|
18
|
+
/** select以外の場合のデフォルト値 */
|
|
19
|
+
default?: string | number | boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* select型オプションの選択肢
|
|
23
|
+
*/
|
|
24
|
+
export interface BlockOptionChoice {
|
|
25
|
+
value: string;
|
|
26
|
+
label: string;
|
|
27
|
+
/** デフォルト選択かどうか */
|
|
28
|
+
isDefault?: boolean;
|
|
29
|
+
}
|
|
3
30
|
export interface LunaPlugin {
|
|
4
31
|
name: string;
|
|
5
32
|
version: string;
|
|
6
33
|
description: string;
|
|
34
|
+
/** プラグインが定義するブロックオプション */
|
|
35
|
+
blockOptions?: BlockOptionDefinition[];
|
|
7
36
|
/** プラグインインストール時の処理(オプション) */
|
|
8
37
|
onInstall?(api: PluginInstallAPI): Promise<void>;
|
|
9
38
|
/** プラグインアンインストール時の処理(オプション) */
|
|
@@ -24,12 +53,12 @@ export interface ScenarioPlaybackData {
|
|
|
24
53
|
scenarioName: string;
|
|
25
54
|
/** 現在のブロック */
|
|
26
55
|
currentBlock: ScenarioBlock | null;
|
|
27
|
-
/**
|
|
28
|
-
displayText?: string;
|
|
56
|
+
/** 表示中のテキスト(改行は自動的に<br />に変換されます) */
|
|
57
|
+
displayText?: string | React.ReactNode;
|
|
29
58
|
/** テキストアニメーション中かどうか */
|
|
30
59
|
isTyping?: boolean;
|
|
31
60
|
/** 表示中のキャラクター */
|
|
32
|
-
displayedCharacters?:
|
|
61
|
+
displayedCharacters?: DisplayedCharacter[];
|
|
33
62
|
}
|
|
34
63
|
/**
|
|
35
64
|
* バックログデータ
|
|
@@ -48,7 +77,7 @@ export interface BacklogData {
|
|
|
48
77
|
* プレイヤー設定データ
|
|
49
78
|
*/
|
|
50
79
|
export interface PlayerSettingsData extends PlayerSettings {
|
|
51
|
-
/** テキスト速度 (
|
|
80
|
+
/** テキスト速度 (ミリ秒/文字) */
|
|
52
81
|
textSpeed: number;
|
|
53
82
|
/** 自動再生速度 (秒) */
|
|
54
83
|
autoPlaySpeed: number;
|
|
@@ -73,6 +102,17 @@ export interface PluginAssetsData {
|
|
|
73
102
|
*/
|
|
74
103
|
getAssetUrl: (pluginName: string, filename: string) => string;
|
|
75
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* フォントデータ
|
|
107
|
+
*/
|
|
108
|
+
export interface FontsData {
|
|
109
|
+
/** 利用可能なフォント一覧 */
|
|
110
|
+
fonts: WorkFont[];
|
|
111
|
+
/** 選択されているフォントファミリー */
|
|
112
|
+
selectedFontFamily: string | undefined;
|
|
113
|
+
/** フォントが読み込み完了しているかどうか */
|
|
114
|
+
isLoaded: boolean;
|
|
115
|
+
}
|
|
76
116
|
/**
|
|
77
117
|
* 全データコンテキスト
|
|
78
118
|
*/
|
|
@@ -85,6 +125,16 @@ export interface DataContext {
|
|
|
85
125
|
settings: PlayerSettingsData;
|
|
86
126
|
/** プラグインアセット */
|
|
87
127
|
pluginAssets: PluginAssetsData;
|
|
128
|
+
/** 会話分岐データ */
|
|
129
|
+
branchData?: ConversationBranchState;
|
|
130
|
+
/** 分岐履歴 */
|
|
131
|
+
branchHistory?: BranchChoiceHistory[];
|
|
132
|
+
/** 現在の背景データ(単一、後方互換性用) */
|
|
133
|
+
background?: BackgroundData | null;
|
|
134
|
+
/** 現在の背景データ(複数、背景グループ対応) */
|
|
135
|
+
backgrounds?: BackgroundData[];
|
|
136
|
+
/** フォント設定 */
|
|
137
|
+
fonts?: FontsData;
|
|
88
138
|
}
|
|
89
139
|
/**
|
|
90
140
|
* データ購読コールバック
|
|
@@ -168,6 +218,68 @@ export interface DataAPI {
|
|
|
168
218
|
* @returns unsubscribe関数
|
|
169
219
|
*/
|
|
170
220
|
watch<K extends keyof DataContext, P extends keyof DataContext[K]>(key: K, property: P, callback: DataSubscriber<DataContext[K][P]>): () => void;
|
|
221
|
+
/**
|
|
222
|
+
* プレイヤー設定を更新
|
|
223
|
+
* @param settings - 更新する設定値(部分更新可能)
|
|
224
|
+
*/
|
|
225
|
+
updateSettings(settings: Partial<PlayerSettingsData>): void;
|
|
226
|
+
/**
|
|
227
|
+
* BGM音量を設定
|
|
228
|
+
* @param volume - 音量(0-1の範囲)
|
|
229
|
+
*/
|
|
230
|
+
setBgmVolume(volume: number): void;
|
|
231
|
+
/**
|
|
232
|
+
* SE音量を設定
|
|
233
|
+
* @param volume - 音量(0-1の範囲)
|
|
234
|
+
*/
|
|
235
|
+
setSeVolume(volume: number): void;
|
|
236
|
+
/**
|
|
237
|
+
* ボイス音量を設定
|
|
238
|
+
* @param volume - 音量(0-1の範囲)
|
|
239
|
+
*/
|
|
240
|
+
setVoiceVolume(volume: number): void;
|
|
241
|
+
/**
|
|
242
|
+
* 全カテゴリの音量を一括設定
|
|
243
|
+
* @param volumes - カテゴリ別音量設定
|
|
244
|
+
*/
|
|
245
|
+
setVolumes(volumes: {
|
|
246
|
+
bgm?: number;
|
|
247
|
+
se?: number;
|
|
248
|
+
voice?: number;
|
|
249
|
+
}): void;
|
|
250
|
+
/**
|
|
251
|
+
* 現在のブロックのオプション値を型安全に取得
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* // プラグイン側で型を定義
|
|
256
|
+
* type MyBlockOptions = {
|
|
257
|
+
* ultemist_bubble_style: "normal" | "monologue" | "star";
|
|
258
|
+
* ultemist_effect_type: "none" | "shake" | "fade";
|
|
259
|
+
* };
|
|
260
|
+
*
|
|
261
|
+
* // コンポーネントで使用
|
|
262
|
+
* const bubbleStyle = dataAPI.getBlockOption<MyBlockOptions, "ultemist_bubble_style">("ultemist_bubble_style");
|
|
263
|
+
* // 型: "normal" | "monologue" | "star" | undefined
|
|
264
|
+
*
|
|
265
|
+
* // または簡易版(キーのみ指定)
|
|
266
|
+
* const bubbleStyle = dataAPI.getBlockOption<MyBlockOptions>("ultemist_bubble_style");
|
|
267
|
+
* ```
|
|
268
|
+
*
|
|
269
|
+
* @param key - オプションのキー
|
|
270
|
+
* @returns オプションの値、または未設定の場合undefined
|
|
271
|
+
*/
|
|
272
|
+
getBlockOption<T extends Record<string, unknown>, K extends keyof T = keyof T>(key: K): T[K] | undefined;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* ブロックオプション登録API
|
|
276
|
+
*/
|
|
277
|
+
export interface BlockOptionsAPI {
|
|
278
|
+
/**
|
|
279
|
+
* ブロックオプションを登録
|
|
280
|
+
* @param definition - ブロックオプションの定義
|
|
281
|
+
*/
|
|
282
|
+
register(definition: BlockOptionDefinition): void;
|
|
171
283
|
}
|
|
172
284
|
export interface PluginAPI {
|
|
173
285
|
style: StyleAPI;
|
|
@@ -179,9 +291,18 @@ export interface PluginAPI {
|
|
|
179
291
|
components: ComponentAPI;
|
|
180
292
|
data: DataAPI;
|
|
181
293
|
ui: UIAPI;
|
|
294
|
+
blockOptions: BlockOptionsAPI;
|
|
182
295
|
React: typeof React;
|
|
183
296
|
setNextCharacterSpeakHandler(callback: (context: CharacterSpeakContext) => void): void;
|
|
184
297
|
getConfig?(): unknown;
|
|
298
|
+
selectChoice?(choiceId: string): void;
|
|
299
|
+
getBranchState?(): ConversationBranchState | null;
|
|
300
|
+
/**
|
|
301
|
+
* ビルトインのクリック音を上書き
|
|
302
|
+
* プラグインが独自のクリック音を再生する場合に呼び出す
|
|
303
|
+
* onBlockChangeフック内で呼び出すことで、そのブロック遷移でのビルトインクリック音を抑制する
|
|
304
|
+
*/
|
|
305
|
+
overrideClickSound?(): void;
|
|
185
306
|
}
|
|
186
307
|
export interface StyleAPI {
|
|
187
308
|
elements: {
|
|
@@ -191,6 +312,8 @@ export interface StyleAPI {
|
|
|
191
312
|
gameScreen: StyleElement;
|
|
192
313
|
characterSprite: StyleElement;
|
|
193
314
|
background: StyleElement;
|
|
315
|
+
fullscreenTextOverlay: StyleElement;
|
|
316
|
+
fullscreenTextContainer: StyleElement;
|
|
194
317
|
};
|
|
195
318
|
injectCSS(css: string): void;
|
|
196
319
|
enableTailwind(): void;
|
|
@@ -225,7 +348,7 @@ export interface AttributeDefinition {
|
|
|
225
348
|
name: string;
|
|
226
349
|
type: "text" | "textarea" | "number" | "select" | "entity";
|
|
227
350
|
label: string;
|
|
228
|
-
default?:
|
|
351
|
+
default?: string | number | boolean;
|
|
229
352
|
required?: boolean;
|
|
230
353
|
placeholder?: string;
|
|
231
354
|
min?: number;
|
|
@@ -272,7 +395,7 @@ export interface ObjectAttributeDefinition {
|
|
|
272
395
|
displayName: string;
|
|
273
396
|
dataType: "string" | "number" | "boolean" | "text";
|
|
274
397
|
isRequired: boolean;
|
|
275
|
-
defaultValue?:
|
|
398
|
+
defaultValue?: string | number | boolean;
|
|
276
399
|
sortOrder?: number;
|
|
277
400
|
}
|
|
278
401
|
/** 簡易的なオブジェクトタイプ情報 */
|
|
@@ -294,16 +417,23 @@ export interface PluginHooks {
|
|
|
294
417
|
onScenarioReady(callback: (context: ScenarioReadyContext) => void): void;
|
|
295
418
|
onBlockChange(callback: (context: BlockChangeContext) => void): void;
|
|
296
419
|
onCharacterEnter(callback: (context: CharacterContext) => void): void;
|
|
297
|
-
onCharacterExit(callback: (context: CharacterContext) => void): void;
|
|
298
420
|
onDialogueShow(callback: (context: DialogueContext) => void): void;
|
|
299
421
|
onActionExecute(callback: (context: ActionExecutionContext) => void): void;
|
|
300
422
|
onScenarioStart(callback: (context: ScenarioContext) => void): void;
|
|
301
423
|
onScenarioEnd(callback: (context: ScenarioContext) => void): void;
|
|
424
|
+
onBranchStart?(callback: (context: BranchStartContext) => void): void;
|
|
425
|
+
onChoiceSelected?(callback: (context: ChoiceSelectedContext) => void): void;
|
|
426
|
+
onBranchEnd?(callback: () => void): void;
|
|
427
|
+
onBranchBlockChange?(callback: (context: BranchBlockChangeContext) => void): void;
|
|
302
428
|
}
|
|
429
|
+
/** 遷移の種類 */
|
|
430
|
+
export type TransitionSource = "click" | "auto" | "time_wait";
|
|
303
431
|
export interface BlockChangeContext {
|
|
304
432
|
previousBlock?: ScenarioBlock;
|
|
305
433
|
currentBlock: ScenarioBlock;
|
|
306
434
|
blockIndex: number;
|
|
435
|
+
/** 遷移の種類(クリック、自動、時間待ち) */
|
|
436
|
+
transitionSource?: TransitionSource;
|
|
307
437
|
}
|
|
308
438
|
export interface CharacterContext {
|
|
309
439
|
character: Character;
|
|
@@ -358,6 +488,22 @@ export interface ScenarioReadyContext {
|
|
|
358
488
|
currentBlockIndex: number;
|
|
359
489
|
currentBlock: ScenarioBlock;
|
|
360
490
|
}
|
|
491
|
+
export interface BranchStartContext {
|
|
492
|
+
branchBlockId: string;
|
|
493
|
+
choices: Array<{
|
|
494
|
+
id: string;
|
|
495
|
+
text: string;
|
|
496
|
+
order: number;
|
|
497
|
+
}>;
|
|
498
|
+
}
|
|
499
|
+
export interface ChoiceSelectedContext {
|
|
500
|
+
choiceId: string;
|
|
501
|
+
choiceText: string;
|
|
502
|
+
}
|
|
503
|
+
export interface BranchBlockChangeContext {
|
|
504
|
+
blockIndex: number;
|
|
505
|
+
block: ScenarioBlock;
|
|
506
|
+
}
|
|
361
507
|
export interface EffectAPI {
|
|
362
508
|
show(options: EffectOptions): string;
|
|
363
509
|
hide(effectId: string): void;
|
|
@@ -372,8 +518,8 @@ export interface EffectOptions {
|
|
|
372
518
|
animation?: "fade" | "slide" | "bounce" | "none";
|
|
373
519
|
}
|
|
374
520
|
export interface StorageAPI {
|
|
375
|
-
get<T =
|
|
376
|
-
set<T =
|
|
521
|
+
get<T = unknown>(key: string): T | null;
|
|
522
|
+
set<T = unknown>(key: string, value: T): void;
|
|
377
523
|
remove(key: string): void;
|
|
378
524
|
clear(): void;
|
|
379
525
|
}
|
|
@@ -382,6 +528,12 @@ export interface AssetAPI {
|
|
|
382
528
|
preload(filenames: string[]): Promise<void>;
|
|
383
529
|
playSound(filename: string, options?: SoundOptions): void;
|
|
384
530
|
stopSound(filename: string): void;
|
|
531
|
+
/**
|
|
532
|
+
* 作品のサウンドをIDで再生
|
|
533
|
+
* @param soundId - 作品に登録されたサウンドのID
|
|
534
|
+
* @param options - 再生オプション(音量、ループなど)
|
|
535
|
+
*/
|
|
536
|
+
playWorkSound(soundId: string, options?: SoundOptions): void;
|
|
385
537
|
}
|
|
386
538
|
export interface SoundOptions {
|
|
387
539
|
volume?: number;
|
|
@@ -398,7 +550,10 @@ export declare enum ComponentType {
|
|
|
398
550
|
LoadMenu = "LoadMenu",
|
|
399
551
|
SettingsMenu = "SettingsMenu",
|
|
400
552
|
GameMenu = "GameMenu",
|
|
401
|
-
Config = "Config"
|
|
553
|
+
Config = "Config",
|
|
554
|
+
ConversationBranch = "ConversationBranch",
|
|
555
|
+
Background = "Background",
|
|
556
|
+
FullscreenTextBox = "FullscreenTextBox"
|
|
402
557
|
}
|
|
403
558
|
/**
|
|
404
559
|
* コンポーネント登録API
|
|
@@ -407,24 +562,17 @@ export declare enum ComponentType {
|
|
|
407
562
|
export interface ComponentAPI {
|
|
408
563
|
registerComponent(type: ComponentType, component: React.ComponentType): void;
|
|
409
564
|
}
|
|
410
|
-
export type { BacklogEntry };
|
|
411
|
-
export interface DisplayedCharacter {
|
|
412
|
-
objectId: string;
|
|
413
|
-
stateId?: string;
|
|
414
|
-
position?: {
|
|
415
|
-
x: number;
|
|
416
|
-
y: number;
|
|
417
|
-
};
|
|
418
|
-
scale?: number;
|
|
419
|
-
}
|
|
565
|
+
export type { BacklogEntry, DisplayedCharacter } from "./types";
|
|
420
566
|
export interface PlayerSettings {
|
|
421
567
|
textSpeed: number;
|
|
422
568
|
autoPlaySpeed: number;
|
|
423
569
|
bgmVolume: number;
|
|
424
570
|
seVolume: number;
|
|
425
571
|
voiceVolume: number;
|
|
572
|
+
/** 選択されたフォントファミリー */
|
|
573
|
+
selectedFontFamily?: string;
|
|
426
574
|
}
|
|
427
|
-
export type {
|
|
575
|
+
export type { ActionNode, BackgroundData, BackgroundGroupData, BackgroundGroupItem, BackgroundMediaType, BlockOptions, Character, EntityState, FontType, ScenarioBlock, ScenarioBlockType, WorkFont, } from "./types";
|
|
428
576
|
export declare function definePlugin(plugin: LunaPlugin): LunaPlugin;
|
|
429
577
|
export declare function defineComponent(type: ComponentType, component: React.ComponentType): {
|
|
430
578
|
type: ComponentType;
|
|
@@ -510,3 +658,17 @@ export declare function useScreenSizeAtom(): [
|
|
|
510
658
|
];
|
|
511
659
|
export { OverlayUI } from "./components/OverlayUI";
|
|
512
660
|
export { aspectRatio, BasisHeight, BasisWidth } from "./constants/screen-size";
|
|
661
|
+
/**
|
|
662
|
+
* テキスト内の改行文字(\n)を<br />タグに変換してReact要素を返す
|
|
663
|
+
* プラグインがDialogueBoxなどのコンポーネントでテキストを表示する際に使用
|
|
664
|
+
*
|
|
665
|
+
* @param text 表示するテキスト(改行文字を含む可能性がある)
|
|
666
|
+
* @returns 改行が<br />タグに変換されたReact要素
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```tsx
|
|
670
|
+
* const content = dataAPI.get("playback", "displayText") || "";
|
|
671
|
+
* return <div>{renderTextWithLineBreaks(content)}</div>;
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
export declare function renderTextWithLineBreaks(text: string): React.ReactElement | string;
|
package/dist/sdk.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
// SDK exports for plugin development
|
|
3
2
|
// This file contains all types and utilities needed for plugin development
|
|
4
3
|
import React from "react";
|
|
@@ -15,6 +14,9 @@ export var ComponentType;
|
|
|
15
14
|
ComponentType["SettingsMenu"] = "SettingsMenu";
|
|
16
15
|
ComponentType["GameMenu"] = "GameMenu";
|
|
17
16
|
ComponentType["Config"] = "Config";
|
|
17
|
+
ComponentType["ConversationBranch"] = "ConversationBranch";
|
|
18
|
+
ComponentType["Background"] = "Background";
|
|
19
|
+
ComponentType["FullscreenTextBox"] = "FullscreenTextBox";
|
|
18
20
|
})(ComponentType || (ComponentType = {}));
|
|
19
21
|
// Component types are already exported as part of the interfaces above
|
|
20
22
|
// Plugin utility function
|
|
@@ -47,7 +49,6 @@ export function calculateFaceRelativePosition(options) {
|
|
|
47
49
|
case "chin":
|
|
48
50
|
baseY = facePosition.y + facePosition.height * 0.3;
|
|
49
51
|
break;
|
|
50
|
-
case "center":
|
|
51
52
|
default:
|
|
52
53
|
// Use face center as is
|
|
53
54
|
break;
|
|
@@ -62,3 +63,27 @@ export { React };
|
|
|
62
63
|
export { OverlayUI } from "./components/OverlayUI";
|
|
63
64
|
// Screen size constants
|
|
64
65
|
export { aspectRatio, BasisHeight, BasisWidth } from "./constants/screen-size";
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Text Utilities - テキスト処理ユーティリティ
|
|
68
|
+
// ============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* テキスト内の改行文字(\n)を<br />タグに変換してReact要素を返す
|
|
71
|
+
* プラグインがDialogueBoxなどのコンポーネントでテキストを表示する際に使用
|
|
72
|
+
*
|
|
73
|
+
* @param text 表示するテキスト(改行文字を含む可能性がある)
|
|
74
|
+
* @returns 改行が<br />タグに変換されたReact要素
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```tsx
|
|
78
|
+
* const content = dataAPI.get("playback", "displayText") || "";
|
|
79
|
+
* return <div>{renderTextWithLineBreaks(content)}</div>;
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function renderTextWithLineBreaks(text) {
|
|
83
|
+
if (!text.includes("\n")) {
|
|
84
|
+
return text;
|
|
85
|
+
}
|
|
86
|
+
return React.createElement(React.Fragment, null, text
|
|
87
|
+
.split("\n")
|
|
88
|
+
.map((line, index, array) => React.createElement("span", { key: index }, line, index < array.length - 1 && React.createElement("br"))));
|
|
89
|
+
}
|