# Splitting a cubic Bézier curve

In this post, I thought I'd go over how to split Bézier curves into an arbitrary number of smaller Bézier curves. Before diving into the nitty gritty, let's take a step back for a little context:

Let's write a very simple button component where we have a background animation.

There's a very straight-forward hover animation, with a pseudo element that has a `transform: translateX();`

applied on hover.
There's also a simple `ease-out`

applied to the `transition`

so it's nice a smooth.

Unfortunately, things quickly break when you have two or more lines:

The first CSS property that came to mind was `box-decoration-break: clone;`

. Unfortunately I needed the display element to be a `block`

, or an `inline-block`

.
So this wouldn't work.

The next solution was to split the button's text into smaller elements and to apply multiple `transition-delay`

to each, to stagger the animation –
it's also worth noting that the `transition-delay`

needs to be applied inversely to `element:hover {}`

so the first element animates last when you hover out. (*note*: I've used `cubic-bezier(0,0,0,1)`

to highlihght the issue)

As you can see, because the ease is applied on a per-element basis, the momentum of the animation is lost.

Below is a visual representation of how the ease is currently applied (in red), versus how we'd want to have it applied (in blue).

This brings me to the topic at hand: splitting Bézier curves. We want to find a `transition-timing-function`

to be applied to each element, such that the overall animation respects the easing.

Below, we have a quadratic Bézier curve: two points where the line starts/end and two control points that dictates the curvature of the curve (control points).

Here's the quadratic Bézier curve function that returns the point of the curve at `t`

(where `t ∈ {0, 1}`

) given the four points `p0, p1, p2, p3`

:

```
function CubicBezierCurve(t, p0, p1, p2, p3) {
return (1 - t)³ * p0 + 3 * (1 - t)² * t * p1 + 3 * (1 - t) * t² * p2 + t³ * p3
}
```

Unfortunately, we cannot solely rely on this formula as it only gives us the point on the curve at a given `t`

, without its two control points.

Luckily, there is a simple recursive approximate algorithm called `de Casteljau's algorithm`

, which allows you to split a curve into two distinct Bézier curves at any given `t`

.

Here's the geometric representation of the algorithm:

`t = 0.1`

`Actual x-position ≅ 0`

We're almost there. Given the text will vary in length, we'll need to split the Bézier curve on the y-axis. And here's the tricky part: how to find all the intersecting points between the line and the Bézier curve? Luckily, the heavy lifting was already done here

Below we have our tweaked component which has the `transition-timing-function`

, `transition-delay`

etc, tweaked and applied on a per element basis.
The red line is a pseudo element on the button, with the same `transition-timing-function: cubic-bezier(0,0,0,1);`