feat(effects): add Closing brush as inverse of Opening brush

Allow covering revealed darkness again during darkened scene sessions.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-07-30 17:21:40 +08:00
parent a3a03eb9e3
commit 41b112159f
7 changed files with 108 additions and 19 deletions
+1
View File
@@ -11,6 +11,7 @@ export type EffectToolType =
| 'explosion'
| 'freeze'
| 'exploreBrush'
| 'closeBrush'
| 'eraser';
export type EffectInstanceType =
+17 -2
View File
@@ -1,11 +1,22 @@
import type { NPoint } from './effects';
/** reveal — снимает тьму (Кисть Открытия); cover — возвращает тьму (Кисть Закрытия). */
export type SceneDarknessStrokeMode = 'reveal' | 'cover';
export type SceneDarknessRevealStroke = {
id: string;
seed: number;
createdAtMs: number;
points: NPoint[];
radiusN: number;
/** По умолчанию reveal (старые штрихи без поля). */
mode?: SceneDarknessStrokeMode;
};
export type SceneDarknessDraft = {
points: NPoint[];
radiusN: number;
mode?: SceneDarknessStrokeMode;
};
export type SceneDarknessState = {
@@ -14,9 +25,13 @@ export type SceneDarknessState = {
enabled: boolean;
cacheKey: string | null;
strokes: SceneDarknessRevealStroke[];
draft: { points: NPoint[]; radiusN: number } | null;
draft: SceneDarknessDraft | null;
};
export type SceneDarknessEvent =
| { kind: 'draft.set'; draft: { points: NPoint[]; radiusN: number } | null }
| { kind: 'draft.set'; draft: SceneDarknessDraft | null }
| { kind: 'stroke.add'; stroke: SceneDarknessRevealStroke };
export function normalizeSceneDarknessStrokeMode(raw: unknown): SceneDarknessStrokeMode {
return raw === 'cover' ? 'cover' : 'reveal';
}