webdevpuneet.com

Bezier Curve Editor — Visual cubic-bezier() Easing Tool

Bezier Curve Editor · Tools · Plain HTML, CSS & JS · Live preview

Copy & paste

Source Code

<div class="bz-card">
  <div class="bz-stage">
    <svg class="bz-svg" id="bzSvg" viewBox="0 0 200 200" aria-label="Easing curve editor">
      <line class="bz-axis" x1="0" y1="200" x2="200" y2="200"/>
      <line class="bz-axis" x1="0" y1="0" x2="0" y2="200"/>
      <line class="bz-handleline" id="bzL1" x1="0" y1="200" x2="0" y2="0"/>
      <line class="bz-handleline" id="bzL2" x1="200" y1="0" x2="200" y2="200"/>
      <path class="bz-curve" id="bzCurve" d=""/>
      <circle class="bz-pt" id="bzP1" r="8" cx="50" cy="150" tabindex="0" role="slider" aria-label="Control point 1"/>
      <circle class="bz-pt" id="bzP2" r="8" cx="150" cy="50" tabindex="0" role="slider" aria-label="Control point 2"/>
    </svg>
    <div class="bz-demo"><span class="bz-ball" id="bzBall"></span></div>
  </div>
  <code class="bz-code" id="bzCode">cubic-bezier(0.25, 0.25, 0.75, 0.75)</code>
  <div class="bz-presets" id="bzPresets">
    <button type="button" class="bz-chip" data-v="0.25,0.1,0.25,1">ease</button>
    <button type="button" class="bz-chip" data-v="0.42,0,1,1">ease-in</button>
    <button type="button" class="bz-chip" data-v="0,0,0.58,1">ease-out</button>
    <button type="button" class="bz-chip" data-v="0.34,1.56,0.64,1">overshoot</button>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Draggable control points
Two SVG handles shape the cubic-bezier curve directly.
Overshoot support
Unclamped y lets you drag past 0–1 for bouncy easings.
Live ball preview
An element animates with the current easing on every edit.
Transition restart trick
Double requestAnimationFrame re-triggers the CSS transition.
Pointer + touch
Pointer Events with document-level tracking work on mobile.
Presets
Chips load ease, ease-in, ease-out, and an overshoot curve.
Copyable output
Click the rounded cubic-bezier() string to copy it.
Keyboard accessible
Focusable slider handles adjust with arrow keys.

About this UI Snippet

Bezier Curve Editor — Drag-Handle cubic-bezier() Easing with Live Preview

Screenshot of the Bezier Curve Editor snippet rendered live

A bezier curve editor lets you shape a CSS cubic-bezier() easing by dragging two control points and watching the motion play in real time — the tool behind every "tweak the animation feel" workflow. This snippet builds a fully interactive one in SVG with draggable handles, a live ball preview, presets, and copyable output, in plain HTML, CSS, and vanilla JavaScript.

SVG curve, mapped to easing space

The editor draws a cubic Bézier path from the bottom-left (0,0) to the top-right (1,1) corner — the fixed endpoints of every CSS easing curve — with two draggable control points in between. The 200×200 SVG is mapped so x runs 0→1 left to right and y runs 0→1 bottom to top, with the conversion x/200 and (200 - y)/200. Crucially, the y axis is left unclamped so you can drag a handle above the top or below the bottom to create overshoot and anticipation curves (values outside 0–1), exactly like the bouncy cubic-bezier(0.34, 1.56, 0.64, 1).

Pointer dragging that works on touch

Handles use Pointer Events, so the same code drives mouse, trackpad, and touch. Pressing a handle attaches document-level pointermove/pointerup listeners, so the drag keeps tracking even when the cursor leaves the SVG — the detail that makes dragging feel solid. touch-action: none on the SVG stops the page scrolling while you drag on mobile.

Live preview that re-triggers

Below the curve, a ball animates left-to-right using the current easing. Every edit re-runs the animation: the script sets transition: none, resets the position, then on the next two animation frames applies the new cubic-bezier() and moves the ball — the double-rAF trick that forces the browser to restart a CSS transition. You feel the easing, not just see the curve, which is how you actually judge whether motion looks right.

Presets and copyable output

Chips load the named CSS easings (ease, ease-in, ease-out) plus an overshoot, instantly positioning the handles — a fast starting point you then fine-tune. The live cubic-bezier(…) string updates as you drag, rounded to three decimals, and clicking it copies it to the clipboard ready to paste into your CSS or a transition.

Keyboard accessible

Each handle is focusable with role="slider" and responds to arrow keys (Shift for larger steps), so the curve can be adjusted without a mouse. The whole editor is self-contained and dependency-free — a clean reference for building an easing picker into a design tool, theme editor, or animation playground.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA curve editor renders with two handles and a ball preview.
  2. 2
    Drag the handlesMove the two control points to shape the easing; drag past the top for overshoot.
  3. 3
    Watch the previewThe ball replays with the new easing on every change.
  4. 4
    Try a presetChips load ease, ease-in, ease-out, and overshoot as starting points.
  5. 5
    Copy the valueClick the cubic-bezier() string to copy it for your CSS.
  6. 6
    Use the keyboardFocus a handle and nudge it with arrow keys (Shift for bigger steps).

Real-world uses

Common Use Cases

Design system motion tokens
Author easing values used across a product, copying a ready cubic-bezier() string once the curve feels right.
Animation playgrounds
Tune curves before applying them to elements, using a live ball preview that replays with the current easing on every edit.
Theme and settings editors
Embed an easing picker in a settings panel next to a colour mode toggle, with presets for common curves.
Interaction prototyping
Feel different easings for a magnetic button or a reveal on scroll, with y values unclamped for overshoot.
Easing and SVG dragging lessons
Show how two control points map to motion, and use the pointer dragging code as a reference for SVG handles.
Related: Canvas Gravity Particle Orbits
See the Canvas Gravity Particle Orbits for a related animations pattern worth pairing with this one.
Related: Filter Icon Active-State Morph
See the Filter Icon Active-State Morph for a related animations pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The SVG is 200×200 with the curve fixed from corner (0,0) to (1,1). Each handle's position converts to easing coordinates with x/200 across and (200 − y)/200 up, then rounds to three decimals. The two resulting (x, y) pairs are the four numbers in cubic-bezier(x1, y1, x2, y2), exactly what CSS expects.

Yes — drag a handle above the top edge or below the bottom edge of the box. The y coordinate is intentionally not clamped, so control points can exceed the 0–1 range, producing easings like cubic-bezier(0.34, 1.56, 0.64, 1) that overshoot and settle. The x coordinate is clamped to 0–1 because CSS requires it.

To feel an easing you have to see the motion, so the ball re-animates whenever the curve changes. Restarting a CSS transition mid-flight requires removing the transition, forcing a reflow, then reapplying it — done here with a double requestAnimationFrame so the browser registers the reset before the new transition. That is the reliable cross-browser way to retrigger a transition.

Yes. The handles use Pointer Events, which unify mouse and touch, and the move/up listeners are attached to the document so a drag keeps tracking even if your finger leaves the SVG. touch-action: none on the SVG prevents the page from scrolling while you drag a handle on a phone.

Hold the two control points in state and render the SVG path, handles, and cubic-bezier string from them. Move the pointer drag into handlers that update state (attach window listeners in an effect and clean them up), and drive the preview by toggling an inline transition. Tailwind users replace the classes with utilities; the coordinate math and transition-restart trick are unchanged.