Skip to content

motion.div layout animation: layout prop (FLIP from the last painted rect) and shared layoutId #409

Description

@Ernxst

Request

Two props on motion.div, matching the motion package's API so the web build maps onto it through the existing conditional import and the same component tree animates identically on both renderers:

  • layout: when the node's own rect changes because of layout (content re-fit, sibling insertion, reflow), animate position and size from the last painted rect to the new one. FLIP over the layout engine's result: the layout runs to completion, the node is painted with a transform and size offset that starts at the old rect and eases to zero.
  • layoutId: a node unmounting in one place and mounting elsewhere with the same id animates between the two rects (the moving highlight behind an active tab).

Why

A dock with an auto-sized pill around a nav whose active label changes, and a highlight that moves to the active tile, currently measures every rect with getBoundingClientRect after commit, keeps the numbers in React state, and animates numeric widths and positions, on both platforms. With layout and layoutId the component declares intent and deletes the measurement. #408 (auto-size width tween) is the width-only special case and would still leave the web build measuring, since CSS cannot animate auto to auto; this request replaces it.

Scope notes

  • Rust owns the interpolation like the existing motion.div target animations: React sends the props once, the renderer tracks the last painted rect per node (and per layoutId) and requests frames until settled.
  • transition applies as it does for target animations; springs included.
  • Reduced Motion follows the existing motion.div behavior.
  • First paint of a node is not animated; a layoutId match on mount is.
  • Scale-vs-resize semantics for children need a decision (the motion package defaults to scale correction on the parent and offers layout="position" / "size"); the minimum useful subset is layout (position + size) and layoutId.

Reported from a downstream app; subsumes #408.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlayer:nativeRust and N-API native bindinglayer:reactReact package and reconciler

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions