mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
refactor: extract decoration model types
Move animation, effect, mask, and param value shapes into model decorations so element data no longer depends on decoration domains. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { snapToStep } from "@/utils/math";
|
import { snapToStep } from "@/utils/math";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type { DynamicAnimationPathValue, NumericSpec } from "./types";
|
import type { DynamicAnimationPathValue, NumericSpec } from "./types";
|
||||||
|
|
||||||
export function getAnimationParamValueKind({
|
export function getAnimationParamValueKind({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ScalarAnimationKey } from "@/animation/types";
|
import type { ScalarAnimationKey } from "@/model/decorations/animations";
|
||||||
|
|
||||||
const BEZIER_SOLVE_ITERATIONS = 20;
|
const BEZIER_SOLVE_ITERATIONS = 20;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
import { converter, formatHex, formatHex8, parse } from "culori";
|
import { converter, formatHex, formatHex8, parse } from "culori";
|
||||||
import type {
|
import type { AnimationBindingComponent, AnimationBindingInstance, AnimationBindingKind, AnimationBindingOfKind, AnimationPath, AnimationValue, ColorAnimationBinding, DiscreteAnimationBinding, DiscreteValue, NumberAnimationBinding, Vector2AnimationBinding, VectorValue } from "@/model/decorations/animations";
|
||||||
AnimationBindingComponent,
|
|
||||||
AnimationBindingOfKind,
|
|
||||||
AnimationBindingInstance,
|
|
||||||
AnimationBindingKind,
|
|
||||||
ColorAnimationBinding,
|
|
||||||
DiscreteAnimationBinding,
|
|
||||||
NumberAnimationBinding,
|
|
||||||
AnimationPath,
|
|
||||||
AnimationValue,
|
|
||||||
DiscreteValue,
|
|
||||||
Vector2AnimationBinding,
|
|
||||||
VectorValue,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import { clamp } from "@/utils/math";
|
import { clamp } from "@/utils/math";
|
||||||
|
|
||||||
interface LinearRgba {
|
interface LinearRgba {
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ import {
|
|||||||
getDefaultLeftHandle,
|
getDefaultLeftHandle,
|
||||||
getDefaultRightHandle,
|
getDefaultRightHandle,
|
||||||
} from "@/animation/bezier";
|
} from "@/animation/bezier";
|
||||||
import type {
|
import type { CurveHandle, NormalizedCubicBezier, ScalarAnimationKey } from "@/model/decorations/animations";
|
||||||
CurveHandle,
|
|
||||||
NormalizedCubicBezier,
|
|
||||||
ScalarAnimationKey,
|
|
||||||
} from "@/animation/types";
|
|
||||||
|
|
||||||
const VALUE_EPSILON = 1e-6;
|
const VALUE_EPSILON = 1e-6;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import type {
|
import type { EffectParamPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
ElementAnimations,
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
EffectParamPath,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { ParamValues } from "@/params";
|
|
||||||
import { removeElementKeyframe } from "./keyframes";
|
import { removeElementKeyframe } from "./keyframes";
|
||||||
import { resolveAnimationPathValueAtTime } from "./resolve";
|
import { resolveAnimationPathValueAtTime } from "./resolve";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import type {
|
import type { AnimationBindingInstance, AnimationPath, ElementAnimations, ScalarAnimationChannel } from "@/model/decorations/animations";
|
||||||
AnimationBindingInstance,
|
import type { ScalarGraphChannel, ScalarGraphKeyframeContext } from "@/animation/types";
|
||||||
AnimationPath,
|
|
||||||
ElementAnimations,
|
|
||||||
ScalarAnimationChannel,
|
|
||||||
ScalarGraphChannel,
|
|
||||||
ScalarGraphKeyframeContext,
|
|
||||||
} from "@/animation/types";
|
|
||||||
|
|
||||||
export interface EditableScalarChannels {
|
export interface EditableScalarChannels {
|
||||||
binding: AnimationBindingInstance;
|
binding: AnimationBindingInstance;
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import type {
|
import type { ElementAnimations, GraphicParamPath } from "@/model/decorations/animations";
|
||||||
ElementAnimations,
|
import type { ParamDefinition, ParamValues } from "@/model/decorations/param-values";
|
||||||
GraphicParamPath,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { ParamDefinition, ParamValues } from "@/params";
|
|
||||||
import { resolveAnimationPathValueAtTime } from "./resolve";
|
import { resolveAnimationPathValueAtTime } from "./resolve";
|
||||||
|
|
||||||
export const GRAPHIC_PARAM_PATH_PREFIX = "params.";
|
export const GRAPHIC_PARAM_PATH_PREFIX = "params.";
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
import type {
|
import type { AnimationChannel, AnimationInterpolation, AnimationValue, DiscreteAnimationChannel, DiscreteValue, ScalarAnimationChannel, ScalarAnimationKey, ScalarSegmentType } from "@/model/decorations/animations";
|
||||||
AnimationChannel,
|
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationValue,
|
|
||||||
DiscreteAnimationChannel,
|
|
||||||
DiscreteValue,
|
|
||||||
ScalarAnimationChannel,
|
|
||||||
ScalarAnimationKey,
|
|
||||||
ScalarSegmentType,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
getBezierPoint,
|
getBezierPoint,
|
||||||
getDefaultLeftHandle,
|
getDefaultLeftHandle,
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
import type {
|
import type { AnimationBindingInstance, AnimationChannel, AnimationPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
AnimationBindingInstance,
|
import type { ElementKeyframe } from "@/animation/types";
|
||||||
AnimationChannel,
|
|
||||||
AnimationPath,
|
|
||||||
ElementAnimations,
|
|
||||||
ElementKeyframe,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
type AnimationComponentValue,
|
type AnimationComponentValue,
|
||||||
composeAnimationValue,
|
composeAnimationValue,
|
||||||
|
|||||||
@@ -1,18 +1,5 @@
|
|||||||
import type {
|
import type { AnimationBindingInstance, AnimationBindingKind, AnimationChannel, AnimationInterpolation, AnimationPath, AnimationValue, DiscreteAnimationChannel, DiscreteAnimationKey, ElementAnimations, ScalarAnimationChannel, ScalarAnimationKey, ScalarSegmentType } from "@/model/decorations/animations";
|
||||||
AnimationBindingInstance,
|
import type { ScalarCurveKeyframePatch } from "@/animation/types";
|
||||||
AnimationBindingKind,
|
|
||||||
AnimationChannel,
|
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationPath,
|
|
||||||
AnimationValue,
|
|
||||||
DiscreteAnimationChannel,
|
|
||||||
DiscreteAnimationKey,
|
|
||||||
ElementAnimations,
|
|
||||||
ScalarAnimationChannel,
|
|
||||||
ScalarAnimationKey,
|
|
||||||
ScalarCurveKeyframePatch,
|
|
||||||
ScalarSegmentType,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
cloneAnimationBinding,
|
cloneAnimationBinding,
|
||||||
createAnimationBinding,
|
createAnimationBinding,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { AnimationPath, AnimationPropertyPath } from "@/animation/types";
|
import type { AnimationPath, AnimationPropertyPath } from "@/model/decorations/animations";
|
||||||
import { ANIMATION_PROPERTY_PATHS } from "./types";
|
import { ANIMATION_PROPERTY_PATHS } from "./types";
|
||||||
import { isEffectParamPath } from "./effect-param-channel";
|
import { isEffectParamPath } from "./effect-param-channel";
|
||||||
import { isGraphicParamPath } from "./graphic-param-channel";
|
import { isGraphicParamPath } from "./graphic-param-channel";
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import type {
|
import type { AnimationPropertyGroup, AnimationPropertyPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
AnimationPropertyGroup,
|
import { ANIMATION_PROPERTY_GROUPS } from "@/model/decorations/animations";
|
||||||
AnimationPropertyPath,
|
|
||||||
ElementAnimations,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import { ANIMATION_PROPERTY_GROUPS } from "@/animation/types";
|
|
||||||
import { getKeyframeAtTime } from "./keyframe-query";
|
import { getKeyframeAtTime } from "./keyframe-query";
|
||||||
|
|
||||||
export interface GroupKeyframeRef {
|
export interface GroupKeyframeRef {
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { AnimationPath, AnimationValueForPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
|
||||||
AnimationValueForPath,
|
|
||||||
ElementAnimations,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
type AnimationComponentValue,
|
type AnimationComponentValue,
|
||||||
composeAnimationValue,
|
composeAnimationValue,
|
||||||
|
|||||||
+57
-181
@@ -1,186 +1,62 @@
|
|||||||
export const ANIMATION_PROPERTY_PATHS = [
|
import type {
|
||||||
"transform.positionX",
|
AnimationInterpolation,
|
||||||
"transform.positionY",
|
AnimationPath,
|
||||||
"transform.scaleX",
|
AnimationValue,
|
||||||
"transform.scaleY",
|
CurveHandle,
|
||||||
"transform.rotate",
|
ScalarAnimationChannel,
|
||||||
"opacity",
|
ScalarAnimationKey,
|
||||||
"volume",
|
ScalarSegmentType,
|
||||||
"color",
|
TangentMode,
|
||||||
"background.color",
|
} from "@/model/decorations/animations";
|
||||||
"background.paddingX",
|
|
||||||
"background.paddingY",
|
|
||||||
"background.offsetX",
|
|
||||||
"background.offsetY",
|
|
||||||
"background.cornerRadius",
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
export type AnimationPropertyPath = (typeof ANIMATION_PROPERTY_PATHS)[number];
|
export type {
|
||||||
export type GraphicParamPath = `params.${string}`;
|
AnimationBindingByKind,
|
||||||
export type EffectParamPath = `effects.${string}.params.${string}`;
|
AnimationBindingComponent,
|
||||||
export type AnimationPath =
|
AnimationBindingInstance,
|
||||||
| AnimationPropertyPath
|
AnimationBindingKind,
|
||||||
| GraphicParamPath
|
AnimationBindingOfKind,
|
||||||
| EffectParamPath;
|
AnimationChannel,
|
||||||
|
AnimationColorPropertyPath,
|
||||||
|
AnimationInterpolation,
|
||||||
|
AnimationKeyframe,
|
||||||
|
AnimationNumericPropertyPath,
|
||||||
|
AnimationPath,
|
||||||
|
AnimationPropertyGroup,
|
||||||
|
AnimationPropertyPath,
|
||||||
|
AnimationPropertyValueMap,
|
||||||
|
AnimationValue,
|
||||||
|
AnimationValueForPath,
|
||||||
|
ChannelExtrapolationMode,
|
||||||
|
ColorAnimationBinding,
|
||||||
|
ContinuousKeyframeInterpolation,
|
||||||
|
CurveHandle,
|
||||||
|
DiscreteAnimationBinding,
|
||||||
|
DiscreteAnimationChannel,
|
||||||
|
DiscreteAnimationKey,
|
||||||
|
DiscreteKeyframeInterpolation,
|
||||||
|
DiscreteValue,
|
||||||
|
DynamicAnimationPathValue,
|
||||||
|
EffectParamPath,
|
||||||
|
ElementAnimationBindingMap,
|
||||||
|
ElementAnimationChannelMap,
|
||||||
|
ElementAnimations,
|
||||||
|
GraphicParamPath,
|
||||||
|
NormalizedCubicBezier,
|
||||||
|
NumberAnimationBinding,
|
||||||
|
NumericSpec,
|
||||||
|
PrimitiveAnimationChannelKind,
|
||||||
|
ScalarAnimationChannel,
|
||||||
|
ScalarAnimationKey,
|
||||||
|
ScalarSegmentType,
|
||||||
|
TangentMode,
|
||||||
|
Vector2AnimationBinding,
|
||||||
|
VectorValue,
|
||||||
|
} from "@/model/decorations/animations";
|
||||||
|
|
||||||
export const ANIMATION_PROPERTY_GROUPS = {
|
export {
|
||||||
"transform.scale": ["transform.scaleX", "transform.scaleY"],
|
ANIMATION_PROPERTY_GROUPS,
|
||||||
} as const satisfies Record<string, ReadonlyArray<AnimationPropertyPath>>;
|
ANIMATION_PROPERTY_PATHS,
|
||||||
|
} from "@/model/decorations/animations";
|
||||||
export type AnimationPropertyGroup = keyof typeof ANIMATION_PROPERTY_GROUPS;
|
|
||||||
|
|
||||||
export type VectorValue = { x: number; y: number };
|
|
||||||
export type DiscreteValue = boolean | string;
|
|
||||||
export type AnimationValue = number | string | boolean | VectorValue;
|
|
||||||
export interface AnimationPropertyValueMap {
|
|
||||||
"transform.positionX": number;
|
|
||||||
"transform.positionY": number;
|
|
||||||
"transform.scaleX": number;
|
|
||||||
"transform.scaleY": number;
|
|
||||||
"transform.rotate": number;
|
|
||||||
opacity: number;
|
|
||||||
volume: number;
|
|
||||||
color: string;
|
|
||||||
"background.color": string;
|
|
||||||
"background.paddingX": number;
|
|
||||||
"background.paddingY": number;
|
|
||||||
"background.offsetX": number;
|
|
||||||
"background.offsetY": number;
|
|
||||||
"background.cornerRadius": number;
|
|
||||||
}
|
|
||||||
export type DynamicAnimationPathValue = number | string | boolean;
|
|
||||||
|
|
||||||
export interface NumericSpec {
|
|
||||||
min?: number;
|
|
||||||
max?: number;
|
|
||||||
step?: number;
|
|
||||||
}
|
|
||||||
export type AnimationValueForPath<TPath extends AnimationPath> =
|
|
||||||
TPath extends AnimationPropertyPath
|
|
||||||
? AnimationPropertyValueMap[TPath]
|
|
||||||
: TPath extends GraphicParamPath | EffectParamPath
|
|
||||||
? DynamicAnimationPathValue
|
|
||||||
: never;
|
|
||||||
export type AnimationNumericPropertyPath = {
|
|
||||||
[K in AnimationPropertyPath]: AnimationValueForPath<K> extends number ? K : never;
|
|
||||||
}[AnimationPropertyPath];
|
|
||||||
export type AnimationColorPropertyPath = {
|
|
||||||
[K in AnimationPropertyPath]: AnimationValueForPath<K> extends string ? K : never;
|
|
||||||
}[AnimationPropertyPath];
|
|
||||||
|
|
||||||
export type ContinuousKeyframeInterpolation = "linear" | "hold" | "bezier";
|
|
||||||
export type DiscreteKeyframeInterpolation = "hold";
|
|
||||||
export type AnimationInterpolation =
|
|
||||||
| ContinuousKeyframeInterpolation
|
|
||||||
| DiscreteKeyframeInterpolation;
|
|
||||||
|
|
||||||
export type PrimitiveAnimationChannelKind = "scalar" | "discrete";
|
|
||||||
export type AnimationBindingKind = "number" | "vector2" | "color" | "discrete";
|
|
||||||
export type ScalarSegmentType = "step" | "linear" | "bezier";
|
|
||||||
export type TangentMode = "auto" | "aligned" | "broken" | "flat";
|
|
||||||
export type ChannelExtrapolationMode = "hold" | "linear";
|
|
||||||
|
|
||||||
export interface CurveHandle {
|
|
||||||
dt: number;
|
|
||||||
dv: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseAnimationKeyframe<TValue extends number | DiscreteValue> {
|
|
||||||
id: string;
|
|
||||||
time: number; // relative to element start time
|
|
||||||
value: TValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScalarAnimationKey extends BaseAnimationKeyframe<number> {
|
|
||||||
leftHandle?: CurveHandle;
|
|
||||||
rightHandle?: CurveHandle;
|
|
||||||
segmentToNext: ScalarSegmentType;
|
|
||||||
tangentMode: TangentMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiscreteAnimationKey
|
|
||||||
extends BaseAnimationKeyframe<DiscreteValue> {}
|
|
||||||
|
|
||||||
export type AnimationKeyframe = ScalarAnimationKey | DiscreteAnimationKey;
|
|
||||||
|
|
||||||
export interface ScalarAnimationChannel {
|
|
||||||
kind: "scalar";
|
|
||||||
keys: ScalarAnimationKey[];
|
|
||||||
extrapolation?: {
|
|
||||||
before: ChannelExtrapolationMode;
|
|
||||||
after: ChannelExtrapolationMode;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiscreteAnimationChannel {
|
|
||||||
kind: "discrete";
|
|
||||||
keys: DiscreteAnimationKey[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnimationChannel =
|
|
||||||
| ScalarAnimationChannel
|
|
||||||
| DiscreteAnimationChannel;
|
|
||||||
|
|
||||||
export type ElementAnimationChannelMap = Record<
|
|
||||||
string,
|
|
||||||
AnimationChannel | undefined
|
|
||||||
>;
|
|
||||||
|
|
||||||
export interface AnimationBindingComponent<TKey extends string = string> {
|
|
||||||
key: TKey;
|
|
||||||
channelId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseAnimationBinding<
|
|
||||||
TKind extends AnimationBindingKind,
|
|
||||||
TComponentKey extends string,
|
|
||||||
> {
|
|
||||||
path: AnimationPath;
|
|
||||||
kind: TKind;
|
|
||||||
components: AnimationBindingComponent<TComponentKey>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NumberAnimationBinding
|
|
||||||
extends BaseAnimationBinding<"number", "value"> {}
|
|
||||||
|
|
||||||
export interface Vector2AnimationBinding
|
|
||||||
extends BaseAnimationBinding<"vector2", "x" | "y"> {}
|
|
||||||
|
|
||||||
export interface ColorAnimationBinding
|
|
||||||
extends BaseAnimationBinding<"color", "r" | "g" | "b" | "a"> {
|
|
||||||
colorSpace: "srgb-linear";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiscreteAnimationBinding
|
|
||||||
extends BaseAnimationBinding<"discrete", "value"> {}
|
|
||||||
|
|
||||||
export type AnimationBindingInstance =
|
|
||||||
| NumberAnimationBinding
|
|
||||||
| Vector2AnimationBinding
|
|
||||||
| ColorAnimationBinding
|
|
||||||
| DiscreteAnimationBinding;
|
|
||||||
|
|
||||||
export interface AnimationBindingByKind {
|
|
||||||
number: NumberAnimationBinding;
|
|
||||||
vector2: Vector2AnimationBinding;
|
|
||||||
color: ColorAnimationBinding;
|
|
||||||
discrete: DiscreteAnimationBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AnimationBindingOfKind<TKind extends AnimationBindingKind> =
|
|
||||||
AnimationBindingByKind[TKind];
|
|
||||||
|
|
||||||
export type ElementAnimationBindingMap = Record<
|
|
||||||
string,
|
|
||||||
AnimationBindingInstance | undefined
|
|
||||||
>;
|
|
||||||
|
|
||||||
export interface ElementAnimations {
|
|
||||||
bindings: ElementAnimationBindingMap;
|
|
||||||
channels: ElementAnimationChannelMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type NormalizedCubicBezier = [number, number, number, number];
|
|
||||||
|
|
||||||
export interface ScalarGraphChannelTarget {
|
export interface ScalarGraphChannelTarget {
|
||||||
propertyPath: AnimationPath;
|
propertyPath: AnimationPath;
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import type { EditorCore } from "@/core";
|
import type { EditorCore } from "@/core";
|
||||||
import type {
|
import type { AnimationInterpolation, AnimationPath, AnimationValue } from "@/model/decorations/animations";
|
||||||
AnimationInterpolation,
|
import type { ScalarCurveKeyframePatch, SelectedKeyframeRef } from "@/animation/types";
|
||||||
AnimationPath,
|
|
||||||
AnimationValue,
|
|
||||||
ScalarCurveKeyframePatch,
|
|
||||||
SelectedKeyframeRef,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { Command } from "@/commands/base-command";
|
import type { Command } from "@/commands/base-command";
|
||||||
import type { CreateTimelineElement, ElementRef, TrackType } from "@/model";
|
import type { CreateTimelineElement, ElementRef, TrackType } from "@/model";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { EditorCore } from "@/core";
|
import { EditorCore } from "@/core";
|
||||||
import { isVisualElement, updateElementInSceneTracks } from "@/timeline";
|
import { isVisualElement, updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { SceneTracks, VisualElement } from "@/model";
|
import type { SceneTracks, VisualElement } from "@/model";
|
||||||
|
|
||||||
function updateEffectParamsOnElement({
|
function updateEffectParamsOnElement({
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { updateElementInSceneTracks } from "@/timeline";
|
import { updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { AnimationPath, AnimationValue } from "@/animation/types";
|
import type { AnimationPath, AnimationValue } from "@/model/decorations/animations";
|
||||||
import type { SceneTracks, TimelineElement } from "@/model";
|
import type { SceneTracks, TimelineElement } from "@/model";
|
||||||
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { EditorCore } from "@/core";
|
|||||||
import { retimeElementKeyframe } from "@/animation";
|
import { retimeElementKeyframe } from "@/animation";
|
||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { updateElementInSceneTracks } from "@/timeline";
|
import { updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { AnimationPath } from "@/animation/types";
|
import type { AnimationPath } from "@/model/decorations/animations";
|
||||||
import type { SceneTracks } from "@/model";
|
import type { SceneTracks } from "@/model";
|
||||||
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ import {
|
|||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { updateElementInSceneTracks } from "@/timeline";
|
import { updateElementInSceneTracks } from "@/timeline";
|
||||||
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
||||||
import type {
|
import type { AnimationPath } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
import type { ScalarCurveKeyframePatch } from "@/animation/types";
|
||||||
ScalarCurveKeyframePatch,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { SceneTracks } from "@/model";
|
import type { SceneTracks } from "@/model";
|
||||||
|
|
||||||
export class UpdateScalarKeyframeCurveCommand extends Command {
|
export class UpdateScalarKeyframeCurveCommand extends Command {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
import { updateElementInSceneTracks } from "@/timeline";
|
import { updateElementInSceneTracks } from "@/timeline";
|
||||||
import { isVisualElement } from "@/timeline/element-utils";
|
import { isVisualElement } from "@/timeline/element-utils";
|
||||||
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
||||||
import type { AnimationInterpolation } from "@/animation/types";
|
import type { AnimationInterpolation } from "@/model/decorations/animations";
|
||||||
import type { SceneTracks } from "@/model";
|
import type { SceneTracks } from "@/model";
|
||||||
|
|
||||||
export class UpsertEffectParamKeyframeCommand extends Command {
|
export class UpsertEffectParamKeyframeCommand extends Command {
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import { upsertPathKeyframe } from "@/animation";
|
|||||||
import { updateElementInSceneTracks } from "@/timeline";
|
import { updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { SceneTracks } from "@/model";
|
import type { SceneTracks } from "@/model";
|
||||||
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
import { resolveAnimationTarget } from "@/timeline/animation-targets";
|
||||||
import type {
|
import type { AnimationInterpolation, AnimationPath, AnimationValue } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationValue,
|
|
||||||
} from "@/animation/types";
|
|
||||||
|
|
||||||
export class UpsertKeyframeCommand extends Command {
|
export class UpsertKeyframeCommand extends Command {
|
||||||
private savedState: SceneTracks | null = null;
|
private savedState: SceneTracks | null = null;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
getCustomMaskClosedStateAfterPointRemoval,
|
getCustomMaskClosedStateAfterPointRemoval,
|
||||||
removeCustomMaskPoints,
|
removeCustomMaskPoints,
|
||||||
} from "@/masks/custom-path";
|
} from "@/masks/custom-path";
|
||||||
import type { CustomMask } from "@/masks/types";
|
import type { CustomMask } from "@/model/decorations/mask";
|
||||||
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { MaskableElement, SceneTracks } from "@/model";
|
import type { MaskableElement, SceneTracks } from "@/model";
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { EditorCore } from "@/core";
|
|||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { insertPointOnCustomMaskSegment } from "@/masks/definitions/custom";
|
import { insertPointOnCustomMaskSegment } from "@/masks/definitions/custom";
|
||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type { CustomMask } from "@/masks/types";
|
import type { CustomMask } from "@/model/decorations/mask";
|
||||||
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { MaskableElement, SceneTracks } from "@/model";
|
import type { MaskableElement, SceneTracks } from "@/model";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EditorCore } from "@/core";
|
import { EditorCore } from "@/core";
|
||||||
import { Command, type CommandResult } from "@/commands/base-command";
|
import { Command, type CommandResult } from "@/commands/base-command";
|
||||||
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
import { isMaskableElement, updateElementInSceneTracks } from "@/timeline";
|
||||||
import type { Mask } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
import type { MaskableElement, SceneTracks } from "@/model";
|
import type { MaskableElement, SceneTracks } from "@/model";
|
||||||
|
|
||||||
export function toggleMaskInvertedOnElement({
|
export function toggleMaskInvertedOnElement({
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import type { ParamDefinition, NumberParamDefinition } from "@/params";
|
import type { NumberParamDefinition, ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import {
|
import {
|
||||||
formatNumberForDisplay,
|
formatNumberForDisplay,
|
||||||
getFractionDigitsForStep,
|
getFractionDigitsForStep,
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
getKeyframeAtTime,
|
getKeyframeAtTime,
|
||||||
hasKeyframesForPath,
|
hasKeyframesForPath,
|
||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import type { AnimationPropertyPath, ElementAnimations } from "@/animation/types";
|
import type { AnimationPropertyPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
import type { TimelineElement } from "@/model";
|
import type { TimelineElement } from "@/model";
|
||||||
import { upsertElementKeyframe } from "@/timeline/animation-properties";
|
import { upsertElementKeyframe } from "@/timeline/animation-properties";
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
getKeyframeAtTime,
|
getKeyframeAtTime,
|
||||||
hasKeyframesForPath,
|
hasKeyframesForPath,
|
||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import type { AnimationPropertyPath, ElementAnimations } from "@/animation/types";
|
import type { AnimationPropertyPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
import type { TimelineElement } from "@/model";
|
import type { TimelineElement } from "@/model";
|
||||||
import { upsertElementKeyframe } from "@/timeline/animation-properties";
|
import { upsertElementKeyframe } from "@/timeline/animation-properties";
|
||||||
import { snapToStep } from "@/utils/math";
|
import { snapToStep } from "@/utils/math";
|
||||||
|
|||||||
+2
-4
@@ -7,15 +7,13 @@ import {
|
|||||||
hasKeyframesForPath,
|
hasKeyframesForPath,
|
||||||
upsertPathKeyframe,
|
upsertPathKeyframe,
|
||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import type {
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
ElementAnimations,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
coerceAnimationParamValue,
|
coerceAnimationParamValue,
|
||||||
getAnimationParamDefaultInterpolation,
|
getAnimationParamDefaultInterpolation,
|
||||||
getAnimationParamValueKind,
|
getAnimationParamValueKind,
|
||||||
} from "@/animation/animated-params";
|
} from "@/animation/animated-params";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type { TimelineElement } from "@/model";
|
import type { TimelineElement } from "@/model";
|
||||||
|
|
||||||
export interface KeyframedParamPropertyResult {
|
export interface KeyframedParamPropertyResult {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { EditorCore } from "@/core";
|
import type { EditorCore } from "@/core";
|
||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { RetimeConfig, SceneTracks, TimelineElement, TimelineTrack, TrackType } from "@/model";
|
import type { RetimeConfig, SceneTracks, TimelineElement, TimelineTrack, TrackType } from "@/model";
|
||||||
import { calculateTotalDuration } from "@/timeline";
|
import { calculateTotalDuration } from "@/timeline";
|
||||||
import { TimelineDragSource } from "@/timeline/drag-source";
|
import { TimelineDragSource } from "@/timeline/drag-source";
|
||||||
@@ -9,13 +9,8 @@ import {
|
|||||||
canElementBeHidden,
|
canElementBeHidden,
|
||||||
canElementHaveAudio,
|
canElementHaveAudio,
|
||||||
} from "@/timeline/element-utils";
|
} from "@/timeline/element-utils";
|
||||||
import type {
|
import type { AnimationInterpolation, AnimationPath, AnimationValue, AnimationValueForPath } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
import type { ScalarCurveKeyframePatch } from "@/animation/types";
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationValue,
|
|
||||||
AnimationValueForPath,
|
|
||||||
ScalarCurveKeyframePatch,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
getElementLocalTime,
|
getElementLocalTime,
|
||||||
resolveAnimationPathValueAtTime,
|
resolveAnimationPathValueAtTime,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { EffectElement, VisualElement } from "@/model";
|
import type { EffectElement, VisualElement } from "@/model";
|
||||||
import { effectsRegistry } from "@/effects";
|
import { effectsRegistry } from "@/effects";
|
||||||
import { useEditor } from "@/editor/use-editor";
|
import { useEditor } from "@/editor/use-editor";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { EffectDefinition, EffectPass } from "@/effects/types";
|
import type { EffectPass } from "@/model/decorations/effect";
|
||||||
|
import type { EffectDefinition } from "@/effects/types";
|
||||||
|
|
||||||
export const GAUSSIAN_BLUR_SHADER = "gaussian-blur";
|
export const GAUSSIAN_BLUR_SHADER = "gaussian-blur";
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { generateUUID } from "@/utils/id";
|
import { generateUUID } from "@/utils/id";
|
||||||
import { buildDefaultParamValues } from "@/params/registry";
|
import { buildDefaultParamValues } from "@/params/registry";
|
||||||
import { effectsRegistry } from "./registry";
|
import { effectsRegistry } from "./registry";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { Effect, EffectDefinition, EffectPass } from "@/effects/types";
|
import type { Effect, EffectPass } from "@/model/decorations/effect";
|
||||||
|
import type { EffectDefinition } from "@/effects/types";
|
||||||
import { VISUAL_ELEMENT_TYPES } from "@/model";
|
import { VISUAL_ELEMENT_TYPES } from "@/model";
|
||||||
|
|
||||||
export { effectsRegistry } from "./registry";
|
export { effectsRegistry } from "./registry";
|
||||||
|
|||||||
@@ -1,27 +1,12 @@
|
|||||||
import type { ParamDefinition, ParamValues } from "@/params";
|
import type { ParamDefinition, ParamValues } from "@/model/decorations/param-values";
|
||||||
|
import type { EffectPass, EffectPassTemplate } from "@/model/decorations/effect";
|
||||||
|
|
||||||
export interface Effect {
|
export type {
|
||||||
id: string;
|
Effect,
|
||||||
type: string;
|
EffectPass,
|
||||||
params: ParamValues;
|
EffectPassTemplate,
|
||||||
enabled: boolean;
|
EffectUniformValue,
|
||||||
}
|
} from "@/model/decorations/effect";
|
||||||
|
|
||||||
export type EffectUniformValue = number | number[];
|
|
||||||
|
|
||||||
export interface EffectPass {
|
|
||||||
shader: string;
|
|
||||||
uniforms: Record<string, EffectUniformValue>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EffectPassTemplate {
|
|
||||||
shader: string;
|
|
||||||
uniforms(params: {
|
|
||||||
effectParams: ParamValues;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
}): Record<string, EffectUniformValue>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EffectRendererConfig {
|
export interface EffectRendererConfig {
|
||||||
passes: EffectPassTemplate[];
|
passes: EffectPassTemplate[];
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
useKeyframedParamProperty,
|
useKeyframedParamProperty,
|
||||||
type KeyframedParamPropertyResult,
|
type KeyframedParamPropertyResult,
|
||||||
} from "@/components/editor/panels/properties/hooks/use-keyframed-param-property";
|
} from "@/components/editor/panels/properties/hooks/use-keyframed-param-property";
|
||||||
import type { ParamDefinition, ParamValues } from "@/params";
|
import type { ParamDefinition, ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { GraphicElement } from "@/model";
|
import type { GraphicElement } from "@/model";
|
||||||
import {
|
import {
|
||||||
graphicsRegistry,
|
graphicsRegistry,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { applyAlignedStroke } from "../stroke";
|
import { applyAlignedStroke } from "../stroke";
|
||||||
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
||||||
import type { GraphicDefinition } from "../types";
|
import type { GraphicDefinition } from "../types";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { applyAlignedStroke } from "../stroke";
|
import { applyAlignedStroke } from "../stroke";
|
||||||
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
||||||
import type { GraphicDefinition } from "../types";
|
import type { GraphicDefinition } from "../types";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { applyAlignedStroke } from "../stroke";
|
import { applyAlignedStroke } from "../stroke";
|
||||||
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
||||||
import type { GraphicDefinition } from "../types";
|
import type { GraphicDefinition } from "../types";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
|
|
||||||
export type GraphicStrokeAlign = "inside" | "center" | "outside";
|
export type GraphicStrokeAlign = "inside" | "center" | "outside";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { applyAlignedStroke } from "../stroke";
|
import { applyAlignedStroke } from "../stroke";
|
||||||
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
import { STROKE_ALIGN_PARAM, type GraphicStrokeAlign } from "./shared";
|
||||||
import type { GraphicDefinition } from "../types";
|
import type { GraphicDefinition } from "../types";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { resolveGraphicParamsAtTime } from "@/animation";
|
import { resolveGraphicParamsAtTime } from "@/animation";
|
||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import { buildDefaultParamValues } from "@/params/registry";
|
import { buildDefaultParamValues } from "@/params/registry";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import { graphicsRegistry } from "./registry";
|
import { graphicsRegistry } from "./registry";
|
||||||
import {
|
import {
|
||||||
registerDefaultGraphics,
|
registerDefaultGraphics,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition, ParamValues } from "@/params";
|
import type { ParamDefinition, ParamValues } from "@/model/decorations/param-values";
|
||||||
|
|
||||||
export const DEFAULT_GRAPHIC_SOURCE_SIZE = 512;
|
export const DEFAULT_GRAPHIC_SOURCE_SIZE = 512;
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,7 @@ import { textMaskDefinition } from "@/masks/definitions/text";
|
|||||||
import { getMaskSnapGeometry } from "@/masks/geometry";
|
import { getMaskSnapGeometry } from "@/masks/geometry";
|
||||||
import { snapMaskInteraction } from "@/masks/snap";
|
import { snapMaskInteraction } from "@/masks/snap";
|
||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type {
|
import type { CustomMaskParams, RectangleMaskParams, SplitMaskParams, TextMaskParams } from "@/model/decorations/mask";
|
||||||
CustomMaskParams,
|
|
||||||
RectangleMaskParams,
|
|
||||||
SplitMaskParams,
|
|
||||||
TextMaskParams,
|
|
||||||
} from "@/masks/types";
|
|
||||||
|
|
||||||
const bounds: ElementBounds = {
|
const bounds: ElementBounds = {
|
||||||
cx: 200,
|
cx: 200,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import type { MaskableElement } from "@/model";
|
import type { MaskableElement } from "@/model";
|
||||||
import type { Mask, MaskType, TextMask } from "@/masks/types";
|
import type { Mask, MaskType, TextMask } from "@/model/decorations/mask";
|
||||||
import type { NumberParamDefinition, SelectParamDefinition } from "@/params";
|
import type { NumberParamDefinition, SelectParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { masksRegistry, buildDefaultMaskInstance } from "@/masks";
|
import { masksRegistry, buildDefaultMaskInstance } from "@/masks";
|
||||||
import { useEditor } from "@/editor/use-editor";
|
import { useEditor } from "@/editor/use-editor";
|
||||||
import { useElementPreview } from "@/timeline/hooks/use-element-preview";
|
import { useElementPreview } from "@/timeline/hooks/use-element-preview";
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
|
import type { CustomMaskPathPoint } from "@/model/decorations/mask";
|
||||||
export interface CustomMaskPathPoint {
|
export type { CustomMaskPathPoint } from "@/model/decorations/mask";
|
||||||
id: string;
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
inX: number;
|
|
||||||
inY: number;
|
|
||||||
outX: number;
|
|
||||||
outY: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CustomMaskHandlePart = "anchor" | "in" | "out";
|
export type CustomMaskHandlePart = "anchor" | "in" | "out";
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,9 @@ import {
|
|||||||
MIN_MASK_DIMENSION,
|
MIN_MASK_DIMENSION,
|
||||||
} from "@/masks/dimensions";
|
} from "@/masks/dimensions";
|
||||||
import { computeFeatherUpdate } from "../param-update";
|
import { computeFeatherUpdate } from "../param-update";
|
||||||
import type {
|
import type { BaseMaskParams, RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
BaseMaskParams,
|
import type { MaskDefaultContext, MaskFeatures, MaskInteractionDefinition, MaskParamUpdateArgs } from "@/masks/types";
|
||||||
MaskDefaultContext,
|
import type { NumberParamDefinition, ParamDefinition } from "@/model/decorations/param-values";
|
||||||
MaskFeatures,
|
|
||||||
MaskInteractionDefinition,
|
|
||||||
MaskParamUpdateArgs,
|
|
||||||
RectangleMaskParams,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import type { NumberParamDefinition, ParamDefinition } from "@/params";
|
|
||||||
import {
|
import {
|
||||||
getBoxMaskHandlePositions,
|
getBoxMaskHandlePositions,
|
||||||
getBoxMaskOverlays,
|
getBoxMaskOverlays,
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import type {
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
MaskDefaultContext,
|
import type { MaskDefaultContext, MaskDefinition } from "@/masks/types";
|
||||||
MaskDefinition,
|
|
||||||
RectangleMaskParams,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
import { generateUUID } from "@/utils/id";
|
import { generateUUID } from "@/utils/id";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import { PEN_CURSOR } from "@/preview/components/cursors";
|
import { PEN_CURSOR } from "@/preview/components/cursors";
|
||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type {
|
import type { CustomMask, CustomMaskParams } from "@/model/decorations/mask";
|
||||||
CustomMask,
|
import type { MaskDefinition, MaskHandlePosition, MaskOverlay, MaskParamUpdateArgs } from "@/masks/types";
|
||||||
CustomMaskParams,
|
|
||||||
MaskDefinition,
|
|
||||||
MaskHandlePosition,
|
|
||||||
MaskOverlay,
|
|
||||||
MaskParamUpdateArgs,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import {
|
import {
|
||||||
buildCustomMaskPath2D,
|
buildCustomMaskPath2D,
|
||||||
buildCustomMaskSvgPath,
|
buildCustomMaskSvgPath,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { MaskDefinition, RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { MaskDefinition, RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { MaskDefinition, RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { BaseMaskParams, MaskDefinition } from "@/masks/types";
|
import type { BaseMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import { masksRegistry, type MaskIconProps } from "../registry";
|
import { masksRegistry, type MaskIconProps } from "../registry";
|
||||||
import { cinematicBarsMaskDefinition } from "./cinematic-bars";
|
import { cinematicBarsMaskDefinition } from "./cinematic-bars";
|
||||||
import { customMaskDefinition } from "./custom";
|
import { customMaskDefinition } from "./custom";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { MaskDefinition, RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
import { computeFeatherUpdate } from "../param-update";
|
import { computeFeatherUpdate } from "../param-update";
|
||||||
import type {
|
import type { SplitMaskParams } from "@/model/decorations/mask";
|
||||||
MaskDefinition,
|
import type { MaskDefinition, MaskParamUpdateArgs } from "@/masks/types";
|
||||||
MaskParamUpdateArgs,
|
|
||||||
SplitMaskParams,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import { halfPlaneSign, lineEdgeIntersection } from "../utils";
|
import { halfPlaneSign, lineEdgeIntersection } from "../utils";
|
||||||
import {
|
import {
|
||||||
getLineMaskHandlePositions,
|
getLineMaskHandlePositions,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { MaskDefinition, RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefinition } from "@/masks/types";
|
||||||
import {
|
import {
|
||||||
BOX_LIKE_MASK_PARAMS,
|
BOX_LIKE_MASK_PARAMS,
|
||||||
buildBoxMaskInteraction,
|
buildBoxMaskInteraction,
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type {
|
import type { TextMask, TextMaskParams } from "@/model/decorations/mask";
|
||||||
MaskDefinition,
|
import type { MaskDefinition, MaskParamUpdateArgs } from "@/masks/types";
|
||||||
MaskParamUpdateArgs,
|
|
||||||
TextMask,
|
|
||||||
TextMaskParams,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import { DEFAULTS } from "@/timeline/defaults";
|
import { DEFAULTS } from "@/timeline/defaults";
|
||||||
import { MIN_FONT_SIZE, MAX_FONT_SIZE } from "@/text/typography";
|
import { MIN_FONT_SIZE, MAX_FONT_SIZE } from "@/text/typography";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type { PreviewSnapLine } from "@/preview/preview-snap";
|
import type { PreviewSnapLine } from "@/preview/preview-snap";
|
||||||
import { MIN_MASK_DIMENSION } from "@/masks/dimensions";
|
import { MIN_MASK_DIMENSION } from "@/masks/dimensions";
|
||||||
import type { RectangleMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
|
|
||||||
type CenterMaskParams = {
|
type CenterMaskParams = {
|
||||||
centerX: number;
|
centerX: number;
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
import { FEATHER_HANDLE_SCALE } from "@/masks/feather";
|
import { FEATHER_HANDLE_SCALE } from "@/masks/feather";
|
||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type {
|
import type { RectangleMaskParams } from "@/model/decorations/mask";
|
||||||
MaskFeatures,
|
import type { MaskFeatures, MaskHandlePosition, MaskLineOverlay, MaskOverlay, MaskRectOverlay, MaskShapeOverlay } from "@/masks/types";
|
||||||
MaskHandlePosition,
|
|
||||||
MaskLineOverlay,
|
|
||||||
MaskOverlay,
|
|
||||||
MaskRectOverlay,
|
|
||||||
RectangleMaskParams,
|
|
||||||
MaskShapeOverlay,
|
|
||||||
} from "@/masks/types";
|
|
||||||
|
|
||||||
const LINE_HANDLE_OFFSET_SCREEN_PX = 20;
|
const LINE_HANDLE_OFFSET_SCREEN_PX = 20;
|
||||||
const BOX_HANDLE_OFFSET_SCREEN_PX = 20;
|
const BOX_HANDLE_OFFSET_SCREEN_PX = 20;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Mask, MaskDefaultContext, MaskType } from "@/masks/types";
|
import type { Mask, MaskType } from "@/model/decorations/mask";
|
||||||
|
import type { MaskDefaultContext } from "@/masks/types";
|
||||||
import { masksRegistry } from "./registry";
|
import { masksRegistry } from "./registry";
|
||||||
import { generateUUID } from "@/utils/id";
|
import { generateUUID } from "@/utils/id";
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
import { MAX_FEATHER } from "@/masks/feather";
|
import { MAX_FEATHER } from "@/masks/feather";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type {
|
import type { BaseMaskParams, MaskType } from "@/model/decorations/mask";
|
||||||
BaseMaskParams,
|
import type { MaskDefaultContext, MaskDefinition, MaskInteractionResult, MaskSnapArgs, MaskSnapResult } from "@/masks/types";
|
||||||
MaskDefaultContext,
|
|
||||||
MaskDefinition,
|
|
||||||
MaskInteractionResult,
|
|
||||||
MaskSnapArgs,
|
|
||||||
MaskSnapResult,
|
|
||||||
MaskType,
|
|
||||||
} from "@/masks/types";
|
|
||||||
import type { HugeiconsIconProps } from "@hugeicons/react";
|
import type { HugeiconsIconProps } from "@hugeicons/react";
|
||||||
import { DefinitionRegistry } from "@/params/registry";
|
import { DefinitionRegistry } from "@/params/registry";
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
type ScaleEdgePreference,
|
type ScaleEdgePreference,
|
||||||
type PreviewSnapLine,
|
type PreviewSnapLine,
|
||||||
} from "@/preview/preview-snap";
|
} from "@/preview/preview-snap";
|
||||||
import type { RectangleMaskParams, SplitMaskParams } from "@/masks/types";
|
import type { RectangleMaskParams, SplitMaskParams } from "@/model/decorations/mask";
|
||||||
import {
|
import {
|
||||||
isRectangleMaskParams,
|
isRectangleMaskParams,
|
||||||
getMaskSnapGeometry,
|
getMaskSnapGeometry,
|
||||||
|
|||||||
+25
-126
@@ -1,135 +1,34 @@
|
|||||||
import type { ElementBounds } from "@/preview/element-bounds";
|
import type { ElementBounds } from "@/preview/element-bounds";
|
||||||
import type { PreviewSnapLine } from "@/preview/preview-snap";
|
import type { PreviewSnapLine } from "@/preview/preview-snap";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type { CustomMaskPathPoint } from "@/masks/custom-path";
|
|
||||||
import type {
|
import type {
|
||||||
|
BaseMaskParams,
|
||||||
|
Mask,
|
||||||
|
MaskType,
|
||||||
|
} from "@/model/decorations/mask";
|
||||||
|
|
||||||
|
export type {
|
||||||
|
BaseMaskParams,
|
||||||
|
CinematicBarsMask,
|
||||||
|
CustomMask,
|
||||||
|
CustomMaskParams,
|
||||||
|
CustomMaskPathPoint,
|
||||||
|
DiamondMask,
|
||||||
|
EllipseMask,
|
||||||
|
HeartMask,
|
||||||
|
Mask,
|
||||||
|
MaskType,
|
||||||
|
RectangleMask,
|
||||||
|
RectangleMaskParams,
|
||||||
|
SplitMask,
|
||||||
|
SplitMaskParams,
|
||||||
|
StarMask,
|
||||||
TextDecoration,
|
TextDecoration,
|
||||||
TextFontStyle,
|
TextFontStyle,
|
||||||
TextFontWeight,
|
TextFontWeight,
|
||||||
} from "@/text/primitives";
|
TextMask,
|
||||||
|
TextMaskParams,
|
||||||
export type MaskType =
|
} from "@/model/decorations/mask";
|
||||||
| "split"
|
|
||||||
| "cinematic-bars"
|
|
||||||
| "rectangle"
|
|
||||||
| "ellipse"
|
|
||||||
| "heart"
|
|
||||||
| "diamond"
|
|
||||||
| "star"
|
|
||||||
| "text"
|
|
||||||
| "custom";
|
|
||||||
|
|
||||||
export interface BaseMaskParams {
|
|
||||||
feather: number;
|
|
||||||
inverted: boolean;
|
|
||||||
strokeColor: string;
|
|
||||||
strokeWidth: number;
|
|
||||||
strokeAlign: "inside" | "center" | "outside";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SplitMaskParams extends BaseMaskParams {
|
|
||||||
centerX: number;
|
|
||||||
centerY: number;
|
|
||||||
rotation: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RectangleMaskParams extends BaseMaskParams {
|
|
||||||
centerX: number;
|
|
||||||
centerY: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
rotation: number;
|
|
||||||
scale: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TextMaskParams extends BaseMaskParams {
|
|
||||||
content: string;
|
|
||||||
fontSize: number;
|
|
||||||
fontFamily: string;
|
|
||||||
fontWeight: TextFontWeight;
|
|
||||||
fontStyle: TextFontStyle;
|
|
||||||
textDecoration: TextDecoration;
|
|
||||||
letterSpacing: number;
|
|
||||||
lineHeight: number;
|
|
||||||
centerX: number;
|
|
||||||
centerY: number;
|
|
||||||
rotation: number;
|
|
||||||
scale: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CustomMaskParams extends BaseMaskParams {
|
|
||||||
path: CustomMaskPathPoint[];
|
|
||||||
closed: boolean;
|
|
||||||
centerX: number;
|
|
||||||
centerY: number;
|
|
||||||
rotation: number;
|
|
||||||
scale: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SplitMask {
|
|
||||||
id: string;
|
|
||||||
type: "split";
|
|
||||||
params: SplitMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CinematicBarsMask {
|
|
||||||
id: string;
|
|
||||||
type: "cinematic-bars";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RectangleMask {
|
|
||||||
id: string;
|
|
||||||
type: "rectangle";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EllipseMask {
|
|
||||||
id: string;
|
|
||||||
type: "ellipse";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HeartMask {
|
|
||||||
id: string;
|
|
||||||
type: "heart";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiamondMask {
|
|
||||||
id: string;
|
|
||||||
type: "diamond";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StarMask {
|
|
||||||
id: string;
|
|
||||||
type: "star";
|
|
||||||
params: RectangleMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TextMask {
|
|
||||||
id: string;
|
|
||||||
type: "text";
|
|
||||||
params: TextMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CustomMask {
|
|
||||||
id: string;
|
|
||||||
type: "custom";
|
|
||||||
params: CustomMaskParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Mask =
|
|
||||||
| SplitMask
|
|
||||||
| CinematicBarsMask
|
|
||||||
| RectangleMask
|
|
||||||
| EllipseMask
|
|
||||||
| HeartMask
|
|
||||||
| DiamondMask
|
|
||||||
| StarMask
|
|
||||||
| TextMask
|
|
||||||
| CustomMask;
|
|
||||||
|
|
||||||
export interface MaskRenderer {
|
export interface MaskRenderer {
|
||||||
buildPath?: (params: {
|
buildPath?: (params: {
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import {
|
|||||||
type PreviewSnapLine,
|
type PreviewSnapLine,
|
||||||
} from "@/preview/preview-snap";
|
} from "@/preview/preview-snap";
|
||||||
import type { SelectedMaskPointSelection } from "@/selection/editor-selection";
|
import type { SelectedMaskPointSelection } from "@/selection/editor-selection";
|
||||||
import type { Mask, MaskInteractionResult } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
|
import type { MaskInteractionResult } from "@/masks/types";
|
||||||
import type { MaskableElement } from "@/model";
|
import type { MaskableElement } from "@/model";
|
||||||
import { registerCanceller } from "@/editor/cancel-interaction";
|
import { registerCanceller } from "@/editor/cancel-interaction";
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
export const ANIMATION_PROPERTY_PATHS = [
|
||||||
|
"transform.positionX",
|
||||||
|
"transform.positionY",
|
||||||
|
"transform.scaleX",
|
||||||
|
"transform.scaleY",
|
||||||
|
"transform.rotate",
|
||||||
|
"opacity",
|
||||||
|
"volume",
|
||||||
|
"color",
|
||||||
|
"background.color",
|
||||||
|
"background.paddingX",
|
||||||
|
"background.paddingY",
|
||||||
|
"background.offsetX",
|
||||||
|
"background.offsetY",
|
||||||
|
"background.cornerRadius",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type AnimationPropertyPath = (typeof ANIMATION_PROPERTY_PATHS)[number];
|
||||||
|
export type GraphicParamPath = `params.${string}`;
|
||||||
|
export type EffectParamPath = `effects.${string}.params.${string}`;
|
||||||
|
export type AnimationPath =
|
||||||
|
| AnimationPropertyPath
|
||||||
|
| GraphicParamPath
|
||||||
|
| EffectParamPath;
|
||||||
|
|
||||||
|
export const ANIMATION_PROPERTY_GROUPS = {
|
||||||
|
"transform.scale": ["transform.scaleX", "transform.scaleY"],
|
||||||
|
} as const satisfies Record<string, ReadonlyArray<AnimationPropertyPath>>;
|
||||||
|
|
||||||
|
export type AnimationPropertyGroup = keyof typeof ANIMATION_PROPERTY_GROUPS;
|
||||||
|
|
||||||
|
export type VectorValue = { x: number; y: number };
|
||||||
|
export type DiscreteValue = boolean | string;
|
||||||
|
export type AnimationValue = number | string | boolean | VectorValue;
|
||||||
|
export interface AnimationPropertyValueMap {
|
||||||
|
"transform.positionX": number;
|
||||||
|
"transform.positionY": number;
|
||||||
|
"transform.scaleX": number;
|
||||||
|
"transform.scaleY": number;
|
||||||
|
"transform.rotate": number;
|
||||||
|
opacity: number;
|
||||||
|
volume: number;
|
||||||
|
color: string;
|
||||||
|
"background.color": string;
|
||||||
|
"background.paddingX": number;
|
||||||
|
"background.paddingY": number;
|
||||||
|
"background.offsetX": number;
|
||||||
|
"background.offsetY": number;
|
||||||
|
"background.cornerRadius": number;
|
||||||
|
}
|
||||||
|
export type DynamicAnimationPathValue = number | string | boolean;
|
||||||
|
|
||||||
|
export interface NumericSpec {
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
|
}
|
||||||
|
export type AnimationValueForPath<TPath extends AnimationPath> =
|
||||||
|
TPath extends AnimationPropertyPath
|
||||||
|
? AnimationPropertyValueMap[TPath]
|
||||||
|
: TPath extends GraphicParamPath | EffectParamPath
|
||||||
|
? DynamicAnimationPathValue
|
||||||
|
: never;
|
||||||
|
export type AnimationNumericPropertyPath = {
|
||||||
|
[K in AnimationPropertyPath]: AnimationValueForPath<K> extends number ? K : never;
|
||||||
|
}[AnimationPropertyPath];
|
||||||
|
export type AnimationColorPropertyPath = {
|
||||||
|
[K in AnimationPropertyPath]: AnimationValueForPath<K> extends string ? K : never;
|
||||||
|
}[AnimationPropertyPath];
|
||||||
|
|
||||||
|
export type ContinuousKeyframeInterpolation = "linear" | "hold" | "bezier";
|
||||||
|
export type DiscreteKeyframeInterpolation = "hold";
|
||||||
|
export type AnimationInterpolation =
|
||||||
|
| ContinuousKeyframeInterpolation
|
||||||
|
| DiscreteKeyframeInterpolation;
|
||||||
|
|
||||||
|
export type PrimitiveAnimationChannelKind = "scalar" | "discrete";
|
||||||
|
export type AnimationBindingKind = "number" | "vector2" | "color" | "discrete";
|
||||||
|
export type ScalarSegmentType = "step" | "linear" | "bezier";
|
||||||
|
export type TangentMode = "auto" | "aligned" | "broken" | "flat";
|
||||||
|
export type ChannelExtrapolationMode = "hold" | "linear";
|
||||||
|
|
||||||
|
export interface CurveHandle {
|
||||||
|
dt: number;
|
||||||
|
dv: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseAnimationKeyframe<TValue extends number | DiscreteValue> {
|
||||||
|
id: string;
|
||||||
|
time: number; // relative to element start time
|
||||||
|
value: TValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScalarAnimationKey extends BaseAnimationKeyframe<number> {
|
||||||
|
leftHandle?: CurveHandle;
|
||||||
|
rightHandle?: CurveHandle;
|
||||||
|
segmentToNext: ScalarSegmentType;
|
||||||
|
tangentMode: TangentMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiscreteAnimationKey
|
||||||
|
extends BaseAnimationKeyframe<DiscreteValue> {}
|
||||||
|
|
||||||
|
export type AnimationKeyframe = ScalarAnimationKey | DiscreteAnimationKey;
|
||||||
|
|
||||||
|
export interface ScalarAnimationChannel {
|
||||||
|
kind: "scalar";
|
||||||
|
keys: ScalarAnimationKey[];
|
||||||
|
extrapolation?: {
|
||||||
|
before: ChannelExtrapolationMode;
|
||||||
|
after: ChannelExtrapolationMode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiscreteAnimationChannel {
|
||||||
|
kind: "discrete";
|
||||||
|
keys: DiscreteAnimationKey[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AnimationChannel =
|
||||||
|
| ScalarAnimationChannel
|
||||||
|
| DiscreteAnimationChannel;
|
||||||
|
|
||||||
|
export type ElementAnimationChannelMap = Record<
|
||||||
|
string,
|
||||||
|
AnimationChannel | undefined
|
||||||
|
>;
|
||||||
|
|
||||||
|
export interface AnimationBindingComponent<TKey extends string = string> {
|
||||||
|
key: TKey;
|
||||||
|
channelId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseAnimationBinding<
|
||||||
|
TKind extends AnimationBindingKind,
|
||||||
|
TComponentKey extends string,
|
||||||
|
> {
|
||||||
|
path: AnimationPath;
|
||||||
|
kind: TKind;
|
||||||
|
components: AnimationBindingComponent<TComponentKey>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumberAnimationBinding
|
||||||
|
extends BaseAnimationBinding<"number", "value"> {}
|
||||||
|
|
||||||
|
export interface Vector2AnimationBinding
|
||||||
|
extends BaseAnimationBinding<"vector2", "x" | "y"> {}
|
||||||
|
|
||||||
|
export interface ColorAnimationBinding
|
||||||
|
extends BaseAnimationBinding<"color", "r" | "g" | "b" | "a"> {
|
||||||
|
colorSpace: "srgb-linear";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiscreteAnimationBinding
|
||||||
|
extends BaseAnimationBinding<"discrete", "value"> {}
|
||||||
|
|
||||||
|
export type AnimationBindingInstance =
|
||||||
|
| NumberAnimationBinding
|
||||||
|
| Vector2AnimationBinding
|
||||||
|
| ColorAnimationBinding
|
||||||
|
| DiscreteAnimationBinding;
|
||||||
|
|
||||||
|
export interface AnimationBindingByKind {
|
||||||
|
number: NumberAnimationBinding;
|
||||||
|
vector2: Vector2AnimationBinding;
|
||||||
|
color: ColorAnimationBinding;
|
||||||
|
discrete: DiscreteAnimationBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AnimationBindingOfKind<TKind extends AnimationBindingKind> =
|
||||||
|
AnimationBindingByKind[TKind];
|
||||||
|
|
||||||
|
export type ElementAnimationBindingMap = Record<
|
||||||
|
string,
|
||||||
|
AnimationBindingInstance | undefined
|
||||||
|
>;
|
||||||
|
|
||||||
|
export interface ElementAnimations {
|
||||||
|
bindings: ElementAnimationBindingMap;
|
||||||
|
channels: ElementAnimationChannelMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NormalizedCubicBezier = [number, number, number, number];
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import type { ParamValues } from "./param-values";
|
||||||
|
|
||||||
|
export interface Effect {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
params: ParamValues;
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EffectUniformValue = number | number[];
|
||||||
|
|
||||||
|
export interface EffectPass {
|
||||||
|
shader: string;
|
||||||
|
uniforms: Record<string, EffectUniformValue>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EffectPassTemplate {
|
||||||
|
shader: string;
|
||||||
|
uniforms(params: {
|
||||||
|
effectParams: ParamValues;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}): Record<string, EffectUniformValue>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export * from "./animations";
|
||||||
|
export * from "./effect";
|
||||||
|
export * from "./mask";
|
||||||
|
export * from "./param-values";
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
export type MaskType =
|
||||||
|
| "split"
|
||||||
|
| "cinematic-bars"
|
||||||
|
| "rectangle"
|
||||||
|
| "ellipse"
|
||||||
|
| "heart"
|
||||||
|
| "diamond"
|
||||||
|
| "star"
|
||||||
|
| "text"
|
||||||
|
| "custom";
|
||||||
|
|
||||||
|
export interface BaseMaskParams {
|
||||||
|
feather: number;
|
||||||
|
inverted: boolean;
|
||||||
|
strokeColor: string;
|
||||||
|
strokeWidth: number;
|
||||||
|
strokeAlign: "inside" | "center" | "outside";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SplitMaskParams extends BaseMaskParams {
|
||||||
|
centerX: number;
|
||||||
|
centerY: number;
|
||||||
|
rotation: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RectangleMaskParams extends BaseMaskParams {
|
||||||
|
centerX: number;
|
||||||
|
centerY: number;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
rotation: number;
|
||||||
|
scale: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TextFontWeight = "normal" | "bold";
|
||||||
|
export type TextFontStyle = "normal" | "italic";
|
||||||
|
export type TextDecoration = "none" | "underline" | "line-through";
|
||||||
|
|
||||||
|
export interface TextMaskParams extends BaseMaskParams {
|
||||||
|
content: string;
|
||||||
|
fontSize: number;
|
||||||
|
fontFamily: string;
|
||||||
|
fontWeight: TextFontWeight;
|
||||||
|
fontStyle: TextFontStyle;
|
||||||
|
textDecoration: TextDecoration;
|
||||||
|
letterSpacing: number;
|
||||||
|
lineHeight: number;
|
||||||
|
centerX: number;
|
||||||
|
centerY: number;
|
||||||
|
rotation: number;
|
||||||
|
scale: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomMaskPathPoint {
|
||||||
|
id: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
inX: number;
|
||||||
|
inY: number;
|
||||||
|
outX: number;
|
||||||
|
outY: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomMaskParams extends BaseMaskParams {
|
||||||
|
path: CustomMaskPathPoint[];
|
||||||
|
closed: boolean;
|
||||||
|
centerX: number;
|
||||||
|
centerY: number;
|
||||||
|
rotation: number;
|
||||||
|
scale: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SplitMask {
|
||||||
|
id: string;
|
||||||
|
type: "split";
|
||||||
|
params: SplitMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CinematicBarsMask {
|
||||||
|
id: string;
|
||||||
|
type: "cinematic-bars";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RectangleMask {
|
||||||
|
id: string;
|
||||||
|
type: "rectangle";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EllipseMask {
|
||||||
|
id: string;
|
||||||
|
type: "ellipse";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeartMask {
|
||||||
|
id: string;
|
||||||
|
type: "heart";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiamondMask {
|
||||||
|
id: string;
|
||||||
|
type: "diamond";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StarMask {
|
||||||
|
id: string;
|
||||||
|
type: "star";
|
||||||
|
params: RectangleMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TextMask {
|
||||||
|
id: string;
|
||||||
|
type: "text";
|
||||||
|
params: TextMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomMask {
|
||||||
|
id: string;
|
||||||
|
type: "custom";
|
||||||
|
params: CustomMaskParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Mask =
|
||||||
|
| SplitMask
|
||||||
|
| CinematicBarsMask
|
||||||
|
| RectangleMask
|
||||||
|
| EllipseMask
|
||||||
|
| HeartMask
|
||||||
|
| DiamondMask
|
||||||
|
| StarMask
|
||||||
|
| TextMask
|
||||||
|
| CustomMask;
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
export type ParamValues = Record<string, number | string | boolean>;
|
||||||
|
|
||||||
|
export type ParamGroup = "stroke";
|
||||||
|
|
||||||
|
interface BaseParamDefinition<TKey extends string = string> {
|
||||||
|
key: TKey;
|
||||||
|
label: string;
|
||||||
|
group?: ParamGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumberParamDefinition<TKey extends string = string>
|
||||||
|
extends BaseParamDefinition<TKey> {
|
||||||
|
type: "number";
|
||||||
|
default: number;
|
||||||
|
min: number;
|
||||||
|
max?: number;
|
||||||
|
step: number;
|
||||||
|
/** When set, min/max/step are in display space. display = stored * displayMultiplier. */
|
||||||
|
displayMultiplier?: number;
|
||||||
|
/** Show as percentage of max. min/max/step/default stay in stored space. */
|
||||||
|
unit?: "percent";
|
||||||
|
/** Short label shown as the scrub handle icon in the number field (e.g. "W", "R"). */
|
||||||
|
shortLabel?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BooleanParamDefinition<TKey extends string = string>
|
||||||
|
extends BaseParamDefinition<TKey> {
|
||||||
|
type: "boolean";
|
||||||
|
default: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ColorParamDefinition<TKey extends string = string>
|
||||||
|
extends BaseParamDefinition<TKey> {
|
||||||
|
type: "color";
|
||||||
|
default: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SelectParamDefinition<TKey extends string = string>
|
||||||
|
extends BaseParamDefinition<TKey> {
|
||||||
|
type: "select";
|
||||||
|
default: string;
|
||||||
|
options: Array<{ value: string; label: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ParamDefinition<TKey extends string = string> =
|
||||||
|
| NumberParamDefinition<TKey>
|
||||||
|
| BooleanParamDefinition<TKey>
|
||||||
|
| ColorParamDefinition<TKey>
|
||||||
|
| SelectParamDefinition<TKey>;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import type { ElementId } from "../ids";
|
import type { ElementId } from "../ids";
|
||||||
|
|
||||||
export interface BaseTimelineElement {
|
export interface BaseTimelineElement {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { BaseTimelineElement } from "./base";
|
import type { BaseTimelineElement } from "./base";
|
||||||
|
|
||||||
export interface EffectElement extends BaseTimelineElement {
|
export interface EffectElement extends BaseTimelineElement {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { Mask } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { BaseTimelineElement } from "./base";
|
import type { BaseTimelineElement } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { Mask } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { BaseTimelineElement } from "./base";
|
import type { BaseTimelineElement } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { BaseTimelineElement } from "./base";
|
import type { BaseTimelineElement } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { BaseTimelineElement } from "./base";
|
import type { BaseTimelineElement } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Effect } from "@/effects/types";
|
import type { Effect } from "@/model/decorations/effect";
|
||||||
import type { Mask } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { BaseTimelineElement, RetimeConfig } from "./base";
|
import type { BaseTimelineElement, RetimeConfig } from "./base";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from "./bookmark";
|
export * from "./bookmark";
|
||||||
|
export * from "./decorations";
|
||||||
export * from "./element-ref";
|
export * from "./element-ref";
|
||||||
export * from "./elements";
|
export * from "./elements";
|
||||||
export * from "./ids";
|
export * from "./ids";
|
||||||
|
|||||||
@@ -1,50 +1,10 @@
|
|||||||
export type ParamValues = Record<string, number | string | boolean>;
|
export type {
|
||||||
|
BooleanParamDefinition,
|
||||||
export type ParamGroup = "stroke";
|
ColorParamDefinition,
|
||||||
|
NumberParamDefinition,
|
||||||
interface BaseParamDefinition<TKey extends string = string> {
|
ParamDefinition,
|
||||||
key: TKey;
|
ParamGroup,
|
||||||
label: string;
|
ParamValues,
|
||||||
group?: ParamGroup;
|
SelectParamDefinition,
|
||||||
}
|
} from "@/model/decorations/param-values";
|
||||||
|
|
||||||
export interface NumberParamDefinition<TKey extends string = string>
|
|
||||||
extends BaseParamDefinition<TKey> {
|
|
||||||
type: "number";
|
|
||||||
default: number;
|
|
||||||
min: number;
|
|
||||||
max?: number;
|
|
||||||
step: number;
|
|
||||||
/** When set, min/max/step are in display space. display = stored * displayMultiplier. */
|
|
||||||
displayMultiplier?: number;
|
|
||||||
/** Show as percentage of max. min/max/step/default stay in stored space. */
|
|
||||||
unit?: "percent";
|
|
||||||
/** Short label shown as the scrub handle icon in the number field (e.g. "W", "R"). */
|
|
||||||
shortLabel?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BooleanParamDefinition<TKey extends string = string>
|
|
||||||
extends BaseParamDefinition<TKey> {
|
|
||||||
type: "boolean";
|
|
||||||
default: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ColorParamDefinition<TKey extends string = string>
|
|
||||||
extends BaseParamDefinition<TKey> {
|
|
||||||
type: "color";
|
|
||||||
default: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SelectParamDefinition<TKey extends string = string>
|
|
||||||
extends BaseParamDefinition<TKey> {
|
|
||||||
type: "select";
|
|
||||||
default: string;
|
|
||||||
options: Array<{ value: string; label: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ParamDefinition<TKey extends string = string> =
|
|
||||||
| NumberParamDefinition<TKey>
|
|
||||||
| BooleanParamDefinition<TKey>
|
|
||||||
| ColorParamDefinition<TKey>
|
|
||||||
| SelectParamDefinition<TKey>;
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ParamDefinition, ParamValues } from "@/params";
|
import type { ParamDefinition, ParamValues } from "@/model/decorations/param-values";
|
||||||
|
|
||||||
export function buildDefaultParamValues(
|
export function buildDefaultParamValues(
|
||||||
params: ParamDefinition[],
|
params: ParamDefinition[],
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
hasKeyframesForPath,
|
hasKeyframesForPath,
|
||||||
setChannel,
|
setChannel,
|
||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import type { Transform } from "@/rendering";
|
import type { Transform } from "@/rendering";
|
||||||
import { resolveTransformAtTime } from "@/rendering/animation-values";
|
import { resolveTransformAtTime } from "@/rendering/animation-values";
|
||||||
import type { ElementRef, SceneTracks, TimelineElement, VisualElement } from "@/model";
|
import type { ElementRef, SceneTracks, TimelineElement, VisualElement } from "@/model";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import { resolveAnimationPathValueAtTime } from "@/animation";
|
import { resolveAnimationPathValueAtTime } from "@/animation";
|
||||||
import type { Transform } from "./index";
|
import type { Transform } from "./index";
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import type { BlendMode } from "@/rendering";
|
import type { BlendMode } from "@/rendering";
|
||||||
import type { ElementType } from "@/model";
|
import type { ElementType } from "@/model";
|
||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import { HugeiconsIcon } from "@hugeicons/react";
|
import { HugeiconsIcon } from "@hugeicons/react";
|
||||||
import { RainDropIcon } from "@hugeicons/core-free-icons";
|
import { RainDropIcon } from "@hugeicons/core-free-icons";
|
||||||
import { KeyframeToggle } from "@/components/editor/panels/properties/components/keyframe-toggle";
|
import { KeyframeToggle } from "@/components/editor/panels/properties/components/keyframe-toggle";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { BlendMode } from "@/rendering";
|
import type { BlendMode } from "@/rendering";
|
||||||
import type { EffectPass } from "@/effects/types";
|
import type { EffectPass } from "@/model/decorations/effect";
|
||||||
|
|
||||||
export type FrameDescriptor = {
|
export type FrameDescriptor = {
|
||||||
width: number;
|
width: number;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createOffscreenCanvas } from "./canvas-utils";
|
import { createOffscreenCanvas } from "./canvas-utils";
|
||||||
import { effectsRegistry, resolveEffectPasses } from "@/effects";
|
import { effectsRegistry, resolveEffectPasses } from "@/effects";
|
||||||
import { buildDefaultParamValues } from "@/params/registry";
|
import { buildDefaultParamValues } from "@/params/registry";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import { gpuRenderer } from "./gpu-renderer";
|
import { gpuRenderer } from "./gpu-renderer";
|
||||||
|
|
||||||
const PREVIEW_SIZE = 160;
|
const PREVIEW_SIZE = 160;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
applyMaskFeather as applyMaskFeatherWasm,
|
applyMaskFeather as applyMaskFeatherWasm,
|
||||||
initializeGpu,
|
initializeGpu,
|
||||||
} from "opencut-wasm";
|
} from "opencut-wasm";
|
||||||
import type { EffectPass, EffectUniformValue } from "@/effects/types";
|
import type { EffectPass, EffectUniformValue } from "@/model/decorations/effect";
|
||||||
|
|
||||||
let gpuAvailable = false;
|
let gpuAvailable = false;
|
||||||
let initPromise: Promise<void> | null = null;
|
let initPromise: Promise<void> | null = null;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { EffectPass } from "@/effects/types";
|
import type { EffectPass } from "@/model/decorations/effect";
|
||||||
import type { RetimeConfig } from "@/model";
|
import type { RetimeConfig } from "@/model";
|
||||||
import { BaseNode } from "./base-node";
|
import { BaseNode } from "./base-node";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { EffectPass } from "@/effects/types";
|
import type { EffectPass } from "@/model/decorations/effect";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import { BaseNode } from "./base-node";
|
import { BaseNode } from "./base-node";
|
||||||
|
|
||||||
export type EffectLayerNodeParams = {
|
export type EffectLayerNodeParams = {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
getGraphicDefinition,
|
getGraphicDefinition,
|
||||||
registerDefaultGraphics,
|
registerDefaultGraphics,
|
||||||
} from "@/graphics";
|
} from "@/graphics";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import {
|
import {
|
||||||
VisualNode,
|
VisualNode,
|
||||||
type ResolvedVisualNodeState,
|
type ResolvedVisualNodeState,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BaseNode } from "./base-node";
|
import { BaseNode } from "./base-node";
|
||||||
import type { TextElement } from "@/model";
|
import type { TextElement } from "@/model";
|
||||||
import type { EffectPass } from "@/effects/types";
|
import type { EffectPass } from "@/model/decorations/effect";
|
||||||
import type { Transform } from "@/rendering";
|
import type { Transform } from "@/rendering";
|
||||||
import { drawMeasuredTextLayout } from "@/text/primitives";
|
import { drawMeasuredTextLayout } from "@/text/primitives";
|
||||||
import type { MeasuredTextElement } from "@/text/measure-element";
|
import type { MeasuredTextElement } from "@/text/measure-element";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { BaseNode } from "./base-node";
|
import { BaseNode } from "./base-node";
|
||||||
import type { Effect, EffectPass } from "@/effects/types";
|
import type { Effect, EffectPass } from "@/model/decorations/effect";
|
||||||
import type { Mask } from "@/masks/types";
|
import type { Mask } from "@/model/decorations/mask";
|
||||||
import type { BlendMode, Transform } from "@/rendering";
|
import type { BlendMode, Transform } from "@/rendering";
|
||||||
import type { RetimeConfig, VisualElement } from "@/model";
|
import type { RetimeConfig, VisualElement } from "@/model";
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
intensityToSigma,
|
intensityToSigma,
|
||||||
} from "@/effects/definitions/blur";
|
} from "@/effects/definitions/blur";
|
||||||
import { effectsRegistry, resolveEffectPasses } from "@/effects";
|
import { effectsRegistry, resolveEffectPasses } from "@/effects";
|
||||||
import type { Effect, EffectPass } from "@/effects/types";
|
import type { Effect, EffectPass } from "@/model/decorations/effect";
|
||||||
import { getSourceTimeAtClipTime } from "@/retime";
|
import { getSourceTimeAtClipTime } from "@/retime";
|
||||||
import {
|
import {
|
||||||
DEFAULT_GRAPHIC_SOURCE_SIZE,
|
DEFAULT_GRAPHIC_SOURCE_SIZE,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { buildGraphicPreviewUrl, buildDefaultGraphicInstance, graphicsRegistry, registerDefaultGraphics } from "@/graphics";
|
import { buildGraphicPreviewUrl, buildDefaultGraphicInstance, graphicsRegistry, registerDefaultGraphics } from "@/graphics";
|
||||||
import type { ParamValues } from "@/params";
|
import type { ParamValues } from "@/model/decorations/param-values";
|
||||||
import { buildStickerId, parseStickerId } from "../sticker-id";
|
import { buildStickerId, parseStickerId } from "../sticker-id";
|
||||||
import type {
|
import type {
|
||||||
StickerBrowseResult,
|
StickerBrowseResult,
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import type {
|
import type { AnimationBindingKind, AnimationInterpolation, AnimationPropertyPath, AnimationValue, ElementAnimations, NumericSpec } from "@/model/decorations/animations";
|
||||||
AnimationBindingKind,
|
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationPropertyPath,
|
|
||||||
AnimationValue,
|
|
||||||
ElementAnimations,
|
|
||||||
NumericSpec,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import { upsertPathKeyframe } from "@/animation";
|
import { upsertPathKeyframe } from "@/animation";
|
||||||
import { parseColorToLinearRgba } from "@/animation/binding-values";
|
import { parseColorToLinearRgba } from "@/animation/binding-values";
|
||||||
import { isAnimationPropertyPath } from "@/animation/path";
|
import { isAnimationPropertyPath } from "@/animation/path";
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
import type {
|
import type { AnimationBindingKind, AnimationInterpolation, AnimationPath, AnimationValue, NumericSpec } from "@/model/decorations/animations";
|
||||||
AnimationBindingKind,
|
|
||||||
AnimationInterpolation,
|
|
||||||
AnimationPath,
|
|
||||||
AnimationValue,
|
|
||||||
NumericSpec,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import {
|
import {
|
||||||
coerceAnimationParamValue,
|
coerceAnimationParamValue,
|
||||||
getAnimationParamDefaultInterpolation,
|
getAnimationParamDefaultInterpolation,
|
||||||
@@ -19,7 +13,7 @@ import {
|
|||||||
} from "@/animation/graphic-param-channel";
|
} from "@/animation/graphic-param-channel";
|
||||||
import { effectsRegistry, registerDefaultEffects } from "@/effects";
|
import { effectsRegistry, registerDefaultEffects } from "@/effects";
|
||||||
import { getGraphicDefinition } from "@/graphics";
|
import { getGraphicDefinition } from "@/graphics";
|
||||||
import type { ParamDefinition } from "@/params";
|
import type { ParamDefinition } from "@/model/decorations/param-values";
|
||||||
import type { TimelineElement } from "@/model";
|
import type { TimelineElement } from "@/model";
|
||||||
import { isVisualElement } from "@/timeline/element-utils";
|
import { isVisualElement } from "@/timeline/element-utils";
|
||||||
import { isAnimationPropertyPath } from "@/animation/path";
|
import { isAnimationPropertyPath } from "@/animation/path";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { cloneAnimations } from "@/animation";
|
import { cloneAnimations } from "@/animation";
|
||||||
import type { ElementAnimations } from "@/animation/types";
|
import type { ElementAnimations } from "@/model/decorations/animations";
|
||||||
import type { MediaAsset } from "@/media/types";
|
import type { MediaAsset } from "@/media/types";
|
||||||
import { DEFAULTS } from "@/timeline/defaults";
|
import { DEFAULTS } from "@/timeline/defaults";
|
||||||
import type { AudioElement, CreateUploadAudioElement, TimelineElement, VideoElement } from "@/model";
|
import type { AudioElement, CreateUploadAudioElement, TimelineElement, VideoElement } from "@/model";
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import type {
|
import type { AnimationPath, ElementAnimations } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
|
||||||
ElementAnimations,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { TimelineTrack } from "@/model";
|
import type { TimelineTrack } from "@/model";
|
||||||
import { getElementKeyframes } from "@/animation";
|
import { getElementKeyframes } from "@/animation";
|
||||||
import { KEYFRAME_LANE_HEIGHT_PX } from "./layout";
|
import { KEYFRAME_LANE_HEIGHT_PX } from "./layout";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useRef, useState, type PointerEvent } from "react";
|
import { useRef, useState, type PointerEvent } from "react";
|
||||||
import { useShiftKey } from "@/hooks/use-shift-key";
|
import { useShiftKey } from "@/hooks/use-shift-key";
|
||||||
import { getBezierPoint } from "@/animation/bezier";
|
import { getBezierPoint } from "@/animation/bezier";
|
||||||
import type { NormalizedCubicBezier } from "@/animation/types";
|
import type { NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
import { cn } from "@/utils/ui";
|
import { cn } from "@/utils/ui";
|
||||||
|
|
||||||
const GRAPH_WIDTH = 140;
|
const GRAPH_WIDTH = 140;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useSyncExternalStore } from "react";
|
import { useSyncExternalStore } from "react";
|
||||||
import { generateUUID } from "@/utils/id";
|
import { generateUUID } from "@/utils/id";
|
||||||
import type { NormalizedCubicBezier } from "@/animation/types";
|
import type { NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
import type { EasingPreset } from "./easing-presets";
|
import type { EasingPreset } from "./easing-presets";
|
||||||
|
|
||||||
const STORAGE_KEY = "graph-editor-presets";
|
const STORAGE_KEY = "graph-editor-presets";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { NormalizedCubicBezier } from "@/animation/types";
|
import type { NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
|
|
||||||
export const PRESET_MATCH_TOLERANCE = 0.02;
|
export const PRESET_MATCH_TOLERANCE = 0.02;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
PlusSignIcon,
|
PlusSignIcon,
|
||||||
} from "@hugeicons/core-free-icons";
|
} from "@hugeicons/core-free-icons";
|
||||||
import { getBezierPoint } from "@/animation/bezier";
|
import { getBezierPoint } from "@/animation/bezier";
|
||||||
import type { NormalizedCubicBezier } from "@/animation/types";
|
import type { NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
import type { GraphEditorComponentOption } from "./session";
|
import type { GraphEditorComponentOption } from "./session";
|
||||||
import {
|
import {
|
||||||
BUILTIN_PRESETS,
|
BUILTIN_PRESETS,
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ import {
|
|||||||
getScalarKeyframeContext,
|
getScalarKeyframeContext,
|
||||||
updateScalarKeyframeCurve,
|
updateScalarKeyframeCurve,
|
||||||
} from "@/animation";
|
} from "@/animation";
|
||||||
import type {
|
import type { AnimationPath, ElementAnimations, NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
AnimationPath,
|
import type { ScalarCurveKeyframePatch, ScalarGraphKeyframeContext, SelectedKeyframeRef } from "@/animation/types";
|
||||||
ElementAnimations,
|
|
||||||
NormalizedCubicBezier,
|
|
||||||
ScalarCurveKeyframePatch,
|
|
||||||
ScalarGraphKeyframeContext,
|
|
||||||
SelectedKeyframeRef,
|
|
||||||
} from "@/animation/types";
|
|
||||||
import type { SceneTracks, TimelineElement } from "@/model";
|
import type { SceneTracks, TimelineElement } from "@/model";
|
||||||
|
|
||||||
const GRAPH_LINEAR_CURVE: NormalizedCubicBezier = [0, 0, 1, 1];
|
const GRAPH_LINEAR_CURVE: NormalizedCubicBezier = [0, 0, 1, 1];
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { useEditor } from "@/editor/use-editor";
|
import { useEditor } from "@/editor/use-editor";
|
||||||
import { registerCanceller } from "@/editor/cancel-interaction";
|
import { registerCanceller } from "@/editor/cancel-interaction";
|
||||||
import type { NormalizedCubicBezier } from "@/animation/types";
|
import type { NormalizedCubicBezier } from "@/model/decorations/animations";
|
||||||
import { useKeyframeSelection } from "@/timeline/hooks/element/use-keyframe-selection";
|
import { useKeyframeSelection } from "@/timeline/hooks/element/use-keyframe-selection";
|
||||||
import {
|
import {
|
||||||
applyGraphEditorCurvePreview,
|
applyGraphEditorCurvePreview,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user