fix(studio): keyframe bug fixes — gate delete hooks, fix value corruption, gesture recording (#1314)

- Gate stripStudioEditsFromTarget/bakeVisibilityOnDelete behind a
  stripStudioEdits flag on the delete mutation type so they only fire on
  user-initiated deletes, not on internal delete-then-recreate drags.

- Add bakeVisibilityOnDelete to the remove-all-keyframes handler so
  elements with CSS opacity:0 stay visible after collapsing keyframes.

- Fix integer rounding in readAllAnimatedProperties: use 3-decimal
  precision for visual properties (opacity, scale, rotation) instead of
  Math.round which corrupted mid-fade values to 0.

- Guard VISUAL_BASELINE against cross-tween contamination by querying
  __timelines for properties animated by other tweens on the same element.

- Harden bakeVisibilityOnDelete: reverse-scan keyframes for the last one
  containing opacity, guard against relative values (+=/-=/*=), and add
  Number.isFinite check.

- Fix falsy-zero doubling in drag commit: replace || fallback with
  Number.isFinite so a base GSAP position of 0 is correctly preserved.

- Fix gesture recording sign inversion: remove pointerElementOffset
  subtraction from dx/dy formula and instead apply it once to basePosition
  so the element center tracks the pointer.

- Fix TypeScript build errors in gsapSoftReload.ts (6 double-casts).

- Strip all diagnostic logs from production code.
This commit is contained in:
Miguel Ángel
2026-06-10 18:53:06 -04:00
committed by GitHub
parent 3a72aa528d
commit f0b499b582
38 changed files with 1641 additions and 821 deletions
+7 -7
View File
@@ -100,7 +100,7 @@ export async function materializeIfDynamic(
* keyframe percentages to preserve their absolute positions, then add
* a new keyframe at the target time.
*/
export async function extendTweenAndAddKeyframe(
async function extendTweenAndAddKeyframe(
selection: DomEditSelection,
anim: GsapAnimation,
properties: Record<string, number>,
@@ -149,7 +149,7 @@ export async function extendTweenAndAddKeyframe(
}
// fallow-ignore-next-line complexity
export async function commitKeyframedPosition(
async function commitKeyframedPosition(
selection: DomEditSelection,
anim: GsapAnimation,
properties: Record<string, number>,
@@ -175,7 +175,7 @@ export async function commitKeyframedPosition(
* drag position at the current percentage.
*/
// fallow-ignore-next-line complexity
export async function commitFlatViaKeyframes(
async function commitFlatViaKeyframes(
selection: DomEditSelection,
anim: GsapAnimation,
properties: Record<string, number>,
@@ -230,10 +230,10 @@ export async function commitGsapPositionFromDrag(
const deltaY = studioOffset.y - origY;
const adjX = deltaX * cos - deltaY * sin;
const adjY = deltaX * sin + deltaY * cos;
const baseGsapX =
Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-x") ?? "") || gsapPos.x;
const baseGsapY =
Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-y") ?? "") || gsapPos.y;
const parsedBaseX = Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-x") ?? "");
const parsedBaseY = Number.parseFloat(el.getAttribute("data-hf-drag-gsap-base-y") ?? "");
const baseGsapX = Number.isFinite(parsedBaseX) ? parsedBaseX : gsapPos.x;
const baseGsapY = Number.isFinite(parsedBaseY) ? parsedBaseY : gsapPos.y;
const newX = Math.round(baseGsapX + adjX);
const newY = Math.round(baseGsapY + adjY);
const restoreOffset = () => {