Bezier Curve Editor & Easing Function Visualizer – CSS, Unity, C++, JS

Interactive cubic Bezier curve editor with real-time animation preview, 35 easing presets, side-by-side comparison, and code export for CSS, Unity C#, C++, and JavaScript.
Drag ● P1 and ● P2 to reshape the curve

Control Points

P1
P2
CSS Output
cubic-bezier()
cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000)
transition
transition: all 1000ms cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000);
Click either line to copy

Animation Preview

1.0 s

Export Code

Click to copy
/* CSS transition */
transition: all 1000ms cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000);

/* timing-function only */
transition-timing-function: cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000);

/* CSS animation */
animation-timing-function: cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000);

What Is a Cubic Bezier Curve Editor?

A cubic Bezier curve editor is an interactive tool for designing easing functions — the timing curves that control how an animated value changes over time. This free online editor lets you drag two control handles (P1 and P2) directly on a canvas, preview the resulting motion with a real-time animation, copy cubic-bezier() and CSS transition code with one click from the live CSS Output panel, and export ready-to-paste code for CSS, Unity C#, Unreal Engine C++, GSAP, and Anime.js.

Easing functions are used everywhere animated motion appears: UI transitions in web apps, character animations in games, camera movements in film, industrial robot motion profiles, and simulation physics. A poorly chosen easing makes motion feel mechanical or jarring; a well-designed Bezier curve makes it feel natural, responsive, and polished.

This tool runs entirely in your browser using WebAssembly (Rust compiled to WASM). No data leaves your machine — all curve computation, Newton-Raphson solving, and code generation happen locally.

Cubic Bezier Curve — Mathematics and CSS Mapping

A cubic Bezier curve is a parametric polynomial of degree 3 defined by four control points. The general form is:

General Bezier formula:

B(t) = (1−t)³·P0 + 3(1−t)²t·P1 + 3(1−t)t²·P2 + t³·P3, t ∈ [0, 1]

In the CSS cubic-bezier() timing function:

  • P0 = (0, 0) — fixed start anchor (t=0, progress=0)
  • P3 = (1, 1) — fixed end anchor (t=1, progress=1)
  • P1 = (x1, y1) — first adjustable control point (orange handle)
  • P2 = (x2, y2) — second adjustable control point (red handle)

The x-axis represents animation time (0 = start, 1 = end); the y-axis represents the animated property's progress. The curve maps time → progress.

The t-to-x Problem and Newton-Raphson Solving

In CSS, the browser needs to answer: given a time fraction x, what is the progress y? But the Bezier parameter t is not the same as x — B(t).x = x must be solved for t first, then y = B(t).y. This tool uses 8-iteration Newton-Raphson to find t, which is exactly how V8 (Chrome), SpiderMonkey (Firefox), and WebKit (Safari) implement cubic-bezier().

Newton-Raphson iteration (x → t):

t_{n+1} = t_n − (B_x(t_n) − x) / B_x′(t_n)

where B_x(t) = 3(1−t)²t·x1 + 3(1−t)t²·x2 + t³ and B_x′(t) = its derivative.

Y-Value Overshoot

The CSS spec requires P1.x and P2.x to remain in [0, 1] to keep the time mapping monotonic. However, P1.y and P2.y are unrestricted — values outside [0, 1] create overshoot, where the animated property temporarily exceeds its target (Back easing) or oscillates (Elastic easing). This tool allows full Y drag beyond the graph box boundary for these effects.

CSS Easing Functions — cubic-bezier() Reference

The CSS transition-timing-function and animation-timing-function properties accept cubic-bezier(x1, y1, x2, y2) directly. The five CSS keywords are Bezier shorthands:

CSS Keywordcubic-bezier() equivalentCharacter
linearcubic-bezier(0, 0, 1, 1)Constant speed
easecubic-bezier(0.25, 0.1, 0.25, 1)Fast start, gentle deceleration (default)
ease-incubic-bezier(0.42, 0, 1, 1)Slow start, accelerates to end
ease-outcubic-bezier(0, 0, 0.58, 1)Fast start, decelerates to end
ease-in-outcubic-bezier(0.42, 0, 0.58, 1)Slow at both ends, fast in middle

How to Use cubic-bezier() in CSS

Transition timing:

transition: transform 400ms cubic-bezier(0.34, 1.56, 0.64, 1);

Animation timing:

animation: slide 600ms cubic-bezier(0.16, 1, 0.3, 1) forwards;

CSS custom property (reusable):

--ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
transition: transform 400ms var(--ease-spring);

Live CSS Output — One-Click cubic-bezier() & transition Copy

The Bezier Editor includes a CSS Output block directly under the Control Points panel — no tab switching required. As you drag P1/P2, type coordinates, or apply a preset, two lines update in real time:

  • cubic-bezier() — the timing-function value only, e.g. cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000)
  • transition — a complete declaration using your Animation Preview duration, e.g. transition: all 1000ms cubic-bezier(0.2500, 0.1000, 0.2500, 1.0000);

Click either line to copy it to the clipboard. Change the Duration slider in Animation Preview to update the milliseconds in the transition line. Use the copied transition line directly in a stylesheet, or paste the cubic-bezier() value into transition-timing-function, animation-timing-function, or a CSS custom property.

Typical workflow:

  1. Shape the curve on the canvas or pick an Easing Preset.
  2. Set Duration to match your UI animation (e.g. 400 ms for a button hover).
  3. Click the transition line in CSS Output and paste into your CSS file.

Easing Preset Families — 35 Named Curves

The Easing Presets tab organises 35 curves into 9 mathematical families. Each family has Ease In (accelerates), Ease Out (decelerates), and Ease In-Out (symmetric) variants. Click any card to apply it immediately to the editor.

FamilyEase InEase OutEase In-OutCharacter
Sine0.12, 0.00, 0.39, 0.000.61, 1.00, 0.88, 1.000.37, 0.00, 0.63, 1.00Gentle sinusoidal — subtle, natural
Quad0.11, 0.00, 0.50, 0.000.50, 1.00, 0.89, 1.000.45, 0.00, 0.55, 1.00Quadratic — smooth UI transitions
Cubic0.32, 0.00, 0.67, 0.000.33, 1.00, 0.68, 1.000.65, 0.00, 0.35, 1.00Cubic — pronounced but smooth
Quart0.50, 0.00, 0.75, 0.000.25, 1.00, 0.50, 1.000.76, 0.00, 0.24, 1.00Quartic — snappy with strong contrast
Expo0.70, 0.00, 0.84, 0.000.16, 1.00, 0.30, 1.000.87, 0.00, 0.13, 1.00Exponential — dramatic, high-contrast
Circ0.55, 0.00, 1.00, 0.450.00, 0.55, 0.45, 1.000.85, 0.00, 0.15, 1.00Circular — sharp change near endpoints
Back0.36, 0.00, 0.66,-0.560.34, 1.56, 0.64, 1.000.68,-0.60, 0.32, 1.60Overshoot — spring-like anticipation
Elastic0.50, 0.00, 0.75,-0.500.25, 1.50, 0.50, 1.000.68,-0.55, 0.27, 1.55Elastic oscillation — rubber-band feel
Bounce0.30, 0.00, 0.70, 0.000.30, 1.00, 0.70, 1.000.50, 0.00, 0.50, 1.00Bounce approximation — ball impact

Which Easing Should I Use?

  • Entering UI elements (slide in, fade in): Ease Out (Cubic or Expo) — starts fast, settles smoothly
  • Exiting UI elements (slide out, fade out): Ease In (Cubic or Expo) — starts gentle, exits cleanly
  • Continuous / looping animations: Ease In-Out (Sine or Quad) — symmetric, no jarring ends
  • Button press / click feedback: Back Out or Elastic Out — spring overshoot feels responsive
  • Object landing / impact: Bounce Out — simulates physical collision
  • Loading spinners, morphing shapes: Linear — constant speed avoids visual rhythm disruption
  • Game UI popups: Back In-Out — anticipation before movement, settle with overshoot
  • Drag-and-drop drop feedback: Elastic Out — communicates successful drop with spring

Export Targets — CSS, Unity, C++, JavaScript

CSS — transition-timing-function and animation-timing-function

The live CSS Output panel under Control Points shows the cubic-bezier() value and a full transition declaration — click either line to copy. The Export Code → CSS tab provides additional snippets including transition-timing-function and animation-timing-function variants:

/* Live CSS Output (one-click copy) */
transition: all 1000ms cubic-bezier(0.34, 1.56, 0.64, 1);

/* Export Code — animation timing */
animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);

Unity C# — AnimationCurve and DOTween

Unity's AnimationCurve uses Hermite spline tangents. The export approximates the Bezier curve by deriving in/out tangents from P1.y and P2.y, compatible with both the built-in Animator and DOTween's SetEase(AnimationCurve).

AnimationCurve curve = new AnimationCurve(
new Keyframe(0f, 0f, 0f, 3f * p1y),
new Keyframe(1f, 1f, 3f * (1f - p2y), 0f)
);

// DOTween
transform.DOMove(target, 1f).SetEase(curve);

// Animator override
animator.SetFloat("SpeedMultiplier", curve.Evaluate(t));

JavaScript — GSAP and Anime.js

GSAP accepts CSS cubic-bezier strings directly as the ease value. Anime.js uses a dedicated cubicBezier() helper.

// GSAP 3
gsap.to(el, { duration: 0.6, ease: 'cubic-bezier(0.34,1.56,0.64,1)' });

// Anime.js
anime({ targets: el, translateX: 250, easing: 'cubicBezier(0.34,1.56,0.64,1)' });

// Web Animations API
el.animate([{ transform: 'translateX(0)' }, { transform: 'translateX(250px)' }],
{ duration: 600, easing: 'cubic-bezier(0.34,1.56,0.64,1)' });

C++ — Unreal Engine and Custom Engines

The C++ export provides a self-contained evaluation function with no dependencies. For Unreal Engine, wrap in a UCurveFloat or call directly in a Tick() function:

float CubicBezierEase(float t, float p1x, float p1y, float p2x, float p2y) {
// Solve for Bezier t parameter given x using Newton-Raphson
float bt = t;
for (int i = 0; i < 8; ++i) {
float x = 3*(1-bt)*(1-bt)*bt*p1x + 3*(1-bt)*bt*bt*p2x + bt*bt*bt - t;
float dx = 3*(1-bt)*(1-3*bt)*p1x + 3*bt*(2-3*bt)*p2x + 3*bt*bt;
bt -= x / dx;
}
float u = 1.0f - bt;
return 3*u*u*bt*p1y + 3*u*bt*bt*p2y + bt*bt*bt;
}

How to Use This Bezier Curve Editor

  1. Drag P1 / P2 on the canvas: Click the orange (P1) or red (P2) handle and drag. P1 and P2 X values are clamped to [0, 1] automatically; Y values can go beyond the box boundary for overshoot effects. The curve, arms, and cubic-bezier() output update instantly.
  2. Type exact coordinates: Use the X / Y number inputs to enter precise values. The input accepts any float — type freely, the canvas updates when the value is valid. Useful for reproducing a specific preset or protocol-specified timing.
  3. Preview the animation: Click Play to see a ball animate from (0,0) to (1,1) along the curve. The progress bar at the bottom of the canvas tracks time (x-axis). The ball's height shows how the easing feels — overshoot is clearly visible for Back and Elastic curves.
  4. Apply a preset: Switch to the Easing Presets tab and click any card. The editor immediately applies that curve's P1 and P2 values and switches back to the Editor tab. Use this as a starting point before fine-tuning.
  5. Compare multiple curves: Click + Save in the Animation Preview section to snapshot the current curve. Switch to the Compare tab to see all saved curves overlaid on the same canvas — useful for deciding between similar easings (e.g., Back Out vs Elastic Out).
  6. Copy CSS output: Under Control Points, use the CSS Output block: click the cubic-bezier() line to copy the easing value, or click the transition line for a ready-to-paste declaration. Both update instantly when P1, P2, or the Duration slider changes.
  7. Copy extended export code: In the Export Code section, select the target (CSS / Unity C# / C++ / JS), then click the code block to copy longer snippets for animation-timing-function, Unity, or JavaScript libraries.

Frequently Asked Questions — Bezier Curve Editor

What is a cubic Bezier curve?

A cubic Bezier curve is a parametric polynomial of degree 3 defined by four control points: P0 (start), P1 (first tangent handle), P2 (second tangent handle), and P3 (end). The curve passes through P0 and P3, and is attracted toward — but does not pass through — P1 and P2. In CSS cubic-bezier(), P0 is fixed at (0, 0) and P3 at (1, 1), so you specify only P1 and P2.

How do I use cubic-bezier() in CSS?

The CSS Output panel under Control Points shows both values live — click to copy. For transition-timing-function or animation-timing-function only, use the cubic-bezier() line; for a full property shorthand, use the transition line.

transition: opacity 300ms cubic-bezier(0.25, 0.1, 0.25, 1.0);
animation-timing-function: cubic-bezier(0.42, 0, 0.58, 1);

The Export Code → CSS tab adds animation-timing-function and related comments for larger paste blocks.

What is the difference between ease, ease-in, ease-out, and ease-in-out?

All four are shorthand keywords for specific cubic-bezier values:

  • ease = cubic-bezier(0.25, 0.1, 0.25, 1.0) — fast start, gentle deceleration (CSS default)
  • ease-in = cubic-bezier(0.42, 0, 1, 1) — slow start, accelerates to end — use for exit transitions
  • ease-out = cubic-bezier(0, 0, 0.58, 1) — fast start, decelerates — use for enter transitions
  • ease-in-out = cubic-bezier(0.42, 0, 0.58, 1) — slow at both ends — use for looping or cross-fades

Can control point Y values go outside the 0–1 range?

Yes — and intentionally. The CSS spec requires P1.x and P2.x to stay in [0, 1] to ensure the time mapping is monotonic (otherwise a single time value could map to multiple progress values). But P1.y and P2.y are unrestricted. Values above 1 or below 0 create overshoot — the animated property temporarily exceeds its start or end value. This is what gives Back easing its anticipation spring and Elastic easing its oscillation. This editor allows free Y drag well beyond the graph box boundary to design these curves.

How do I export a Bezier curve to Unity?

Select the Unity C# tab in the Export Code section. The tool generates an AnimationCurve with Keyframe tangents derived from P1.y and P2.y using the relation: outTangent = 3·P1.y, inTangent = 3·(1−P2.y). This is compatible with the Unity Animation window, Animator Controller, and DOTween's SetEase(AnimationCurve).

How do I use a Bezier easing curve in GSAP or Anime.js?

Select the JavaScript tab. GSAP 3 accepts CSS cubic-bezier strings directly as the ease option. Anime.js provides a cubicBezier(x1, y1, x2, y2) easing factory. The export code shows both, ready to paste:

gsap.to(el, { duration: 0.6, ease: 'cubic-bezier(0.34,1.56,0.64,1)' });
anime({ targets: el, easing: 'cubicBezier(0.34,1.56,0.64,1)' });

What is the Newton-Raphson method used for in Bezier easing?

The Bezier parameter t is not the same as animation time x. To find the progress y at a given time x, we must solve B_x(t) = x for t, then evaluate B_y(t). Newton-Raphson iteration solves this in 8 steps to machine precision, which is the same algorithm used by all major browser CSS engines. Without it, the animation preview would be inaccurate — especially for steep curves with Expo or Circ easing.

How do I copy the CSS cubic-bezier value or transition code?

Open the Bezier Editor tab and find CSS Output under Control Points. Two monospace lines update as you edit the curve: the cubic-bezier() timing function and a complete transition: all …ms …; declaration. Click either line to copy. The duration in the transition line follows the Animation Preview Duration slider — set it to match your UI before copying.

How do I compare multiple easing curves?

Configure a curve in the Bezier Editor, then click the + Save button in the Animation Preview section. Repeat for other curves. Then switch to the Compare tab — all saved curves are overlaid on the same canvas in distinct colours, alongside the current editor curve (always shown in cyan). Up to 4 curves can be saved simultaneously. Click the × icon next to any saved curve to remove it.