mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 01:38:44 +00:00
Bug/fix keyframes (#419)
Co-authored-by: Christopher Oliphant <RALifeCoach@users.noreply.github.com>
This commit is contained in:
1 parent
14bbd47b12
commit
e939639337
7 files changed
+87
-134
No files matched your search
@@ -24,13 +24,13 @@ import { TimerGrid } from "~/pages/PageEnigma/comps/Timeline/TimerGrid";
|
||||
import { Scrubber } from "~/pages/PageEnigma/comps/Timeline/Scrubber";
|
||||
import { Characters } from "~/pages/PageEnigma/comps/Timeline/Characters";
|
||||
import { ObjectGroups } from "~/pages/PageEnigma/comps/Timeline/ObjectGroups";
|
||||
import useUpdateKeyframe from "~/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe";
|
||||
import { Clip, Keyframe } from "~/pages/PageEnigma/models";
|
||||
import { RowHeaders } from "~/pages/PageEnigma/comps/Timeline/RowHeaders/RowHeaders";
|
||||
import { pageWidth } from "~/signals";
|
||||
import { Pages } from "~/pages/PageEnigma/constants/page";
|
||||
import PremiumLockTimeline from "./PremiumLockTimeline";
|
||||
import { AssetType, DoNotShow } from "~/enums";
|
||||
import { deleteKeyframe } from "~/pages/PageEnigma/signals/timeline";
|
||||
|
||||
function getItemType(item: Clip | Keyframe | null) {
|
||||
if (!item) {
|
||||
@@ -50,7 +50,6 @@ function scrollItem(itemId: string) {
|
||||
export const Timeline = () => {
|
||||
useSignals();
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const { deleteKeyframe } = useUpdateKeyframe();
|
||||
const lastSelectedObject = useRef(selectedObject.value);
|
||||
|
||||
if (selectedObject.value !== lastSelectedObject.current) {
|
||||
@@ -101,7 +100,7 @@ export const Timeline = () => {
|
||||
deleteKeyframe(selectedItem.value as Keyframe);
|
||||
}
|
||||
selectedItem.value = null;
|
||||
}, [deleteKeyframe]);
|
||||
}, []);
|
||||
|
||||
const onDeleteAsk = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
@@ -114,7 +113,9 @@ export const Timeline = () => {
|
||||
) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const show = localStorage.getItem("Delete-clip");
|
||||
const show = localStorage.getItem(
|
||||
`Delete-${getItemType(selectedItem.value)}`,
|
||||
);
|
||||
if (show === DoNotShow) {
|
||||
onDelete();
|
||||
return;
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
import { createContext } from "react";
|
||||
import { MediaItem, Keyframe, QueueKeyframe } from "~/pages/PageEnigma/models";
|
||||
import { MediaItem } from "~/pages/PageEnigma/models";
|
||||
|
||||
export const TrackContext = createContext<{
|
||||
// keyframes
|
||||
addKeyframe: (keyframe: QueueKeyframe, offset: number) => void;
|
||||
deleteKeyframe: (keyframe: Keyframe) => void;
|
||||
deleteObjectOrCharacter: (item: MediaItem) => void;
|
||||
|
||||
// misc
|
||||
clearExistingData: () => void;
|
||||
|
||||
// drag and drop
|
||||
startDrag: (item: MediaItem) => void;
|
||||
endDrag: () => void;
|
||||
}>({
|
||||
addKeyframe: () => {},
|
||||
deleteKeyframe: () => {},
|
||||
deleteObjectOrCharacter: () => {},
|
||||
|
||||
clearExistingData: () => {},
|
||||
|
||||
startDrag: () => {},
|
||||
endDrag: () => {},
|
||||
});
|
||||
@@ -1,24 +1,12 @@
|
||||
import { TrackContext } from "~/pages/PageEnigma/contexts/TrackContext/TrackContext";
|
||||
import { ReactNode, useCallback, useMemo } from "react";
|
||||
import { MediaItem } from "~/pages/PageEnigma/models";
|
||||
import useUpdateDragDrop from "~/pages/PageEnigma/contexts/TrackContext/utils/useUpdateDragDrop";
|
||||
import {
|
||||
characterGroup,
|
||||
cameraGroup,
|
||||
audioGroup,
|
||||
objectGroup,
|
||||
deleteCharacter,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import useUpdateKeyframe from "~/pages/PageEnigma/contexts/TrackContext/utils/useUpdateKeyframe";
|
||||
import { deleteObject } from "~/pages/PageEnigma/signals/objectGroup/deleteObject";
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const TrackProvider = ({ children }: Props) => {
|
||||
const keyframes = useUpdateKeyframe();
|
||||
|
||||
const { endDrag, ...dragDrop } = useUpdateDragDrop();
|
||||
|
||||
// cross group functions
|
||||
@@ -26,48 +14,12 @@ export const TrackProvider = ({ children }: Props) => {
|
||||
endDrag();
|
||||
}, [endDrag]);
|
||||
|
||||
const clearExistingData = useCallback(() => {
|
||||
characterGroup.value = {
|
||||
id: "ChG1",
|
||||
characters: [],
|
||||
};
|
||||
cameraGroup.value = {
|
||||
id: "CG1",
|
||||
keyframes: [],
|
||||
};
|
||||
audioGroup.value = {
|
||||
id: "AG-1",
|
||||
clips: [],
|
||||
muted: false,
|
||||
};
|
||||
objectGroup.value = {
|
||||
id: "OG1",
|
||||
objects: [],
|
||||
};
|
||||
}, []);
|
||||
|
||||
const deleteObjectOrCharacter = useCallback((item: MediaItem) => {
|
||||
deleteCharacter(item);
|
||||
deleteObject(item);
|
||||
}, []);
|
||||
|
||||
const values = useMemo(() => {
|
||||
return {
|
||||
...keyframes,
|
||||
|
||||
clearExistingData,
|
||||
deleteObjectOrCharacter,
|
||||
|
||||
...dragDrop,
|
||||
endDrag: dropClip,
|
||||
};
|
||||
}, [
|
||||
keyframes,
|
||||
dragDrop,
|
||||
dropClip,
|
||||
clearExistingData,
|
||||
deleteObjectOrCharacter,
|
||||
]);
|
||||
}, [dragDrop, dropClip]);
|
||||
|
||||
return (
|
||||
<TrackContext.Provider value={values}>{children}</TrackContext.Provider>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import { useCallback } from "react";
|
||||
import { QueueKeyframe, Keyframe } from "~/pages/PageEnigma/models";
|
||||
import {
|
||||
addCameraKeyframe,
|
||||
addCharacterKeyframe,
|
||||
addObjectKeyframe,
|
||||
deleteCameraKeyframe,
|
||||
deleteCharacterKeyframe,
|
||||
deleteObjectKeyframe,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import { ClipGroup } from "~/pages/PageEnigma/enums";
|
||||
|
||||
const ADD_KEYFRAME: Record<
|
||||
ClipGroup,
|
||||
(keyframe: QueueKeyframe, offset: number) => void
|
||||
> = {
|
||||
[ClipGroup.CAMERA]: addCameraKeyframe,
|
||||
[ClipGroup.CHARACTER]: addCharacterKeyframe,
|
||||
[ClipGroup.OBJECT]: addObjectKeyframe,
|
||||
[ClipGroup.GLOBAL_AUDIO]: () => {},
|
||||
};
|
||||
|
||||
const DELETE_KEYFRAME: Record<ClipGroup, (keyframe: Keyframe) => void> = {
|
||||
[ClipGroup.CAMERA]: deleteCameraKeyframe,
|
||||
[ClipGroup.CHARACTER]: deleteCharacterKeyframe,
|
||||
[ClipGroup.OBJECT]: deleteObjectKeyframe,
|
||||
[ClipGroup.GLOBAL_AUDIO]: () => {},
|
||||
};
|
||||
|
||||
export default function useUpdateKeyframe() {
|
||||
const addKeyframe = useCallback((keyframe: QueueKeyframe, offset: number) => {
|
||||
ADD_KEYFRAME[keyframe.group](keyframe, offset);
|
||||
}, []);
|
||||
|
||||
const deleteKeyframe = useCallback((keyframe: Keyframe) => {
|
||||
DELETE_KEYFRAME[keyframe.group](keyframe);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
addKeyframe,
|
||||
deleteKeyframe,
|
||||
};
|
||||
}
|
||||
@@ -1,44 +1,35 @@
|
||||
import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { useCallback, useContext, useEffect } from "react";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import {
|
||||
addNewCharacter,
|
||||
addObjectToTimeline,
|
||||
clearExistingData,
|
||||
currentTime,
|
||||
deleteObjectOrCharacter,
|
||||
loadAudioData,
|
||||
loadCameraData,
|
||||
loadCharacterData,
|
||||
loadObjectData,
|
||||
selectedObject,
|
||||
addKeyframe,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import Queue, { ToastDataType } from "~/pages/PageEnigma/Queue/Queue";
|
||||
import Queue, {
|
||||
QueueSubscribeType,
|
||||
ToastDataType,
|
||||
} from "~/pages/PageEnigma/Queue/Queue";
|
||||
import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames";
|
||||
import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions";
|
||||
import {
|
||||
MediaItem,
|
||||
QueueClip,
|
||||
QueueKeyframe,
|
||||
UpdateTime,
|
||||
} from "~/pages/PageEnigma/models";
|
||||
import { ClipGroup } from "~/pages/PageEnigma/enums";
|
||||
import { TrackContext } from "~/pages/PageEnigma/contexts/TrackContext/TrackContext";
|
||||
import { addToast } from "~/signals";
|
||||
import { ToastTypes } from "~/enums";
|
||||
import { toTimelineActions } from "~/pages/PageEnigma/Queue/toTimelineActions";
|
||||
import { ClipUI } from "~/pages/PageEnigma/datastructures/clips/clip_ui";
|
||||
|
||||
interface Arguments {
|
||||
action: fromEngineActions | toEngineActions | toTimelineActions;
|
||||
data:
|
||||
| QueueClip
|
||||
| UpdateTime
|
||||
| QueueKeyframe
|
||||
| ClipUI[]
|
||||
| MediaItem
|
||||
| ToastDataType
|
||||
| null;
|
||||
}
|
||||
|
||||
const LOADING_FUNCTIONS: Record<ClipGroup, (item: ClipUI) => void> = {
|
||||
[ClipGroup.CHARACTER]: loadCharacterData,
|
||||
[ClipGroup.OBJECT]: loadObjectData,
|
||||
@@ -48,11 +39,9 @@ const LOADING_FUNCTIONS: Record<ClipGroup, (item: ClipUI) => void> = {
|
||||
|
||||
export function useQueueHandler() {
|
||||
useSignals();
|
||||
const { addKeyframe, clearExistingData, deleteObjectOrCharacter } =
|
||||
useContext(TrackContext);
|
||||
|
||||
const handleFromEngineActions = useCallback(
|
||||
({ action, data }: Arguments) => {
|
||||
({ action, data }: QueueSubscribeType) => {
|
||||
console.log("FROM ENGINE", action, data);
|
||||
switch (action) {
|
||||
case fromEngineActions.ADD_OBJECT: {
|
||||
@@ -97,11 +86,11 @@ export function useQueueHandler() {
|
||||
throw new Error(`Unknown action ${action}`);
|
||||
}
|
||||
},
|
||||
[clearExistingData, deleteObjectOrCharacter],
|
||||
[deleteObjectOrCharacter],
|
||||
);
|
||||
|
||||
const handleToTimelineActions = useCallback(
|
||||
({ action, data }: Arguments) => {
|
||||
({ action, data }: QueueSubscribeType) => {
|
||||
console.log("TO TIMELINE", action, data);
|
||||
switch (action) {
|
||||
case toTimelineActions.ADD_KEYFRAME:
|
||||
@@ -111,7 +100,7 @@ export function useQueueHandler() {
|
||||
throw new Error(`Unknown action ${action}`);
|
||||
}
|
||||
},
|
||||
[addKeyframe],
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -15,4 +15,5 @@ export * from "./sidePanel";
|
||||
export * from "./sizing";
|
||||
export * from "./stylizeTab";
|
||||
export * from "./timing";
|
||||
export * from "./timeline";
|
||||
export * from "./error";
|
||||
@@ -0,0 +1,67 @@
|
||||
import { useCallback } from "react";
|
||||
import { QueueKeyframe, Keyframe, MediaItem } from "~/pages/PageEnigma/models";
|
||||
import {
|
||||
addCameraKeyframe,
|
||||
addCharacterKeyframe,
|
||||
addObjectKeyframe,
|
||||
audioGroup,
|
||||
cameraGroup,
|
||||
characterGroup,
|
||||
deleteCameraKeyframe,
|
||||
deleteCharacter,
|
||||
deleteCharacterKeyframe,
|
||||
deleteObjectKeyframe,
|
||||
objectGroup,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import { ClipGroup } from "~/pages/PageEnigma/enums";
|
||||
import { deleteObject } from "~/pages/PageEnigma/signals/objectGroup/deleteObject";
|
||||
|
||||
const ADD_KEYFRAME: Record<
|
||||
ClipGroup,
|
||||
(keyframe: QueueKeyframe, offset: number) => void
|
||||
> = {
|
||||
[ClipGroup.CAMERA]: addCameraKeyframe,
|
||||
[ClipGroup.CHARACTER]: addCharacterKeyframe,
|
||||
[ClipGroup.OBJECT]: addObjectKeyframe,
|
||||
[ClipGroup.GLOBAL_AUDIO]: () => {},
|
||||
};
|
||||
|
||||
const DELETE_KEYFRAME: Record<ClipGroup, (keyframe: Keyframe) => void> = {
|
||||
[ClipGroup.CAMERA]: deleteCameraKeyframe,
|
||||
[ClipGroup.CHARACTER]: deleteCharacterKeyframe,
|
||||
[ClipGroup.OBJECT]: deleteObjectKeyframe,
|
||||
[ClipGroup.GLOBAL_AUDIO]: () => {},
|
||||
};
|
||||
|
||||
export function addKeyframe(keyframe: QueueKeyframe, offset: number) {
|
||||
ADD_KEYFRAME[keyframe.group](keyframe, offset);
|
||||
}
|
||||
|
||||
export function deleteKeyframe(keyframe: Keyframe) {
|
||||
DELETE_KEYFRAME[keyframe.group](keyframe);
|
||||
}
|
||||
|
||||
export function clearExistingData() {
|
||||
characterGroup.value = {
|
||||
id: "ChG1",
|
||||
characters: [],
|
||||
};
|
||||
cameraGroup.value = {
|
||||
id: "CG1",
|
||||
keyframes: [],
|
||||
};
|
||||
audioGroup.value = {
|
||||
id: "AG-1",
|
||||
clips: [],
|
||||
muted: false,
|
||||
};
|
||||
objectGroup.value = {
|
||||
id: "OG1",
|
||||
objects: [],
|
||||
};
|
||||
}
|
||||
|
||||
export function deleteObjectOrCharacter(item: MediaItem) {
|
||||
deleteCharacter(item);
|
||||
deleteObject(item);
|
||||
}
|
||||
Reference in new issue
Block a user