mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 00:05:39 +00:00
fix presets and motion blur, add dev sliders
This commit is contained in:
@@ -29,6 +29,10 @@ import {
|
||||
import {
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SHUTTER_FRACTION,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SHUTTER_FRACTION,
|
||||
} from "@/lib/exporter/temporalMotionBlur";
|
||||
import type { ExtensionSettingField } from "@/lib/extensions";
|
||||
import { extensionHost, type FrameInstance } from "@/lib/extensions";
|
||||
@@ -85,7 +89,6 @@ import {
|
||||
DEFAULT_WEBCAM_SHADOW,
|
||||
DEFAULT_WEBCAM_SIZE,
|
||||
DEFAULT_ZOOM_IN_DURATION_MS,
|
||||
DEFAULT_ZOOM_SMOOTHNESS,
|
||||
DEFAULT_ZOOM_OUT_DURATION_MS,
|
||||
} from "./types";
|
||||
import { fromCursorSwaySliderValue, toCursorSwaySliderValue } from "./videoPlayback/cursorSway";
|
||||
@@ -470,6 +473,7 @@ interface SettingsPanelProps {
|
||||
onShadowChange?: (intensity: number) => void;
|
||||
backgroundBlur?: number;
|
||||
onBackgroundBlurChange?: (amount: number) => void;
|
||||
zoomTemporalMotionBlur?: number;
|
||||
onZoomTemporalMotionBlurChange?: (amount: number) => void;
|
||||
zoomMotionBlurSampleCount?: number | null;
|
||||
onZoomMotionBlurSampleCountChange?: (count: number | null) => void;
|
||||
@@ -849,8 +853,11 @@ export function SettingsPanel({
|
||||
onShadowChange,
|
||||
backgroundBlur = 0,
|
||||
onBackgroundBlurChange,
|
||||
zoomTemporalMotionBlur = 0,
|
||||
onZoomTemporalMotionBlurChange,
|
||||
zoomMotionBlurSampleCount = TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT,
|
||||
onZoomMotionBlurSampleCountChange,
|
||||
zoomMotionBlurShutterFraction = TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION,
|
||||
onZoomMotionBlurShutterFractionChange,
|
||||
connectZooms = true,
|
||||
onConnectZoomsChange,
|
||||
@@ -1124,6 +1131,7 @@ export function SettingsPanel({
|
||||
() => ({ ...builtInCursorPreviewUrls, ...extensionCursorPreviewUrls }),
|
||||
[builtInCursorPreviewUrls, extensionCursorPreviewUrls],
|
||||
);
|
||||
const showDevMotionControls = import.meta.env.DEV;
|
||||
const cursorStyleOptions = useMemo<CursorStyleOption[]>(
|
||||
() => [
|
||||
...BUILTIN_CURSOR_STYLE_OPTIONS,
|
||||
@@ -1448,9 +1456,9 @@ export function SettingsPanel({
|
||||
|
||||
const resetZoomSection = () => {
|
||||
onZoomTemporalMotionBlurChange?.(initialEditorPreferences.zoomTemporalMotionBlur);
|
||||
onZoomMotionBlurSampleCountChange?.(TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT);
|
||||
onZoomMotionBlurSampleCountChange?.(initialEditorPreferences.zoomMotionBlurSampleCount);
|
||||
onZoomMotionBlurShutterFractionChange?.(
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION,
|
||||
initialEditorPreferences.zoomMotionBlurShutterFraction,
|
||||
);
|
||||
onZoomInDurationMsChange?.(initialEditorPreferences.zoomInDurationMs);
|
||||
onZoomOutDurationMsChange?.(initialEditorPreferences.zoomOutDurationMs);
|
||||
@@ -2690,14 +2698,79 @@ export function SettingsPanel({
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="rounded-lg border border-foreground/10 bg-foreground/[0.03] px-3 py-2">
|
||||
<div className="text-[10px] text-muted-foreground">
|
||||
{tSettings("effects.exportBlurLocked", "Export blur is fixed for this build.")}
|
||||
{showDevMotionControls ? (
|
||||
<div className="space-y-1.5 rounded-lg border border-[#2563EB]/15 bg-[#2563EB]/5 px-3 py-3">
|
||||
<div>
|
||||
<div className="text-[11px] font-medium text-foreground">
|
||||
{tSettings("effects.exportBlurDebug", "Export Blur Debug")}
|
||||
</div>
|
||||
<div className="mt-0.5 text-[10px] text-muted-foreground">
|
||||
{tSettings(
|
||||
"effects.exportBlurDebugHint",
|
||||
"Development-only temporal blur tuning for export and preview parity checks.",
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<SliderControl
|
||||
label={tSettings("effects.zoomTemporalMotionBlur", "Temporal blur")}
|
||||
value={zoomTemporalMotionBlur}
|
||||
defaultValue={initialEditorPreferences.zoomTemporalMotionBlur}
|
||||
min={0}
|
||||
max={2}
|
||||
step={0.05}
|
||||
onChange={(value) => onZoomTemporalMotionBlurChange?.(value)}
|
||||
formatValue={(value) => `${value.toFixed(2)}×`}
|
||||
parseInput={(text) => parseFloat(text.replace(/×$/, ""))}
|
||||
/>
|
||||
<SliderControl
|
||||
label={tSettings("effects.zoomMotionBlurSampleCount", "Sample count")}
|
||||
value={
|
||||
zoomMotionBlurSampleCount ?? TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT
|
||||
}
|
||||
defaultValue={
|
||||
initialEditorPreferences.zoomMotionBlurSampleCount ??
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT
|
||||
}
|
||||
min={TEMPORAL_MOTION_BLUR_MIN_SAMPLE_COUNT}
|
||||
max={TEMPORAL_MOTION_BLUR_MAX_SAMPLE_COUNT}
|
||||
step={2}
|
||||
onChange={(value) =>
|
||||
onZoomMotionBlurSampleCountChange?.(Math.round(value))
|
||||
}
|
||||
formatValue={(value) => `${Math.round(value)} samples`}
|
||||
parseInput={(text) => parseFloat(text.replace(/samples?$/i, "").trim())}
|
||||
/>
|
||||
<SliderControl
|
||||
label={tSettings("effects.zoomMotionBlurShutterFraction", "Shutter")}
|
||||
value={
|
||||
zoomMotionBlurShutterFraction ??
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION
|
||||
}
|
||||
defaultValue={
|
||||
initialEditorPreferences.zoomMotionBlurShutterFraction ??
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION
|
||||
}
|
||||
min={TEMPORAL_MOTION_BLUR_MIN_SHUTTER_FRACTION}
|
||||
max={TEMPORAL_MOTION_BLUR_MAX_SHUTTER_FRACTION}
|
||||
step={0.01}
|
||||
onChange={(value) => onZoomMotionBlurShutterFractionChange?.(value)}
|
||||
formatValue={(value) => `${Math.round(value * 100)}%`}
|
||||
parseInput={(text) => parseFloat(text.replace(/%$/, "")) / 100}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-1 text-[12px] font-medium text-foreground">
|
||||
{`${TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT} samples · ${Math.round(TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION * 100)}% shutter`}
|
||||
) : (
|
||||
<div className="rounded-lg border border-foreground/10 bg-foreground/[0.03] px-3 py-2">
|
||||
<div className="text-[10px] text-muted-foreground">
|
||||
{tSettings(
|
||||
"effects.exportBlurLocked",
|
||||
"Export blur is fixed for this build.",
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-1 text-[12px] font-medium text-foreground">
|
||||
{`${TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT} samples · ${Math.round(TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION * 100)}% shutter`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{selectedZoomId && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
@@ -2941,6 +3014,67 @@ export function SettingsPanel({
|
||||
return parseFloat(text.replace(/×$/, ""));
|
||||
}}
|
||||
/>
|
||||
{showDevMotionControls ? (
|
||||
<div className="space-y-1.5 rounded-lg border border-[#2563EB]/15 bg-[#2563EB]/5 px-3 py-3">
|
||||
<div>
|
||||
<div className="text-[11px] font-medium text-foreground">
|
||||
{tSettings("effects.cursorDebugTuning", "Cursor Debug Tuning")}
|
||||
</div>
|
||||
<div className="mt-0.5 text-[10px] text-muted-foreground">
|
||||
{tSettings(
|
||||
"effects.cursorDebugTuningHint",
|
||||
"Development-only spring tuning controls.",
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<SliderControl
|
||||
label={tSettings(
|
||||
"effects.cursorSpringStiffnessMultiplier",
|
||||
"Spring stiffness",
|
||||
)}
|
||||
value={cursorSpringStiffnessMultiplier}
|
||||
defaultValue={initialEditorPreferences.cursorSpringStiffnessMultiplier}
|
||||
min={0.25}
|
||||
max={3}
|
||||
step={0.01}
|
||||
onChange={(value) =>
|
||||
onCursorSpringStiffnessMultiplierChange?.(value)
|
||||
}
|
||||
formatValue={(value) => `${value.toFixed(2)}×`}
|
||||
parseInput={(text) => parseFloat(text.replace(/×$/, ""))}
|
||||
/>
|
||||
<SliderControl
|
||||
label={tSettings(
|
||||
"effects.cursorSpringDampingMultiplier",
|
||||
"Spring damping",
|
||||
)}
|
||||
value={cursorSpringDampingMultiplier}
|
||||
defaultValue={initialEditorPreferences.cursorSpringDampingMultiplier}
|
||||
min={0.25}
|
||||
max={3}
|
||||
step={0.01}
|
||||
onChange={(value) =>
|
||||
onCursorSpringDampingMultiplierChange?.(value)
|
||||
}
|
||||
formatValue={(value) => `${value.toFixed(2)}×`}
|
||||
parseInput={(text) => parseFloat(text.replace(/×$/, ""))}
|
||||
/>
|
||||
<SliderControl
|
||||
label={tSettings(
|
||||
"effects.cursorSpringMassMultiplier",
|
||||
"Spring mass",
|
||||
)}
|
||||
value={cursorSpringMassMultiplier}
|
||||
defaultValue={initialEditorPreferences.cursorSpringMassMultiplier}
|
||||
min={0.25}
|
||||
max={3}
|
||||
step={0.01}
|
||||
onChange={(value) => onCursorSpringMassMultiplierChange?.(value)}
|
||||
formatValue={(value) => `${value.toFixed(2)}×`}
|
||||
parseInput={(text) => parseFloat(text.replace(/×$/, ""))}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{renderExtensionPanelsForSections("cursor")}
|
||||
</section>
|
||||
|
||||
@@ -597,6 +597,15 @@ export default function VideoEditor() {
|
||||
);
|
||||
const [backgroundBlur, setBackgroundBlur] = useState(initialEditorPreferences.backgroundBlur);
|
||||
const [zoomMotionBlur, setZoomMotionBlur] = useState(initialEditorPreferences.zoomMotionBlur);
|
||||
const [zoomTemporalMotionBlur, setZoomTemporalMotionBlur] = useState(
|
||||
initialEditorPreferences.zoomTemporalMotionBlur,
|
||||
);
|
||||
const [zoomMotionBlurSampleCount, setZoomMotionBlurSampleCount] = useState<number | null>(
|
||||
initialEditorPreferences.zoomMotionBlurSampleCount,
|
||||
);
|
||||
const [zoomMotionBlurShutterFraction, setZoomMotionBlurShutterFraction] = useState<
|
||||
number | null
|
||||
>(initialEditorPreferences.zoomMotionBlurShutterFraction);
|
||||
const [autoApplyFreshRecordingAutoZooms, setAutoApplyFreshRecordingAutoZooms] = useState(
|
||||
initialEditorPreferences.autoApplyFreshRecordingAutoZooms,
|
||||
);
|
||||
@@ -829,10 +838,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur: zoomMotionBlur,
|
||||
zoomMotionBlurSampleCount: initialEditorPreferences.zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction:
|
||||
initialEditorPreferences.zoomMotionBlurShutterFraction,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -877,8 +885,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
initialEditorPreferences.zoomMotionBlurSampleCount,
|
||||
initialEditorPreferences.zoomMotionBlurShutterFraction,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -964,6 +973,9 @@ export default function VideoEditor() {
|
||||
setShadowIntensity(snapshot.shadowIntensity);
|
||||
setBackgroundBlur(snapshot.backgroundBlur);
|
||||
setZoomMotionBlur(snapshot.zoomMotionBlur);
|
||||
setZoomTemporalMotionBlur(snapshot.zoomTemporalMotionBlur);
|
||||
setZoomMotionBlurSampleCount(snapshot.zoomMotionBlurSampleCount);
|
||||
setZoomMotionBlurShutterFraction(snapshot.zoomMotionBlurShutterFraction);
|
||||
setConnectZooms(snapshot.connectZooms);
|
||||
setZoomInDurationMs(snapshot.zoomInDurationMs);
|
||||
setZoomInOverlapMs(snapshot.zoomInOverlapMs);
|
||||
@@ -1192,6 +1204,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -1338,6 +1353,9 @@ export default function VideoEditor() {
|
||||
zoomInEasing,
|
||||
zoomInOverlapMs,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
zoomOutDurationMs,
|
||||
zoomOutEasing,
|
||||
zoomRegions,
|
||||
@@ -1640,6 +1658,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity: number;
|
||||
backgroundBlur: number;
|
||||
zoomMotionBlur: number;
|
||||
zoomTemporalMotionBlur: number;
|
||||
zoomMotionBlurSampleCount: number | null;
|
||||
zoomMotionBlurShutterFraction: number | null;
|
||||
connectZooms: boolean;
|
||||
zoomInDurationMs: number;
|
||||
zoomInOverlapMs: number;
|
||||
@@ -1791,6 +1812,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -1844,6 +1868,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -2025,6 +2052,9 @@ export default function VideoEditor() {
|
||||
setShadowIntensity(normalizedEditor.shadowIntensity);
|
||||
setBackgroundBlur(normalizedEditor.backgroundBlur);
|
||||
setZoomMotionBlur(normalizedEditor.zoomMotionBlur);
|
||||
setZoomTemporalMotionBlur(normalizedEditor.zoomTemporalMotionBlur);
|
||||
setZoomMotionBlurSampleCount(normalizedEditor.zoomMotionBlurSampleCount);
|
||||
setZoomMotionBlurShutterFraction(normalizedEditor.zoomMotionBlurShutterFraction);
|
||||
setConnectZooms(normalizedEditor.connectZooms);
|
||||
setZoomInDurationMs(normalizedEditor.zoomInDurationMs);
|
||||
setZoomInOverlapMs(normalizedEditor.zoomInOverlapMs);
|
||||
@@ -2431,6 +2461,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
autoApplyFreshRecordingAutoZooms,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
@@ -2475,6 +2508,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
autoApplyFreshRecordingAutoZooms,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
@@ -4313,6 +4349,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity: effectiveShadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -4489,6 +4528,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity: effectiveShadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -4740,6 +4782,9 @@ export default function VideoEditor() {
|
||||
shadowIntensity,
|
||||
backgroundBlur,
|
||||
zoomMotionBlur,
|
||||
zoomTemporalMotionBlur,
|
||||
zoomMotionBlurSampleCount,
|
||||
zoomMotionBlurShutterFraction,
|
||||
connectZooms,
|
||||
zoomInDurationMs,
|
||||
zoomInOverlapMs,
|
||||
@@ -5721,6 +5766,14 @@ export default function VideoEditor() {
|
||||
onShadowChange={setShadowIntensity}
|
||||
backgroundBlur={backgroundBlur}
|
||||
onBackgroundBlurChange={setBackgroundBlur}
|
||||
zoomTemporalMotionBlur={zoomTemporalMotionBlur}
|
||||
onZoomTemporalMotionBlurChange={setZoomTemporalMotionBlur}
|
||||
zoomMotionBlurSampleCount={zoomMotionBlurSampleCount}
|
||||
onZoomMotionBlurSampleCountChange={setZoomMotionBlurSampleCount}
|
||||
zoomMotionBlurShutterFraction={zoomMotionBlurShutterFraction}
|
||||
onZoomMotionBlurShutterFractionChange={
|
||||
setZoomMotionBlurShutterFraction
|
||||
}
|
||||
autoApplyFreshRecordingAutoZooms={autoApplyFreshRecordingAutoZooms}
|
||||
onAutoApplyFreshRecordingAutoZoomsChange={
|
||||
setAutoApplyFreshRecordingAutoZooms
|
||||
|
||||
@@ -32,8 +32,8 @@ export const CURSOR_MOTION_PRESETS: Record<CursorMotionPresetId, CursorMotionPre
|
||||
id: "focused",
|
||||
label: "Focused",
|
||||
zoomSmoothness: 0.5,
|
||||
zoomInDurationMs: 100,
|
||||
zoomOutDurationMs: 100,
|
||||
zoomInDurationMs: 200,
|
||||
zoomOutDurationMs: 200,
|
||||
...SHARED_CURSOR_PRESET_VALUES,
|
||||
cursorSpringStiffnessMultiplier: 1.35,
|
||||
cursorSpringDampingMultiplier: 0.79,
|
||||
|
||||
@@ -12,6 +12,10 @@ import { isValidMp4FrameRate } from "@/lib/exporter";
|
||||
import {
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SHUTTER_FRACTION,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SHUTTER_FRACTION,
|
||||
} from "@/lib/exporter/temporalMotionBlur";
|
||||
import { DEFAULT_WALLPAPER_PATH } from "@/lib/wallpapers";
|
||||
import { ASPECT_RATIOS, type AspectRatio, isCustomAspectRatio } from "@/utils/aspectRatioUtils";
|
||||
@@ -300,6 +304,27 @@ export function validateProjectData(candidate: unknown): candidate is EditorProj
|
||||
}
|
||||
|
||||
export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): ProjectEditorState {
|
||||
const normalizeTemporalBlurSampleCount = (value: unknown): number => {
|
||||
if (!isFiniteNumber(value)) {
|
||||
return TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT;
|
||||
}
|
||||
|
||||
const roundedValue = Math.round(value);
|
||||
const clampedValue = clamp(
|
||||
roundedValue,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SAMPLE_COUNT,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SAMPLE_COUNT,
|
||||
);
|
||||
|
||||
if (clampedValue % 2 === 1) {
|
||||
return clampedValue;
|
||||
}
|
||||
|
||||
return clampedValue >= TEMPORAL_MOTION_BLUR_MAX_SAMPLE_COUNT
|
||||
? clampedValue - 1
|
||||
: clampedValue + 1;
|
||||
};
|
||||
|
||||
const validAspectRatios = new Set<AspectRatio>(ASPECT_RATIOS);
|
||||
const legacyMotionBlurEnabled = (editor as Partial<{ motionBlurEnabled: boolean }>)
|
||||
.motionBlurEnabled;
|
||||
@@ -323,9 +348,18 @@ export function normalizeProjectEditor(editor: Partial<ProjectEditorState>): Pro
|
||||
: legacyShowBlur
|
||||
? 2
|
||||
: 0;
|
||||
const normalizedZoomMotionBlurSampleCount = TEMPORAL_MOTION_BLUR_DEFAULT_SAMPLE_COUNT;
|
||||
const normalizedZoomMotionBlurShutterFraction =
|
||||
TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION;
|
||||
const normalizedZoomMotionBlurSampleCount = normalizeTemporalBlurSampleCount(
|
||||
(editor as Partial<ProjectEditorState>).zoomMotionBlurSampleCount,
|
||||
);
|
||||
const normalizedZoomMotionBlurShutterFraction = isFiniteNumber(
|
||||
(editor as Partial<ProjectEditorState>).zoomMotionBlurShutterFraction,
|
||||
)
|
||||
? clamp(
|
||||
(editor as Partial<ProjectEditorState>).zoomMotionBlurShutterFraction as number,
|
||||
TEMPORAL_MOTION_BLUR_MIN_SHUTTER_FRACTION,
|
||||
TEMPORAL_MOTION_BLUR_MAX_SHUTTER_FRACTION,
|
||||
)
|
||||
: TEMPORAL_MOTION_BLUR_DEFAULT_SHUTTER_FRACTION;
|
||||
const normalizedZoomInDurationMs = isFiniteNumber(editor.zoomInDurationMs)
|
||||
? clamp(editor.zoomInDurationMs, 60, 4000)
|
||||
: DEFAULT_MOTION_PRESET.zoomInDurationMs;
|
||||
|
||||
@@ -2638,16 +2638,6 @@ export class FrameRenderer {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (resolvedSnapshot !== lastSnapshot) {
|
||||
await this.renderSceneSample(
|
||||
Math.round(resolvedSnapshot.timeMs * 1000),
|
||||
Math.round(resolvedSnapshot.cursorTimeMs * 1000),
|
||||
Math.round(resolvedSnapshot.backgroundTimelineTimeMs * 1000),
|
||||
layoutCache,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
}
|
||||
this.updateCaptionLayer(resolvedSnapshot.timeMs);
|
||||
|
||||
const hasOverlayCanvasWork =
|
||||
|
||||
Reference in New Issue
Block a user