mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-08 10:46:06 +00:00
feat(studio): scale GSAP positions on clip resize + shift on drag + diamond fixes (#1448)
Resize: proportionally scale all GSAP animation positions and durations to fit the new clip duration via scalePositionsInScript. This preserves clip-relative keyframe percentages — diamonds don't move during resize, nothing disappears. Modeled after After Effects Time Stretch behavior. Drag: shift all GSAP positions by the time delta (unchanged from before). Diamond rendering: - Clamp diamonds at 0%/100% so they stay fully visible at clip edges - Filter out-of-range keyframes using predicted percentages during resize - Clamp connection lines to clip boundaries - PropertyRows: same edge clamping for SVG diamonds Parser: scalePositionsInScript (proportional position + duration scaling), shiftPositionsInScript (rigid shift), scale-positions + shift-positions mutation types, 5 shift tests passing.
This commit is contained in:
@@ -6,7 +6,7 @@ interface GestureTrailOverlayProps {
|
||||
sampleCount?: number;
|
||||
trail?: Array<{ x: number; y: number }>;
|
||||
simplifiedPoints?: Map<number, Record<string, number>>;
|
||||
canvasRect: { left: number; top: number; width: number; height: number };
|
||||
canvasRect: { left: number; top: number; width: number; height: number } | null;
|
||||
compositionSize?: { width: number; height: number };
|
||||
mode: "recording" | "preview";
|
||||
accentColor?: string;
|
||||
@@ -23,6 +23,7 @@ export const GestureTrailOverlay = memo(function GestureTrailOverlay({
|
||||
accentColor = "#3CE6AC",
|
||||
}: GestureTrailOverlayProps) {
|
||||
const trailPoints = useMemo(() => {
|
||||
if (!canvasRect) return "";
|
||||
if (trail && trail.length > 1) {
|
||||
return trail.map((p) => `${p.x - canvasRect.left},${p.y - canvasRect.top}`).join(" ");
|
||||
}
|
||||
@@ -32,7 +33,7 @@ export const GestureTrailOverlay = memo(function GestureTrailOverlay({
|
||||
.map((s) => `${s.properties.x},${s.properties.y}`)
|
||||
.join(" ");
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [samples, trail, sampleCount, canvasRect.left, canvasRect.top]);
|
||||
}, [samples, trail, sampleCount, canvasRect?.left, canvasRect?.top]);
|
||||
|
||||
const simplifiedPath = useMemo(() => {
|
||||
if (!simplifiedPoints || simplifiedPoints.size === 0) return "";
|
||||
@@ -58,7 +59,7 @@ export const GestureTrailOverlay = memo(function GestureTrailOverlay({
|
||||
return pts.sort((a, b) => a.pct - b.pct);
|
||||
}, [simplifiedPoints]);
|
||||
|
||||
if (samples.length < 2 && !simplifiedPoints) return null;
|
||||
if (!canvasRect || (samples.length < 2 && !simplifiedPoints)) return null;
|
||||
|
||||
return (
|
||||
<svg
|
||||
|
||||
Reference in New Issue
Block a user