mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
feat: position animated independently per axis
Made-with: Cursor
This commit is contained in:
@@ -1,56 +1,58 @@
|
||||
export { StorageMigration } from "./base";
|
||||
import { V0toV1Migration } from "./v0-to-v1";
|
||||
import { V1toV2Migration } from "./v1-to-v2";
|
||||
import { V2toV3Migration } from "./v2-to-v3";
|
||||
import { V3toV4Migration } from "./v3-to-v4";
|
||||
import { V4toV5Migration } from "./v4-to-v5";
|
||||
import { V5toV6Migration } from "./v5-to-v6";
|
||||
import { V6toV7Migration } from "./v6-to-v7";
|
||||
import { V7toV8Migration } from "./v7-to-v8";
|
||||
import { V8toV9Migration } from "./v8-to-v9";
|
||||
import { V9toV10Migration } from "./v9-to-v10";
|
||||
import { V10toV11Migration } from "./v10-to-v11";
|
||||
import { V11toV12Migration } from "./v11-to-v12";
|
||||
import { V12toV13Migration } from "./v12-to-v13";
|
||||
import { V13toV14Migration } from "./v13-to-v14";
|
||||
import { V14toV15Migration } from "./v14-to-v15";
|
||||
import { V15toV16Migration } from "./v15-to-v16";
|
||||
import { V16toV17Migration } from "./v16-to-v17";
|
||||
import { V17toV18Migration } from "./v17-to-v18";
|
||||
import { V18toV19Migration } from "./v18-to-v19";
|
||||
import { V19toV20Migration } from "./v19-to-v20";
|
||||
import { V20toV21Migration } from "./v20-to-v21";
|
||||
import { V21toV22Migration } from "./v21-to-v22";
|
||||
import { V22toV23Migration } from "./v22-to-v23";
|
||||
import { V23toV24Migration } from "./v23-to-v24";
|
||||
export { runStorageMigrations } from "./runner";
|
||||
export type { MigrationProgress } from "./runner";
|
||||
|
||||
export const CURRENT_PROJECT_VERSION = 24;
|
||||
|
||||
export const migrations = [
|
||||
new V0toV1Migration(),
|
||||
new V1toV2Migration(),
|
||||
new V2toV3Migration(),
|
||||
new V3toV4Migration(),
|
||||
new V4toV5Migration(),
|
||||
new V5toV6Migration(),
|
||||
new V6toV7Migration(),
|
||||
new V7toV8Migration(),
|
||||
new V8toV9Migration(),
|
||||
new V9toV10Migration(),
|
||||
new V10toV11Migration(),
|
||||
new V11toV12Migration(),
|
||||
new V12toV13Migration(),
|
||||
new V13toV14Migration(),
|
||||
new V14toV15Migration(),
|
||||
new V15toV16Migration(),
|
||||
new V16toV17Migration(),
|
||||
new V17toV18Migration(),
|
||||
new V18toV19Migration(),
|
||||
new V19toV20Migration(),
|
||||
new V20toV21Migration(),
|
||||
new V21toV22Migration(),
|
||||
new V22toV23Migration(),
|
||||
new V23toV24Migration(),
|
||||
];
|
||||
export { StorageMigration } from "./base";
|
||||
import { V0toV1Migration } from "./v0-to-v1";
|
||||
import { V1toV2Migration } from "./v1-to-v2";
|
||||
import { V2toV3Migration } from "./v2-to-v3";
|
||||
import { V3toV4Migration } from "./v3-to-v4";
|
||||
import { V4toV5Migration } from "./v4-to-v5";
|
||||
import { V5toV6Migration } from "./v5-to-v6";
|
||||
import { V6toV7Migration } from "./v6-to-v7";
|
||||
import { V7toV8Migration } from "./v7-to-v8";
|
||||
import { V8toV9Migration } from "./v8-to-v9";
|
||||
import { V9toV10Migration } from "./v9-to-v10";
|
||||
import { V10toV11Migration } from "./v10-to-v11";
|
||||
import { V11toV12Migration } from "./v11-to-v12";
|
||||
import { V12toV13Migration } from "./v12-to-v13";
|
||||
import { V13toV14Migration } from "./v13-to-v14";
|
||||
import { V14toV15Migration } from "./v14-to-v15";
|
||||
import { V15toV16Migration } from "./v15-to-v16";
|
||||
import { V16toV17Migration } from "./v16-to-v17";
|
||||
import { V17toV18Migration } from "./v17-to-v18";
|
||||
import { V18toV19Migration } from "./v18-to-v19";
|
||||
import { V19toV20Migration } from "./v19-to-v20";
|
||||
import { V20toV21Migration } from "./v20-to-v21";
|
||||
import { V21toV22Migration } from "./v21-to-v22";
|
||||
import { V22toV23Migration } from "./v22-to-v23";
|
||||
import { V23toV24Migration } from "./v23-to-v24";
|
||||
import { V24toV25Migration } from "./v24-to-v25";
|
||||
export { runStorageMigrations } from "./runner";
|
||||
export type { MigrationProgress } from "./runner";
|
||||
|
||||
export const CURRENT_PROJECT_VERSION = 25;
|
||||
|
||||
export const migrations = [
|
||||
new V0toV1Migration(),
|
||||
new V1toV2Migration(),
|
||||
new V2toV3Migration(),
|
||||
new V3toV4Migration(),
|
||||
new V4toV5Migration(),
|
||||
new V5toV6Migration(),
|
||||
new V6toV7Migration(),
|
||||
new V7toV8Migration(),
|
||||
new V8toV9Migration(),
|
||||
new V9toV10Migration(),
|
||||
new V10toV11Migration(),
|
||||
new V11toV12Migration(),
|
||||
new V12toV13Migration(),
|
||||
new V13toV14Migration(),
|
||||
new V14toV15Migration(),
|
||||
new V15toV16Migration(),
|
||||
new V16toV17Migration(),
|
||||
new V17toV18Migration(),
|
||||
new V18toV19Migration(),
|
||||
new V19toV20Migration(),
|
||||
new V20toV21Migration(),
|
||||
new V21toV22Migration(),
|
||||
new V22toV23Migration(),
|
||||
new V23toV24Migration(),
|
||||
new V24toV25Migration(),
|
||||
];
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import type { MigrationResult, ProjectRecord } from "./types";
|
||||
import { getProjectId, isRecord } from "./utils";
|
||||
|
||||
export function transformProjectV24ToV25({
|
||||
project,
|
||||
}: {
|
||||
project: ProjectRecord;
|
||||
}): MigrationResult<ProjectRecord> {
|
||||
if (!getProjectId({ project })) {
|
||||
return { project, skipped: true, reason: "no project id" };
|
||||
}
|
||||
|
||||
const version = project.version;
|
||||
if (typeof version !== "number") {
|
||||
return { project, skipped: true, reason: "invalid version" };
|
||||
}
|
||||
if (version >= 25) {
|
||||
return { project, skipped: true, reason: "already v25" };
|
||||
}
|
||||
if (version !== 24) {
|
||||
return { project, skipped: true, reason: "not v24" };
|
||||
}
|
||||
|
||||
return {
|
||||
project: {
|
||||
...migrateProject({ project }),
|
||||
version: 25,
|
||||
},
|
||||
skipped: false,
|
||||
};
|
||||
}
|
||||
|
||||
function migrateProject({
|
||||
project,
|
||||
}: {
|
||||
project: ProjectRecord;
|
||||
}): ProjectRecord {
|
||||
if (!Array.isArray(project.scenes)) {
|
||||
return project;
|
||||
}
|
||||
|
||||
return {
|
||||
...project,
|
||||
scenes: project.scenes.map((scene) => migrateScene({ scene })),
|
||||
};
|
||||
}
|
||||
|
||||
function migrateScene({ scene }: { scene: unknown }): unknown {
|
||||
if (!isRecord(scene) || !isRecord(scene.tracks)) {
|
||||
return scene;
|
||||
}
|
||||
|
||||
const tracks = scene.tracks;
|
||||
const nextTracks: ProjectRecord = { ...tracks };
|
||||
|
||||
if (isRecord(tracks.main)) {
|
||||
nextTracks.main = migrateTrack({ track: tracks.main });
|
||||
}
|
||||
|
||||
if (Array.isArray(tracks.overlay)) {
|
||||
nextTracks.overlay = tracks.overlay.map((track) =>
|
||||
migrateTrack({ track }),
|
||||
);
|
||||
}
|
||||
|
||||
if (Array.isArray(tracks.audio)) {
|
||||
nextTracks.audio = tracks.audio.map((track) => migrateTrack({ track }));
|
||||
}
|
||||
|
||||
return { ...scene, tracks: nextTracks };
|
||||
}
|
||||
|
||||
function migrateTrack({ track }: { track: unknown }): unknown {
|
||||
if (!isRecord(track) || !Array.isArray(track.elements)) {
|
||||
return track;
|
||||
}
|
||||
|
||||
return {
|
||||
...track,
|
||||
elements: track.elements.map((element) => migrateElement({ element })),
|
||||
};
|
||||
}
|
||||
|
||||
function migrateElement({ element }: { element: unknown }): unknown {
|
||||
if (!isRecord(element) || !isRecord(element.animations)) {
|
||||
return element;
|
||||
}
|
||||
|
||||
const nextAnimations = migrateAnimations({ animations: element.animations });
|
||||
if (nextAnimations === element.animations) {
|
||||
return element;
|
||||
}
|
||||
|
||||
return { ...element, animations: nextAnimations };
|
||||
}
|
||||
|
||||
function migrateAnimations({
|
||||
animations,
|
||||
}: {
|
||||
animations: ProjectRecord;
|
||||
}): ProjectRecord {
|
||||
if (!isRecord(animations.bindings) || !isRecord(animations.channels)) {
|
||||
return animations;
|
||||
}
|
||||
|
||||
const positionBinding = animations.bindings["transform.position"];
|
||||
if (!isRecord(positionBinding) || positionBinding.kind !== "vector2") {
|
||||
return animations;
|
||||
}
|
||||
|
||||
const xChannel = animations.channels["transform.position:x"];
|
||||
const yChannel = animations.channels["transform.position:y"];
|
||||
|
||||
const nextBindings: ProjectRecord = { ...animations.bindings };
|
||||
const nextChannels: ProjectRecord = { ...animations.channels };
|
||||
|
||||
delete nextBindings["transform.position"];
|
||||
delete nextChannels["transform.position:x"];
|
||||
delete nextChannels["transform.position:y"];
|
||||
|
||||
nextBindings["transform.positionX"] = {
|
||||
path: "transform.positionX",
|
||||
kind: "number",
|
||||
components: [{ key: "value", channelId: "transform.positionX:value" }],
|
||||
};
|
||||
nextBindings["transform.positionY"] = {
|
||||
path: "transform.positionY",
|
||||
kind: "number",
|
||||
components: [{ key: "value", channelId: "transform.positionY:value" }],
|
||||
};
|
||||
|
||||
if (isRecord(xChannel)) {
|
||||
nextChannels["transform.positionX:value"] = xChannel;
|
||||
}
|
||||
if (isRecord(yChannel)) {
|
||||
nextChannels["transform.positionY:value"] = yChannel;
|
||||
}
|
||||
|
||||
return { ...animations, bindings: nextBindings, channels: nextChannels };
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { StorageMigration } from "./base";
|
||||
import type { ProjectRecord } from "./transformers/types";
|
||||
import { transformProjectV24ToV25 } from "./transformers/v24-to-v25";
|
||||
|
||||
export class V24toV25Migration extends StorageMigration {
|
||||
from = 24;
|
||||
to = 25;
|
||||
|
||||
async transform(project: ProjectRecord): Promise<{
|
||||
project: ProjectRecord;
|
||||
skipped: boolean;
|
||||
reason?: string;
|
||||
}> {
|
||||
return transformProjectV24ToV25({ project });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user