mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
fix(studio): span the clip on the remaining duration-less tween paths
Two sibling call paths still answered from GSAP's 0.5s default while the toggle path had moved to the clip-wide fallback. isPlayheadWithinTween now takes the selection, so the toolbar stops promising "extends animation" on a duration-less tween whose click actually toggles an interior keyframe. The arc drag commit resolves its replacement duration the same way its click-path sibling does, instead of authoring duration 0.5 and collapsing the arc window. The flat text section drops its two marker-clearing effects: the autofocus marker is a ref now, read and cleared by the render that consumes it.
This commit is contained in:
@@ -4,6 +4,7 @@ import { usePlayerStore } from "../player/store/playerStore";
|
||||
import { resolveTweenStart, resolveTweenDuration } from "../utils/globalTimeCompiler";
|
||||
import { roundTo3 } from "../utils/rounding";
|
||||
import { computeDraggedGsapPosition } from "./draggedGsapPosition";
|
||||
import { resolveEditableTweenDuration } from "./gsapShared";
|
||||
import {
|
||||
type GsapDragCommitCallbacks,
|
||||
computeCurrentPercentage,
|
||||
@@ -297,7 +298,9 @@ export async function commitGsapPositionFromDrag(
|
||||
}
|
||||
|
||||
const tweenStart = resolveTweenStart(anim);
|
||||
const tweenDuration = resolveTweenDuration(anim);
|
||||
// Clip-wide, same as applyArcKeyframeAtPlayhead: authoring GSAP's 0.5s
|
||||
// default here would collapse a duration-less arc's window on drag.
|
||||
const tweenDuration = resolveEditableTweenDuration(anim, selection);
|
||||
if (tweenStart === null || tweenDuration <= 0 || keyframes.length < 2) return;
|
||||
const temporalKeyframes = buildTemporalArcKeyframes(anim, pct, { x: newX, y: newY });
|
||||
await callbacks.commitMutation(
|
||||
|
||||
@@ -108,6 +108,19 @@ describe("isPlayheadWithinTween", () => {
|
||||
it("does not block when the start can't be resolved", () => {
|
||||
expect(isPlayheadWithinTween(anim({ position: "+=1" }), 99)).toBe(true);
|
||||
});
|
||||
|
||||
// The toolbar's "extends animation" tooltip has to agree with what the edit
|
||||
// paths do. Those span a duration-less tween across its clip, so answering
|
||||
// from GSAP's 0.5s default reported the playhead outside a window the click
|
||||
// then treated as clip-wide.
|
||||
it("spans the clip for a duration-less tween when given the selection", () => {
|
||||
const durationless = anim({ position: 0 });
|
||||
const selection = { dataAttributes: { duration: "16" } } as unknown as DomEditSelection;
|
||||
|
||||
expect(isPlayheadWithinTween(durationless, 5)).toBe(false);
|
||||
expect(isPlayheadWithinTween(durationless, 5, selection)).toBe(true);
|
||||
expect(isPlayheadWithinTween(durationless, 20, selection)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildExtendedKeyframes", () => {
|
||||
|
||||
@@ -77,11 +77,22 @@ export function animatedProps(anim: GsapAnimation | null): string[] {
|
||||
* Whether the playhead sits inside an animation's tween range. When the tween's
|
||||
* start can't be resolved we don't block (the percentage falls back to clip range,
|
||||
* preserving prior behavior for elements without explicit timing).
|
||||
*
|
||||
* Pass the selection whenever the caller has one: a duration-less tween spans
|
||||
* its clip, and answering from GSAP's 0.5s default reports the playhead outside
|
||||
* a window the edit paths treat as clip-wide.
|
||||
*/
|
||||
export function isPlayheadWithinTween(anim: GsapAnimation, currentTime: number): boolean {
|
||||
export function isPlayheadWithinTween(
|
||||
anim: GsapAnimation,
|
||||
currentTime: number,
|
||||
selection?: DomEditSelection | null,
|
||||
): boolean {
|
||||
const start = resolveTweenStart(anim);
|
||||
if (start === null) return true;
|
||||
return isTimeWithinTween(currentTime, start, resolveTweenDuration(anim));
|
||||
const duration = selection
|
||||
? resolveEditableTweenDuration(anim, selection)
|
||||
: resolveTweenDuration(anim);
|
||||
return isTimeWithinTween(currentTime, start, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user