Skip to content

fix(plugin-bezier): use bezier-easing 3.2 closed-form solver - #616

Open
gre wants to merge 1 commit into
pmndrs:mainfrom
gre:bezier-easing-3
Open

gre wants to merge 1 commit into
pmndrs:mainfrom
gre:bezier-easing-3

Conversation

@gre

@gre gre commented Oct 8, 2026 •

Copy link
Copy Markdown

Hi, this is @gre, I'm the author of bezier-easing, which is also embedded in this project (packages/plugin-bezier/src/bezier-utils.ts). The library was recently improved with better performance and more reliability, and I wanted to backport the benefits here.

This brings its 3.2 solver (closed-form, no sample table) to evaluate:

  • Fixes steep curves. For (1, 0, 0, 1), evaluate(0.4996) returned 0.348 instead of 0.431, and the value went backwards around the middle.
  • Exact. Error goes from up to ~1e-3 to ~1e-14 on regular curves.
  • Faster and smaller. No table is built when a curve is created, and the file goes from 566 to 468 bytes min+gz.
  • x outside [0, 1] now saturates to 0 / 1. The old search returned arbitrary values there.

Includes a patch changeset for @leva-ui/plugin-bezier. Compared against bezier-easing 3.2 on ~7.6M values: bit-identical. prettier is clean, and tsc reports no new errors.

download

Summary by CodeRabbit

  • Bug Fixes
    • Improved Bézier curve evaluation, including on steep curves, to prevent backward jumps.
    • Inputs at or beyond the curve’s endpoints now return the corresponding endpoint values.

Replace the sample table + Newton-Raphson + bisection search with the
closed-form solver of bezier-easing 3.2: exact (~1e-14 instead of up to
~1e-3), no backward jump on steep curves such as (1, 0, 0, 1).

x outside [0, 1] now saturates to 0 / 1 instead of going through the
old search, which returned arbitrary values there.
@changeset-bot

changeset-bot Bot commented Oct 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: abebcc2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@leva-ui/plugin-bezier Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0e49392f-228f-46cf-9e3b-0f44bb90dd47
📥 Commits

Reviewing files that changed from the base of the PR and between 402a1e9 and abebcc2.

📒 Files selected for processing (2)
  • .changeset/bezier-easing-solver.md
  • packages/plugin-bezier/src/bezier-utils.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The Bézier easing function replaces its sampled-table and iterative solver with a cubic solver. It clamps inputs at the endpoints and evaluates the y polynomial for interior inputs. A patch changeset records the update.

Changes

Bézier easing evaluation

Layer / File(s) Summary
Cubic Bézier evaluation
packages/plugin-bezier/src/bezier-utils.ts, .changeset/bezier-easing-solver.md
The solver computes cubic coefficients, selects a real root, and caps the parameter at 1. The easing function returns 0 for inputs at or below 0, returns 1 for inputs at or above 1, and evaluates the y polynomial for interior inputs. The changeset records the solver update.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to abebc

The Bézier evaluation change appears ready to merge after normal checks; no material issue remains identified.

Architecture Summary

Architecture risk: 🟡 Medium · up to abebc

The change affects 1 system.

Changed systems: packages/plugin-bezier

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/plugin-bezier (library) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/plugin-bezier/src/bezier-utils.ts: The file replaces the prior constants and helpers for sampling, Newton iteration, and binary subdivision with solveTForX, which computes a cubic root using Cardano’s method for one-real-root cases or selects the largest real root for three-real-root cases, then caps the solved parameter at 1.
  • observed — Modified behavior in packages/plugin-bezier/src/bezier-utils.ts: bezier now computes x- and y-polynomial coefficients directly instead of building a sample table and selecting among Newton iteration, binary subdivision, or a zero-slope estimate. Its returned easing function now maps x <= 0 to 0 and x >= 1 to 1, then solves for t and evaluates the y polynomial for interior inputs.
  • observed — Modified behavior in .changeset/bezier-easing-solver.md: Adds a patch changeset for @leva-ui/plugin-bezier with a description of the Bézier evaluation change.

Reliability and maintainability

  • inferred — Risk-relevant change factors for packages/plugin-bezier: blast_radius_1; direct_dependents_1
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: replacing the plugin's solver with the bezier-easing 3.2 closed-form solver.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant