feat(scene): video map editor parity and help updates

Enable scene editor, overlays, effects, and darkness on video scenes; brighten GM trap markers; document snap, NPC types, materials, and control controls in RU/EN help.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-08-07 08:23:08 +08:00
parent 8d5a68c71e
commit 1fbaaa6e77
17 changed files with 443 additions and 98 deletions
+24 -9
View File
@@ -50,6 +50,7 @@ import { useEditorI18n } from '../editor/i18n/EditorI18nContext';
import { getDndApi } from '../shared/dndApi';
import { EllipsisText } from '../shared/ui/EllipsisText';
import ellipsisStyles from '../shared/ui/ellipsisText.module.css';
import { ContainedVideo } from '../shared/ContainedVideo';
import { SceneGridOverlay } from '../shared/grid/SceneGridOverlay';
import { PlayerTokenView } from '../shared/playerToken/PlayerTokenView';
import { RotatedImage } from '../shared/RotatedImage';
@@ -521,6 +522,8 @@ export function SceneEditorApp() {
const editingToken =
tokenModal?.mode === 'edit' ? (appTokens.find((t) => t.id === tokenModal.tokenId) ?? null) : null;
const isImage = scene?.previewAssetType === 'image' && Boolean(url);
const isVideo = scene?.previewAssetType === 'video' && Boolean(url);
const hasMapMedia = isImage || isVideo;
return (
<div className={styles.page}>
@@ -703,8 +706,8 @@ export function SceneEditorApp() {
</aside>
<div className={styles.stage}>
{!isImage ? (
<div className={styles.empty}>Нужно изображение сцены</div>
{!hasMapMedia ? (
<div className={styles.empty}>Нужно изображение или видео сцены</div>
) : (
<div
ref={hostRef}
@@ -808,13 +811,25 @@ export function SceneEditorApp() {
dragRef.current = null;
}}
>
<RotatedImage
url={url!}
rotationDeg={rot}
mode="contain"
viewCamera={viewCamera}
onContentRectChange={setContentRect}
/>
{isImage ? (
<RotatedImage
url={url!}
rotationDeg={rot}
mode="contain"
viewCamera={viewCamera}
onContentRectChange={setContentRect}
/>
) : (
<ContainedVideo
url={url!}
muted
playsInline
loop
preload="metadata"
viewCamera={viewCamera}
onContentRectChange={setContentRect}
/>
)}
<SceneGridOverlay grid={localGrid} viewport={contentRect} />
{contentRect
? localTokens.map((tok) => {