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:
@@ -1,6 +1,11 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import type { SceneDarknessRevealStroke, SceneDarknessState } from '../../../shared/types';
|
||||
import type {
|
||||
SceneDarknessRevealStroke,
|
||||
SceneDarknessState,
|
||||
SceneDarknessStrokeMode,
|
||||
} from '../../../shared/types';
|
||||
import { normalizeSceneDarknessStrokeMode } from '../../../shared/types/sceneDarkness';
|
||||
|
||||
export type SceneDarknessOverlayProps = {
|
||||
state: SceneDarknessState | null;
|
||||
@@ -10,14 +15,18 @@ export type SceneDarknessOverlayProps = {
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
function drawRevealStroke(
|
||||
function drawDarknessStroke(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
stroke: SceneDarknessRevealStroke | { points: { x: number; y: number }[]; radiusN: number },
|
||||
stroke: SceneDarknessRevealStroke | { points: { x: number; y: number }[]; radiusN: number; mode?: SceneDarknessStrokeMode },
|
||||
w: number,
|
||||
h: number,
|
||||
): void {
|
||||
const pts = stroke.points;
|
||||
if (pts.length === 0) return;
|
||||
const mode = normalizeSceneDarknessStrokeMode(stroke.mode);
|
||||
ctx.globalCompositeOperation = mode === 'cover' ? 'source-over' : 'destination-out';
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.strokeStyle = '#000000';
|
||||
const r = stroke.radiusN * Math.min(w, h);
|
||||
if (pts.length === 1) {
|
||||
const p = pts[0];
|
||||
@@ -30,7 +39,6 @@ function drawRevealStroke(
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.lineWidth = r * 2;
|
||||
ctx.strokeStyle = 'rgba(0,0,0,1)';
|
||||
ctx.beginPath();
|
||||
const first = pts[0];
|
||||
if (!first) return;
|
||||
@@ -65,12 +73,11 @@ export function SceneDarknessOverlay({
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.fillRect(0, 0, w, h);
|
||||
|
||||
ctx.globalCompositeOperation = 'destination-out';
|
||||
for (const stroke of state.strokes) {
|
||||
drawRevealStroke(ctx, stroke, w, h);
|
||||
drawDarknessStroke(ctx, stroke, w, h);
|
||||
}
|
||||
if (state.draft && state.draft.points.length > 0) {
|
||||
drawRevealStroke(ctx, state.draft, w, h);
|
||||
drawDarknessStroke(ctx, state.draft, w, h);
|
||||
}
|
||||
}, [state, viewport]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user