Migrate Group Transforms to a Hierarchical Scene Graph
Buget: $180.0
FIXED /
⭐ 4.98 (31)
GBR
typescript
Mazera is an animation editor. Designs are imported (often from Figma), converted into a hierarchical scene graph (parent/child tree with transforms on each node), and that tree feeds node context, which knows what a group is, who its members are, and what bounds to use. Group transform playback works today, but through a legacy bridge, not through the hierarchy the way a proper scene graph should. This is production playback logic; regressions show up immediately for users.
What we want
A standard hierarchical transform model: each node has a transform in its parent's space; world/canvas pose is built by composing transforms up the ancestor chain. Animate a container once; children inherit through transform composition. Nested groups, rotate/scale/move on parent or child, and sequences like "rotate the whole frame, then scale one inner group" should compose naturally.
Figma uses parent-local transforms on a scene graph, which is a useful reference, but the target is a general model that scales to any import source and any nesting depth, not a Figma clone.
Goal: one source of truth for transforms. Parent and child transforms compose through the hierarchy rather than being reapplied in a post-processing step.
Success: nested child rotate, top-level group rotate, and parent rotate followed by child scale all work together, not one at the expense of the others.
Scope includes container-targeted Custom Rotate, Custom Scale, Custom Move, and Custom Resize clips.
What we have today
Import (app/imports/figma-payload/) builds the design hierarchy (containers, leaves, bounds, rotation).
Node system (app/node-system/) stores the tree and DesignNode.transform.
Node context (app/animation-engine/input/node-context/) is structural metadata only: membership, union bounds, group proxy. It should not become the long-term home for transform math.
Group expansion (app/animation-engine/input/group-expansion.ts) expands a container animation into per-member animations, so the engine keeps treating transforms as leaf-level work.
Group config (app/animation-engine/pipeline/group-config/) splits primary vs secondary group motion and upgrades baselines for nested clips.
Group transform (app/animation-engine/pipeline/group-transform/) runs a post-pass after per-item interpolation: computes deltas from design, moves each member inside group bounds, then writes canvas x/y/scale/rotation.
Orchestrator (app/animation-engine/pipeline/orchestrator.ts) ties playhead time to SceneState and canvas apply.
That pipeline works, but it is not a single source of truth. It relies on clip expansion, transform post-passes, and special handling for nested groups. A previous migration toward storing parent-local transforms on the scene graph was attempted and rolled back after introducing regressions.
Regressions encountered during previous migration attempts
These regressions traded places throughout the migration. They were symptoms of two transform systems running simultaneously, not isolated bugs.
Rotate a nested child group: the group orbited around the parent pivot ("clock" motion) instead of rotating in place; inner leaves drifted inside the child.
Rotate the top-level group: nested child groups collapsed or vanished at animation start.
Rotate the parent, then scale a child group: the child snapped back to its design position, detached from the parent's rotation; scale appeared absent or incorrect.
Fix rotate, then use hierarchy composition for members: pivot and leaf placement broke again because matrix output no longer matched how the renderer applied group motion.
Fix nested transforms, then reintroduce the legacy post-pass per container: parent motion worked until a child container animated; the child pass overwrote the parent's motion using the raw design baseline.
The cycle became: rotate works, nested composition works, scale-after-rotate works, but never all three at the same time while the legacy and hierarchical paths were both updating the same leaves.
Your job
Understand the current pipeline end to end, then migrate group transform playback to parent-local hierarchical composition. Propose the migration plan and phases, including how you will verify behavior stays correct before removing legacy paths. The shipped app must continue working for real imports and real animation sequences throughout the migration.
Key entry points include the files above, plus:
app/animation-engine/pipeline/item-state-at-time.ts
app/animation-engine/pipeline/design-baseline/
app/animation-engine/output-applier/
These determine how animated state is produced and ultimately reaches the canvas.
Good fit if you have implemented scene graphs, graphics editors, game engine transforms, CAD tools, or design-tool transform systems; can reason about rest pose, local animation, world composition, and canvas application as one continuous contract; and can explain how you would retire clip expansion and transform post-passes without reintroducing the regressions described above.
Please submit your GitHub username so that I can invite you to the codebase. I need you to first take a look at the architecture, apply some animations Figma Imported Designs, and then if you are confident/comfortable proceeding after you take a first look, I can start the contract immediately today itself. This helps us both save time because this is a migration towards a better graph model.
I'll let you know the relevant files after you send me your GitHub username.
thanks
Deschide pe Upwork