mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(studio): split color grading inspector files
This commit is contained in:
@@ -1,120 +1,14 @@
|
||||
import { parseCssColor, type ParsedColor } from "./colorValue";
|
||||
import { COMMON_LOCAL_FONT_FAMILIES } from "./fontCatalog";
|
||||
import type { DomEditSelection } from "./domEditing";
|
||||
import type { ImportedFontAsset } from "./fontAssets";
|
||||
import type { GsapAnimation } from "@hyperframes/parsers/gsap-parser";
|
||||
import { roundToCenti } from "../../utils/rounding";
|
||||
|
||||
export interface PropertyPanelProps {
|
||||
projectId: string;
|
||||
projectDir: string | null;
|
||||
assets: string[];
|
||||
element: DomEditSelection | null;
|
||||
multiSelectCount?: number;
|
||||
copiedAgentPrompt: boolean;
|
||||
onClearSelection: () => void;
|
||||
/** Dissolve the selected data-hf-group wrapper (shown only for group selections). */
|
||||
onUngroup?: () => void;
|
||||
onSetStyle: (prop: string, value: string) => void | Promise<void>;
|
||||
onSetAttribute: (attr: string, value: string) => void | Promise<void>;
|
||||
onSetAttributeLive: (attr: string, value: string | null) => void | Promise<void>;
|
||||
onApplyColorGradingScope?: (
|
||||
scope: "source-file" | "project",
|
||||
value: string | null,
|
||||
) => Promise<{ changedFiles: number; changedElements: number }>;
|
||||
onSetHtmlAttribute: (attr: string, value: string | null) => void | Promise<void>;
|
||||
onRemoveBackground?: (
|
||||
inputPath: string,
|
||||
options: {
|
||||
createBackgroundPlate?: boolean;
|
||||
quality?: "fast" | "balanced" | "best";
|
||||
onProgress?: (progress: BackgroundRemovalProgress) => void;
|
||||
},
|
||||
) => Promise<BackgroundRemovalResult>;
|
||||
onSetManualOffset: (element: DomEditSelection, next: { x: number; y: number }) => void;
|
||||
onSetManualSize: (element: DomEditSelection, next: { width: number; height: number }) => void;
|
||||
onSetManualRotation: (element: DomEditSelection, next: { angle: number }) => void;
|
||||
onSetText: (value: string, fieldKey?: string) => void;
|
||||
onSetTextFieldStyle: (fieldKey: string, property: string, value: string) => void;
|
||||
onAddTextField: (afterFieldKey?: string) => string | Promise<string | null> | null;
|
||||
onRemoveTextField: (fieldKey: string) => void;
|
||||
onAskAgent: () => void;
|
||||
onImportAssets?: (files: FileList, dir?: string) => Promise<string[]>;
|
||||
fontAssets?: ImportedFontAsset[];
|
||||
onImportFonts?: (files: FileList | File[]) => Promise<ImportedFontAsset[]>;
|
||||
previewIframeRef?: React.RefObject<HTMLIFrameElement | null>;
|
||||
gsapAnimations?: import("@hyperframes/parsers/gsap-parser").GsapAnimation[];
|
||||
gsapMultipleTimelines?: boolean;
|
||||
gsapUnsupportedTimelinePattern?: boolean;
|
||||
onUpdateGsapProperty?: (animId: string, prop: string, value: number | string) => void;
|
||||
onUpdateGsapMeta?: (
|
||||
animId: string,
|
||||
updates: { duration?: number; ease?: string; position?: number },
|
||||
) => void;
|
||||
onDeleteGsapAnimation?: (animId: string) => void;
|
||||
onAddGsapProperty?: (animId: string, prop: string) => void;
|
||||
onRemoveGsapProperty?: (animId: string, prop: string) => void;
|
||||
onUpdateGsapFromProperty?: (animId: string, prop: string, value: number | string) => void;
|
||||
onAddGsapFromProperty?: (animId: string, prop: string) => void;
|
||||
onRemoveGsapFromProperty?: (animId: string, prop: string) => void;
|
||||
onAddGsapAnimation?: (method: "to" | "from" | "set" | "fromTo") => void;
|
||||
onSetArcPath?: (
|
||||
animId: string,
|
||||
config: {
|
||||
enabled: boolean;
|
||||
autoRotate?: boolean | number;
|
||||
segments?: import("@hyperframes/parsers/gsap-parser").ArcPathSegment[];
|
||||
},
|
||||
) => void;
|
||||
onUpdateArcSegment?: (
|
||||
animId: string,
|
||||
segmentIndex: number,
|
||||
update: Partial<import("@hyperframes/parsers/gsap-parser").ArcPathSegment>,
|
||||
) => void;
|
||||
/** Unroll computed (helper/loop) tweens into literal tweens for direct editing. */
|
||||
onUnroll?: (animationId: string) => void;
|
||||
onAddKeyframe?: (
|
||||
animationId: string,
|
||||
percentage: number,
|
||||
property: string,
|
||||
value: number | string,
|
||||
) => void;
|
||||
onRemoveKeyframe?: (animationId: string, percentage: number) => void;
|
||||
onUpdateKeyframeEase?: (animationId: string, percentage: number, ease: string) => void;
|
||||
onSetAllKeyframeEases?: (animationId: string, ease: string) => void;
|
||||
onConvertToKeyframes?: (animationId: string, duration?: number) => void;
|
||||
onCommitAnimatedProperty?: (
|
||||
selection: DomEditSelection,
|
||||
property: string,
|
||||
value: number | string,
|
||||
) => Promise<void>;
|
||||
/** Batched variant: commit several props into ONE keyframe (e.g. the 3D cube's
|
||||
* rotationX/Y/Z) so multi-axis edits don't race into adjacent duplicates. */
|
||||
onCommitAnimatedProperties?: (
|
||||
selection: DomEditSelection,
|
||||
props: Record<string, number | string>,
|
||||
) => Promise<void>;
|
||||
onSeekToTime?: (time: number) => void;
|
||||
recordingState?: "idle" | "recording" | "preview";
|
||||
recordingDuration?: number;
|
||||
onToggleRecording?: () => void;
|
||||
}
|
||||
|
||||
export interface BackgroundRemovalProgress {
|
||||
status: "processing" | "complete" | "failed";
|
||||
progress: number;
|
||||
stage?: string;
|
||||
outputPath?: string;
|
||||
backgroundOutputPath?: string;
|
||||
error?: string;
|
||||
provider?: string;
|
||||
}
|
||||
|
||||
export interface BackgroundRemovalResult {
|
||||
outputPath: string;
|
||||
backgroundOutputPath?: string;
|
||||
provider?: string;
|
||||
}
|
||||
export type {
|
||||
BackgroundRemovalProgress,
|
||||
BackgroundRemovalResult,
|
||||
PropertyPanelProps,
|
||||
} from "./propertyPanelTypes";
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Font types & constants (shared by font and section modules) */
|
||||
@@ -350,23 +244,24 @@ export function normalizeTextMetricValue(
|
||||
}
|
||||
|
||||
function splitCssFunctions(value: string): string[] {
|
||||
const source = value.trim();
|
||||
const functions: string[] = [];
|
||||
let current = "";
|
||||
// fallow-ignore-next-line code-duplication -- pre-existing; surfaced in this file's diff by an unrelated line shift
|
||||
let depth = 0;
|
||||
let start = 0;
|
||||
|
||||
for (const char of value.trim()) {
|
||||
for (let index = 0; index < source.length; index += 1) {
|
||||
const char = source[index];
|
||||
if (char === "(") depth += 1;
|
||||
if (char === ")") depth = Math.max(0, depth - 1);
|
||||
if (/\s/.test(char) && depth === 0) {
|
||||
if (current.trim()) functions.push(current.trim());
|
||||
current = "";
|
||||
continue;
|
||||
const part = source.slice(start, index).trim();
|
||||
if (part) functions.push(part);
|
||||
start = index + 1;
|
||||
}
|
||||
current += char;
|
||||
}
|
||||
|
||||
if (current.trim()) functions.push(current.trim());
|
||||
const lastPart = source.slice(start).trim();
|
||||
if (lastPart) functions.push(lastPart);
|
||||
return functions;
|
||||
}
|
||||
|
||||
@@ -518,11 +413,11 @@ export function extractBackgroundImageUrl(value: string | undefined): string {
|
||||
|
||||
// ── GSAP runtime value readers (used by PropertyPanel) ────────────────────
|
||||
|
||||
// fallow-ignore-next-line complexity -- pre-existing; surfaced in this file's diff by an unrelated line shift
|
||||
// Core transform channels the panel ALWAYS reads live — even before a just-set
|
||||
// value (e.g. rotationX) has re-parsed into `gsapAnimations`. Without this the
|
||||
// cube + fields drop the prop and flicker to 0 on every commit; gsap.getProperty
|
||||
// reflects the in-place instant patch, so it's the true current value.
|
||||
// fallow-ignore-next-line complexity
|
||||
const ALWAYS_READ_CHANNELS = [
|
||||
"x",
|
||||
"y",
|
||||
|
||||
Reference in New Issue
Block a user