mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 10:14:30 +00:00
* feat(studio): runtime hooks — global time compiler + keyframe runtime Add the runtime bridge layer: global time compilation (tween % → clip %), soft reload after mutations, runtime keyframe preview, and keyframe commit helper. * feat(studio): runtime hooks — global time compiler + keyframe runtime Add the runtime bridge layer: global time compilation (tween % → clip %), soft reload after mutations, runtime keyframe preview, and keyframe commit helper. * feat(studio): keyframe cache + commit hooks Add hooks for keyframe cache population (tween → clip-relative %), mutation dispatch, keyframe snapping, and audio beat detection. * feat(studio): timeline UI — dopesheet diamonds + keyboard nav Add dopesheet strip with diamond keyframe indicators, timeline property rows, keyboard navigation (J/Shift+J/Delete/K), and feature gate (STUDIO_KEYFRAMES_ENABLED defaults to false). * feat(studio): design panel — arc controls + ease curve + stagger Add arc path controls (curviness slider, auto-rotate), motion path SVG overlay, ease curve visualization, stagger controls, and expanded animation card. Includes border-radius editor dependency from #1217. * feat(studio): gesture recording core Add gesture recording engine with RAF sampling, modifier key property mapping (Shift→rotationXY, Alt→rotation, Cmd→opacity), Ramer-Douglas-Peucker simplification, and ghost trail SVG overlay. * fix(studio): keyframe drag + recording bug bash 21 fixes: capture GSAP base at drag start, translate:none before gsap.set, skip reapplyPathOffsets for GSAP elements, clamp recording seek, _auto flag for 100% keyframes, overlay flash fix, block edits during recording. * feat(studio): keyframe integration wiring + docs Wire App.tsx recording orchestration, TimelineToolbar K/R buttons, PropertyPanel per-property diamonds, shortcuts panel, toast notifications, and keyframes guide documentation. All gated on STUDIO_KEYFRAMES_ENABLED (default false).
65 lines
1.5 KiB
TypeScript
65 lines
1.5 KiB
TypeScript
import { memo } from "react";
|
|
|
|
export type DiamondState = "active" | "inactive" | "ghost";
|
|
|
|
interface KeyframeDiamondProps {
|
|
state: DiamondState;
|
|
onClick: () => void;
|
|
title?: string;
|
|
size?: number;
|
|
isHold?: boolean;
|
|
}
|
|
|
|
// fallow-ignore-next-line complexity
|
|
export const KeyframeDiamond = memo(function KeyframeDiamond({
|
|
state,
|
|
onClick,
|
|
title,
|
|
size = 10,
|
|
isHold = false,
|
|
}: KeyframeDiamondProps) {
|
|
const isFilled = state === "active";
|
|
const opacity = state === "ghost" ? 0.25 : state === "inactive" ? 0.6 : 1;
|
|
const color = state === "active" ? "#3CE6AC" : "#a3a3a3";
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onClick();
|
|
}}
|
|
className="flex-shrink-0 p-0.5 transition-opacity hover:opacity-100"
|
|
style={{ color, opacity }}
|
|
title={title}
|
|
>
|
|
<svg width={size} height={size} viewBox="0 0 10 10">
|
|
{isHold ? (
|
|
<rect
|
|
x="2"
|
|
y="2"
|
|
width="6"
|
|
height="6"
|
|
rx="0.5"
|
|
fill={isFilled ? "currentColor" : "none"}
|
|
stroke="currentColor"
|
|
strokeWidth="1.2"
|
|
/>
|
|
) : (
|
|
<rect
|
|
x="5"
|
|
y="0.7"
|
|
width="6"
|
|
height="6"
|
|
rx="1"
|
|
transform="rotate(45 5 0.7)"
|
|
fill={isFilled ? "currentColor" : "none"}
|
|
stroke="currentColor"
|
|
strokeWidth="1.2"
|
|
/>
|
|
)}
|
|
</svg>
|
|
</button>
|
|
);
|
|
});
|