Free, local and no login

Visual cubic-bezier editor

Stop trial-and-error tuning of CSS easing values. Drag bezier handles, preview the movement in context and export the exact cubic-bezier timing function.

Create an animation

The curve editor

Nothing to install and nothing to open — this is the editor from the studio.

Drag the handles, or start from a preset. The dot replays the motion on every change, so you are judging the movement rather than the numbers.

timing function
animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);

Paste it onto any animation or transition.

Try it right here

A working example with the exact code it produces. Copy it, or open it in the editor and change anything.

animation.css
.elastic-in {
  transform: translate3d(180px, 100px, 0);
  width: 120px;
  height: 120px;
  background: #6366f1;
  border-radius: 20px;
  animation: elastic-in-anim 1000ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes elastic-in-anim {
  0% {
    transform: translate3d(180px, 100px, 0) scale(0.2, 0.2);
    opacity: 0;
    animation-timing-function: ease-out;
  }
  2.5% {
    transform: translate3d(180px, 100px, 0) scale(0.417, 0.417);
    opacity: 0.161;
  }
  5% {
    transform: translate3d(180px, 100px, 0) scale(0.717, 0.717);
    opacity: 0.308;
  }
  7.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 0.445;
  }
  10% {
    transform: translate3d(180px, 100px, 0) scale(1.2, 1.2);
    opacity: 0.571;
  }
  12.5% {
    transform: translate3d(180px, 100px, 0) scale(1.291, 1.291);
    opacity: 0.685;
  }
  15% {
    transform: translate3d(180px, 100px, 0) scale(1.283, 1.283);
    opacity: 0.785;
  }
  17.5% {
    transform: translate3d(180px, 100px, 0) scale(1.206, 1.206);
    opacity: 0.87;
  }
  20% {
    transform: translate3d(180px, 100px, 0) scale(1.1, 1.1);
    opacity: 0.938;
  }
  22.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 0.983;
  }
  25% {
    transform: translate3d(180px, 100px, 0) scale(0.929, 0.929);
    opacity: 1;
  }
  27.5% {
    transform: translate3d(180px, 100px, 0) scale(0.897, 0.897);
    opacity: 1;
  }
  30% {
    transform: translate3d(180px, 100px, 0) scale(0.9, 0.9);
    opacity: 1;
  }
  32.5% {
    transform: translate3d(180px, 100px, 0) scale(0.927, 0.927);
    opacity: 1;
  }
  35% {
    transform: translate3d(180px, 100px, 0) scale(0.965, 0.965);
    opacity: 1;
  }
  37.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
  40% {
    transform: translate3d(180px, 100px, 0) scale(1.025, 1.025);
    opacity: 1;
  }
  42.5% {
    transform: translate3d(180px, 100px, 0) scale(1.036, 1.036);
    opacity: 1;
  }
  45% {
    transform: translate3d(180px, 100px, 0) scale(1.035, 1.035);
    opacity: 1;
  }
  47.5% {
    transform: translate3d(180px, 100px, 0) scale(1.026, 1.026);
    opacity: 1;
  }
  50% {
    transform: translate3d(180px, 100px, 0) scale(1.012, 1.012);
    opacity: 1;
  }
  52.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
  55% {
    transform: translate3d(180px, 100px, 0) scale(0.991, 0.991);
    opacity: 1;
  }
  57.5% {
    transform: translate3d(180px, 100px, 0) scale(0.987, 0.987);
    opacity: 1;
  }
  60% {
    transform: translate3d(180px, 100px, 0) scale(0.988, 0.988);
    opacity: 1;
  }
  62.5% {
    transform: translate3d(180px, 100px, 0) scale(0.991, 0.991);
    opacity: 1;
  }
  65% {
    transform: translate3d(180px, 100px, 0) scale(0.996, 0.996);
    opacity: 1;
  }
  67.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
  70% {
    transform: translate3d(180px, 100px, 0) scale(1.003, 1.003);
    opacity: 1;
  }
  72.5% {
    transform: translate3d(180px, 100px, 0) scale(1.005, 1.005);
    opacity: 1;
  }
  75% {
    transform: translate3d(180px, 100px, 0) scale(1.004, 1.004);
    opacity: 1;
  }
  77.5% {
    transform: translate3d(180px, 100px, 0) scale(1.003, 1.003);
    opacity: 1;
  }
  80% {
    transform: translate3d(180px, 100px, 0) scale(1.002, 1.002);
    opacity: 1;
  }
  82.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
  85% {
    transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
    opacity: 1;
  }
  87.5% {
    transform: translate3d(180px, 100px, 0) scale(0.998, 0.998);
    opacity: 1;
  }
  90% {
    transform: translate3d(180px, 100px, 0) scale(0.998, 0.998);
    opacity: 1;
  }
  92.5% {
    transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
    opacity: 1;
  }
  95% {
    transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
    opacity: 1;
  }
  97.5% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(180px, 100px, 0);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .elastic-in {
    animation: none;
    transition: none;
  }
}

Why it is built this way

Same principle as the bounce: the oscillation is baked into keyframes rather than expressed as an easing function. Use it sparingly — elastic motion draws a lot of attention, which is the point once per screen and a nuisance twice.

More ready-made animations

Browse all animations →

Bounce In Animation

An element that drops in and bounces to a stop — in pure CSS.

Zoom In Animation

A clean scale-up entrance with a slight overshoot.

Changes saved

Supporting copy goes here.

Toast Notification Slide In

A toast that slides in from the right with a soft overshoot.

What you can do

Create custom CSS timing functions visually

Compare smooth, sharp and expressive motion curves

Use easing consistently across a complete animation

How it works

  1. 01

    Open the curve editor in MotionCraft.

  2. 02

    Drag the bezier control points while previewing motion.

  3. 03

    Copy the cubic-bezier value or export the full animation.

Frequently asked questions

What is cubic-bezier in CSS?

It is a CSS timing function that controls how an animation accelerates and decelerates between keyframes.

Can I use spring-like motion?

Yes. MotionCraft can sample spring and bounce motion into CSS keyframes when a single timing function is not enough.

Open MotionCraft