mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(studio): address caption designer PR feedback (#200)
* fix(studio): address caption designer PR feedback Fixes from review comments on feature/caption-designer (#180): - fix(generator): guard named colors in hexToRgba — "red", "transparent" no longer produce NaN rgba values - fix(sync): log auto-save failures instead of silently swallowing them - fix(sync): check res.ok before parsing caption-overrides response - refactor(components): extract Section, Row, inputCls into shared.tsx to eliminate duplication between CaptionPropertyPanel and CaptionAnimationPanel - fix(store): replace non-deterministic Date.now()+Math.random() ID with counter-based group IDs - fix(store): read selectedGroupId from state param instead of get() to avoid stale reads in batched set() calls - fix(overlay): remove cssScale multiplier from getBoundingClientRect coords — the browser already accounts for CSS transforms - docs(parser): add comment explaining the lazy ]; regex assumption Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): address remaining caption designer feedback Overlay: handle both per-word spans (generator output) and grouped text nodes (existing templates). Wraps text nodes into individual spans on demand so the overlay can target words in any caption format. Property panel: add Typography (font, size, weight, spacing) and Color (color, active, dim, opacity) sections alongside existing Position and Transform controls. Timeline: move caption timeline into a dedicated flex-shrink-0 section below the main timeline tracks instead of inside the scrollable area. Gives it fixed 60px height that's always visible. Caption overrides: classify color tweens by comparing target color to the dim baseline instead of relying on timeline position order. This handles compositions with custom color tweens correctly. App.tsx: remove polling interval, rely on runtime postMessage events for caption detection. Add clarifying comment on why useEffect is appropriate (external event subscription). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): restore cssScale in overlay coordinate conversion getBoundingClientRect() on iframe-internal elements returns coordinates in the iframe's native resolution (1920x1080), not the CSS-scaled display size. The cssScale multiplier is needed to convert to parent window coordinates. The earlier removal was incorrect — it only worked at 1:1 scale. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): fix reversed scaling on left-side corner handles Scale interaction used horizontal dx from start position, which goes negative when dragging left handles outward. Now uses distance from box center — dragging away from center increases scale regardless of which corner handle is used. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): make rotation respond to horizontal drag only Rotation handle sits directly above the word, so atan2-based rotation barely responds to left/right movement. Replace with linear horizontal mapping: drag right = clockwise, drag left = counter-clockwise, 200px = 90 degrees. Vertical movement is ignored. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(studio): remove animation tab and typography/color from property panel Keep only Position (X, Y) and Transform (Scale, Rotation) controls. Remove tab switcher UI since there's only one view now. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: fix oxfmt formatting in CLAUDE.md and captions skill docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d36c1785b9
commit
5e2781b459
@@ -83,25 +83,30 @@ export function applyCaptionOverrides(): void {
|
||||
if (override.fontWeight !== undefined) styleProps.fontWeight = override.fontWeight;
|
||||
if (override.fontFamily !== undefined) styleProps.fontFamily = override.fontFamily;
|
||||
|
||||
// Replace color values in existing GSAP tweens by timeline order.
|
||||
// For any word, color tweens follow: dim (setup) → active (spoken) → after.
|
||||
// Sort by startTime and assign by position, not by content heuristics.
|
||||
// Replace color values in existing GSAP tweens.
|
||||
// Instead of relying on timeline position order (fragile if custom
|
||||
// color tweens exist), we classify each tween by comparing its
|
||||
// target color to the current computed color of the element.
|
||||
// Tweens that match the current color are "dim" tweens; tweens
|
||||
// with a different color are "active" tweens.
|
||||
if (override.activeColor || override.dimColor) {
|
||||
const allTweens = gsap.getTweensOf(el);
|
||||
const colorTweens = allTweens
|
||||
.filter((tw) => tw.vars.color !== undefined)
|
||||
.sort((a, b) => a.startTime() - b.startTime());
|
||||
|
||||
for (let i = 0; i < colorTweens.length; i++) {
|
||||
if (i === 0 && override.dimColor) {
|
||||
// First color tween = dim setup
|
||||
colorTweens[i].vars.color = override.dimColor;
|
||||
} else if (i === 1 && override.activeColor) {
|
||||
// Second color tween = active/spoken
|
||||
colorTweens[i].vars.color = override.activeColor;
|
||||
} else if (i >= 2 && override.dimColor) {
|
||||
// Third+ = after/deactivate (use dim color)
|
||||
colorTweens[i].vars.color = override.dimColor;
|
||||
// Use the first tween's color as the dim baseline — if no tweens,
|
||||
// fall back to computed style.
|
||||
const dimBaseline = colorTweens.length > 0 ? String(colorTweens[0].vars.color) : "";
|
||||
|
||||
for (const tw of colorTweens) {
|
||||
const tweenColor = String(tw.vars.color);
|
||||
if (tweenColor === dimBaseline) {
|
||||
// This tween targets the dim/inactive color
|
||||
if (override.dimColor) tw.vars.color = override.dimColor;
|
||||
} else {
|
||||
// This tween targets the active/spoken color
|
||||
if (override.activeColor) tw.vars.color = override.activeColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user