fix: resize not matching with frames
This commit is contained in:
parent
b00d6d5fb6
commit
09cb8c8d98
|
|
@ -68,45 +68,51 @@ export function TimelineTrackContent({
|
|||
elementDuration: number,
|
||||
excludeElementId?: string
|
||||
) => {
|
||||
if (!snappingEnabled) {
|
||||
// Use frame snapping if project has FPS, otherwise use decimal snapping
|
||||
const projectStore = useProjectStore.getState();
|
||||
const projectFps = projectStore.activeProject?.fps || 30;
|
||||
return snapTimeToFrame(dropTime, projectFps);
|
||||
// Always apply frame snapping first
|
||||
const projectStore = useProjectStore.getState();
|
||||
const projectFps = projectStore.activeProject?.fps || 30;
|
||||
let finalTime = snapTimeToFrame(dropTime, projectFps);
|
||||
|
||||
// Additionally apply element snapping if enabled
|
||||
if (snappingEnabled) {
|
||||
// Try snapping both start and end edges for drops
|
||||
const startSnapResult = snapElementEdge(
|
||||
dropTime,
|
||||
elementDuration,
|
||||
tracks,
|
||||
currentTime,
|
||||
zoomLevel,
|
||||
excludeElementId,
|
||||
true // snap to start edge
|
||||
);
|
||||
|
||||
const endSnapResult = snapElementEdge(
|
||||
dropTime,
|
||||
elementDuration,
|
||||
tracks,
|
||||
currentTime,
|
||||
zoomLevel,
|
||||
excludeElementId,
|
||||
false // snap to end edge
|
||||
);
|
||||
|
||||
// Choose the snap result with the smaller distance (closer snap)
|
||||
let bestSnapResult = startSnapResult;
|
||||
if (
|
||||
endSnapResult.snapPoint &&
|
||||
(!startSnapResult.snapPoint ||
|
||||
endSnapResult.snapDistance < startSnapResult.snapDistance)
|
||||
) {
|
||||
bestSnapResult = endSnapResult;
|
||||
}
|
||||
|
||||
// Only use element snapping if it found a snap point, otherwise keep frame-snapped time
|
||||
if (bestSnapResult.snapPoint) {
|
||||
finalTime = bestSnapResult.snappedTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Try snapping both start and end edges for drops
|
||||
const startSnapResult = snapElementEdge(
|
||||
dropTime,
|
||||
elementDuration,
|
||||
tracks,
|
||||
currentTime,
|
||||
zoomLevel,
|
||||
excludeElementId,
|
||||
true // snap to start edge
|
||||
);
|
||||
|
||||
const endSnapResult = snapElementEdge(
|
||||
dropTime,
|
||||
elementDuration,
|
||||
tracks,
|
||||
currentTime,
|
||||
zoomLevel,
|
||||
excludeElementId,
|
||||
false // snap to end edge
|
||||
);
|
||||
|
||||
// Choose the snap result with the smaller distance (closer snap)
|
||||
let bestSnapResult = startSnapResult;
|
||||
if (
|
||||
endSnapResult.snapPoint &&
|
||||
(!startSnapResult.snapPoint ||
|
||||
endSnapResult.snapDistance < startSnapResult.snapDistance)
|
||||
) {
|
||||
bestSnapResult = endSnapResult;
|
||||
}
|
||||
|
||||
return bestSnapResult.snappedTime;
|
||||
return finalTime;
|
||||
};
|
||||
|
||||
const timelineRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -148,9 +154,13 @@ export function TimelineTrackContent({
|
|||
);
|
||||
const adjustedTime = Math.max(0, mouseTime - dragState.clickOffsetTime);
|
||||
|
||||
// Apply snapping if enabled
|
||||
let finalTime = adjustedTime;
|
||||
// Always apply frame snapping first
|
||||
const projectStore = useProjectStore.getState();
|
||||
const projectFps = projectStore.activeProject?.fps || 30;
|
||||
let finalTime = snapTimeToFrame(adjustedTime, projectFps);
|
||||
let snapPoint = null;
|
||||
|
||||
// Additionally apply element snapping if enabled
|
||||
if (snappingEnabled) {
|
||||
// Find the element being dragged to get its duration
|
||||
let elementDuration = 5; // fallback duration
|
||||
|
|
@ -196,18 +206,16 @@ export function TimelineTrackContent({
|
|||
bestSnapResult = endSnapResult;
|
||||
}
|
||||
|
||||
finalTime = bestSnapResult.snappedTime;
|
||||
snapPoint = bestSnapResult.snapPoint;
|
||||
// Only use element snapping if it found a snap point, otherwise keep frame-snapped time
|
||||
if (bestSnapResult.snapPoint) {
|
||||
finalTime = bestSnapResult.snappedTime;
|
||||
snapPoint = bestSnapResult.snapPoint;
|
||||
}
|
||||
|
||||
// Notify parent component about snap point change
|
||||
onSnapPointChange?.(snapPoint);
|
||||
} else {
|
||||
// Use frame snapping if project has FPS, otherwise use decimal snapping
|
||||
const projectStore = useProjectStore.getState();
|
||||
const projectFps = projectStore.activeProject?.fps || 30;
|
||||
finalTime = snapTimeToFrame(adjustedTime, projectFps);
|
||||
|
||||
// Clear snap point when not snapping
|
||||
// Clear snap point when element snapping is disabled
|
||||
onSnapPointChange?.(null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,17 +221,34 @@ export function useTimelineElementResize({
|
|||
}
|
||||
} else {
|
||||
// Normal trimming within original duration
|
||||
const maxTrimEnd = element.duration - resizing.initialTrimStart - 0.1; // Leave at least 0.1s visible
|
||||
const newTrimEnd = snapTimeToFrame(
|
||||
Math.max(0, Math.min(maxTrimEnd, calculated)),
|
||||
projectFps
|
||||
// Calculate the desired end time based on mouse movement
|
||||
const currentEndTime =
|
||||
element.startTime +
|
||||
element.duration -
|
||||
element.trimStart -
|
||||
element.trimEnd;
|
||||
const desiredEndTime = currentEndTime + deltaTime;
|
||||
|
||||
// Snap the desired end time to frame
|
||||
const snappedEndTime = snapTimeToFrame(desiredEndTime, projectFps);
|
||||
|
||||
// Calculate what trimEnd should be to achieve this snapped end time
|
||||
const newTrimEnd = Math.max(
|
||||
0,
|
||||
element.duration -
|
||||
element.trimStart -
|
||||
(snappedEndTime - element.startTime)
|
||||
);
|
||||
|
||||
// Ensure we don't trim more than available content (leave at least 0.1s visible)
|
||||
const maxTrimEnd = element.duration - element.trimStart - 0.1;
|
||||
const finalTrimEnd = Math.min(maxTrimEnd, newTrimEnd);
|
||||
|
||||
updateElementTrim(
|
||||
track.id,
|
||||
element.id,
|
||||
resizing.initialTrimStart,
|
||||
newTrimEnd,
|
||||
element.trimStart,
|
||||
finalTrimEnd,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue