mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
fix(studio): correct gesture commits for scaled and graded elements
- resize on a scale-driven element commits per-axis scale (scaleX/scaleY for non-uniform drags) with keyframe normalization to the longhands, and clears the width/height draft so size can't double-apply; the intercept moves to gsapResizeIntercept.ts - the drop frame applies the corrected position synchronously in the same microtask chain as the soft reload (no network-window jump), and the draft pins the anchor through accumulated moves on scaled elements - gesture size/position math divides by the element's own content scale - convert-to-keyframes resolves current values through the property-group filter for ALL capture passes (opacity/rotationX from unrelated tweens no longer leak into a rotation commit), and a grading-hidden source's opacity is read from its canvas, not the inline hide - canvas pointer-down confirms the hover target with a synchronous hit-test before starting a marquee (stale-hover race lost selections)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { memo, useEffect, useMemo, useRef, useState, type RefObject } from "react";
|
||||
import { getPreviewTargetFromPointer } from "../../utils/studioPreviewHelpers";
|
||||
import { type DomEditSelection } from "./domEditing";
|
||||
import type { PreviewMouseDownOptions } from "../../hooks/usePreviewInteraction";
|
||||
import { useMarqueeGestures } from "./marqueeCommit";
|
||||
@@ -305,8 +306,18 @@ export const DomEditOverlay = memo(function DomEditOverlay({
|
||||
const target = event.target as HTMLElement | null;
|
||||
if (target?.closest('[data-dom-edit-selection-box="true"]')) return;
|
||||
|
||||
// Start marquee if clicking on empty canvas (no element under pointer)
|
||||
// Start marquee if clicking on empty canvas (no element under pointer).
|
||||
// The hover selection is an ASYNC cache: on a fast click (or when the
|
||||
// pointer was already resting over an element) it can still be empty while
|
||||
// an element IS under the pointer — starting a marquee here would swallow
|
||||
// the selection mousedown and the click would silently select nothing.
|
||||
// Confirm emptiness with a fresh SYNCHRONOUS hit-test before committing.
|
||||
if (!hoverSelectionRef.current && onMarqueeSelectRef.current && compRect.width > 0) {
|
||||
const iframe = iframeRef.current;
|
||||
const freshTarget = iframe
|
||||
? getPreviewTargetFromPointer(iframe, event.clientX, event.clientY, activeCompositionPath)
|
||||
: null;
|
||||
if (freshTarget) return;
|
||||
const overlayEl = overlayRef.current;
|
||||
if (overlayEl) {
|
||||
const oRect = overlayEl.getBoundingClientRect();
|
||||
|
||||
Reference in New Issue
Block a user