How to create a slick animation from Killing Eve
Tags: webdev, tutorial, javascript, css
Published: 2020-12-24 13:30:48

I thought it would be fun to recreate some of the title sequences from TV shows and movies as web animations. Title sequences now feature very creative and eye-catching sequences to open and close the production, while giving credit to those who made it!

I thought it might be a good opportunity to boost my frontend skills. 

First stop, Killing Eve.

## Killing Eve

[Killing Eve](https://en.wikipedia.org/wiki/Killing_Eve) is a British spy thriller television series, produced in the United Kingdom for BBC America and BBC Three. The series follows Eve Polastri (Sandra Oh), a British intelligence investigator tasked with capturing psychopathic assassin Villanelle (Jodie Comer).

## The opening title sequence

The title is very well crafted with beautiful typography and a subtle animation.

The title sequence was created by [Matt Wiley](https://mattwilley.co.uk/) for Pentagram. You can see [some of the design assets in Pentagram's portfolio](https://www.pentagram.com/work/killing-eve).

Below is an example from an episode.

{% vimeo 408409007 %}

For each episode, the title changes in the following ways:

- The background color and the text color is different;
- The oozing blood trail runs down a different characters (either the 'K', 'N', or 'V');
- There is a different accompanying song.

<figure>
<img src="https://www.roboleary.net/assets/img/blog/2020-12-24-title-sequences/title-sequence-variations.png" alt="variations of title sequence" width="984" height="563" loading="lazy">
<figcaption>Variations of title sequence</figcaption>
</figure>
<br/>

The song selection is excellent. Coincidentally, I saw in the titles that there is a _Song Co-ordinator_ who must do this! I found myself searching for some of the featured music after watching a few different episodes!

What I want to do is to create a montage of the different variations. Every few seconds, it will randomly pick generate the title sequence. The colors, the oozing blood trail, and the song will be chosen at random each time.

## TLDR

Here is the completed animation.

{% codepen https://codepen.io/robjoeol/pen/gOwGojN %}

Give it a ❤️ on Codepen if you like it! 😊

## Design Decisions

Ideally, we would use the original typeface, but fancy typefaces tend to carry a pricetag. 🤑 This is just for fun, so I'm only looking at free options. If we get lucky and can use the original typeface for free, then we would have more options to create it whatever way we like.

It looks like the [typeface](https://mattwilley.co.uk/Killing-Eve) was custom-made by Matt Wiley for the TV show. It doesn't appear to be published. So, we definitely need to search for free alternative.

The closest match I could find is [Deutschlander](https://www.dafont.com/deutschlander.font). It would need to be edited in a few ways to match the original typeface. We need to make a SVG (Scalable Vector Graphic) to be able to do this. What we can do is convert the title text to a SVG `path`, and then we can edit it whatever we want to.

SVG is desirable for this type of animation generally because it is scalable, we know everything will look good on different screen sizes without any extra work. Text can be a bit tricky to work with animations, if you want to scale it or move forward/backwards, then you can get some undesirable results.

If you're not familiar with converting text to a path, you can do it in [Inkscape](https://inkscape.org/) by selecting the text instance, and selecting "Object to Path" (as below). You can do the same in most vector graphics tools.

![convert text to path](https://dev-to-uploads.s3.amazonaws.com/i/js56m0qatgq18gr08u20.png)

When I typed out the text "KILLING EVE", I was surprised that the letter 'g' is actually lower case, while the others are all uppercase! It didn't register until it was in front of my nose! It's an unusual decision but it works well!

![Demo of how the text was created](https://dev-to-uploads.s3.amazonaws.com/i/jvcuwcy18pfdqh35e55u.png)

In the image above, you can see how I transformed the text. The text on top is the text that I typed out as normal. Below the red arrow, is the version I edited as a SVG path. I had to change the shape of a few letters (E, L, g, V). All of the letters needed to be made narrower and taller.

The next thing to figure out is how do we create the dripping blood trails?

Morphing the path of a letter to "cut out" and animate the blood trail is possible, but it would be complicated. There are some JavaScript libraries to help with that (such as [GSAP MorphSVGPlugin](https://greensock.com/morphSVG/)), but it's a last resort.

It's probably easiest to overlay an instance of the blood trail over each of the chosen letters. So, we can do something like the image below.

![overlay blood trails](https://dev-to-uploads.s3.amazonaws.com/i/mfj0i507y6d14vae8urf.png)

The black objects are the overlayed blood paths. We will change the fill of these to match the background colour (pink in this case) to create the effect. We just hide them until we need to animate them. There is one variation on the effect - the blood trail at the bottom of the 'V' matches the text colour (white in this case).

For the dripping animation, we want it to trickle slowly down. The droplet at the bottom of the trail is also gradually growing in size. So, it's probably best we split the blood trail into 2 different paths : the _trail_ (we can make it a `rect`) and the _droplet_. We just need to synchronize the speed of descent of both of these.

We prefer to use the `transform` and `opacity` properties for our animation as they are [the most performant](https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count).

![Blood trails](https://dev-to-uploads.s3.amazonaws.com/i/v3a56r6fk8798e3fdl20.png)

The movement for the *trail* is straightforward, it is a translation along the Y axis with `transform: translateY(50px);`. You can try out the values to see what gives you the required result.

Similarly, for the *droplet* we want to move it on the Y axis, but also scale it up at the same time. When we use `transform: scale(1.2);` to make something 20% bigger, it also reduces the amount we need to move it. So we need to reduce the amount of the Y translation to get it to match the *trail*.

The final bit of the animation is have the entire title (ominously) move towards the viewer. This is a translation along the Z axis. To get the amount of movement correct, we must also set the [perspective](https://developer.mozilla.org/en-US/docs/Web/CSS/perspective) on the parent element. So we can use something like`transform: translateZ(100px);` on the SVG, and `perspective: 1100px;` on the `body` (the parent element) to get the right effect.

That's the thought process behind it.

The animation can be done in CSS or in JavaScript. I chose to do in JavaScript with the [GreenSock (GSAP) library](https://greensock.com/gsap/). The random elements can't be done in CSS.

There is an implication if you use JavaScript to execute an infinite looping animation like this. Most libraries use [`requestAnimationFrame()`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) under the hood. When you switch tabs on a browser, if the browser finds an animation that uses `requestAnimationFrame()`, it will slow it down to save resources. So when you open the tab again, the animation might be in an odd state. This animation could have some ghosting of multiple blood trails for a little while before it returns to business as usual. 

To prevent this tab-switching issue, you need to intervene and suspend the animation yourself when the window loses focus.

## Source code (GitHub Repo and Codepen Collection)

The source code is available in [this github repo](https://github.com/robole/title-sequences). I will create more title sequences soon and them to the repo also.

Also, you can check them out in [this codepen collection](https://codepen.io/collection/nNmwgP).

## What I learned

I learned a bit more about [GSAP](https://greensock.com/gsap/):

- You can have simultaneous tweens execute on the same timeline by using a label or specifying a time variable. Prior to that, I was creating separate timelines.
- You can't repeat an animation if you want to use a random function to change the selector for a tween each time it repeats. The best solution I found is to wrap the call to the random function and the associated timeline in a `setInterval` call. You can check the code to see what I did!
- If you want to randomize a tween value, you can use built-in random functions.

## The end

This is end, for now! Watch this space for more title sequences!

Also, if you're a fan of The Queen's Gambit, I found [this interview with the designer behind the title sequences](https://www.artofthetitle.com/title/the-queens-gambit/) an interesting read. I have added some of them to my TODO list!

I hope you enjoyed this short walk-through.

Happy holidays!

---
**Thank you for reading! Feel free to subscribe to my [RSS feed](https://www.roboleary.net/feed.xml), and share this article with others on social media. 💌 🙂**