motiondivision / motiondivision/motion

SVG clipPath/filter share the WAAPI zero-duration desync #3781 just fixed for opacity/transform

Open Beginner friendly
#3,790 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
33.7k
Forks
1.4k
Avg merge
1d 10h
Merged PRs (30d)
14

Description

#3781 fixed the WAAPI/instant-write channel mismatch for opacity and transform on SVG elements by adding both to cssStyleProperties in build-attrs.ts, so they get written through style instead of as raw SVG attributes. clipPath and filter are in the same boat and are still missing from that list.

acceleratedValues (packages/motion-dom/src/animation/waapi/utils/accelerated-values.ts) is:

export const acceleratedValues = new Set<string>([
    "opacity",
    "clipPath",
    "filter",
    "transform",
    "backgroundColor",
])

cssStyleProperties (packages/motion-dom/src/render/svg/utils/build-attrs.ts, post-#3781) is:

export const cssStyleProperties = [
    "transform",
    "opacity",
    "offsetDistance",
    "offsetPath",
    "offsetRotate",
    "offsetAnchor",
]

clipPath and filter are WAAPI-eligible but aren't in cssStyleProperties, so on an SVG element they still fall through to being written as plain SVG attributes (setAttribute('clip-path', ...) / setAttribute('filter', ...)) whenever Motion writes an instant/final value. WAAPI-driven animations, on the other hand, always operate on the element's CSS style/Web Animations timeline, never on attributes. That's exactly the split #3781's PR description describes for opacity: "WAAPI completion and instant JS updates write to the same channel" only holds for the four properties actually in the list.

Repro, same shape as #3781's own regression test but with clipPath:

<svg width={200} height={200}>
  <motion.circle
    id="target"
    cx={50} cy={50} r={40}
    animate={{ clipPath: hidden ? "circle(0%)" : "circle(50%)" }}
    initial={false}
    transition={
      hidden
        ? { duration: 0.3 }
        : { duration: 0.3, clipPath: { duration: 0 } }
    }
  />
</svg>

Toggling hidden back and forth should leave a WAAPI-completed zero-duration clipPath restore stale on the attribute while the CSS-driven animation channel has already moved on, the same "stuck at the mid-animation value" symptom #3781 fixed for opacity, reproducible with the exact same toggle-twice pattern as the waapi-svg-zero-duration Cypress spec added there.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing packages/motion-dom/src/render/svg/utils/build-attrs.ts with packages/motion-dom/src/animation/waapi/utils/accelerated-values.ts, then inspect the waapi-svg-zero-duration Cypress spec added for #3781. Reproduce the clipPath toggle-twice case and extend the regression coverage so zero-duration WAAPI completion and instant updates remain synchronized.

Written by the indexing model from the issue text.

Assessment

Tech stack
cypress, react, typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.