# 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.

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` – and `t` doesn't directly correlate to the x-axis.

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 visual representation of the algorithm (the vertical line tracks `t`):

`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 (as opposed to the x-axis which is the easing duration). And this is where it gets a bit tricky: as you can see in the graph below, if we were to split the Bézier curve on the y-axis, in three separate parts, we'd end-up with more than one intersection between the horizontal lines and the curve:

Luckily, finding the intersection of a line and a Bézier curve is solved here.

👀 Note to self: finish writing this.

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);`