ABSA Cape Epic Uses CasparCG

The Absa Cape Epic is the most televised mountain bike race in the world and the only eight-day mountain bike stage race classed as hors catégorie by the Union Cycliste Internationale (UCI). This official UCI status makes it a highlight on the professional racer’s calendar. Based in South Africa and mainly streamed live to YouTube (https://www.youtube.com/user/absacapeepic/) and Facebook

We build a custom graphics package for TV for the event this year, using the power of CasparCG, it’s HTML templates and a web based control panel, data was pulled in real time from both the rider database as well as the timing system which allowed us to create split boards and rider profiles on the fly.

Some of the graphics we had


Brilliant work - thanks for sharing.

What was your workflow on building up the HTML templates? What software did you use here?


We designed all the animations in adobe after effects, then exported them with lottie so they were html embed-able animations. From there it was just an html page with some javascript running to update the text, colours and flags based on the data coming in.

This method while a bit of a pain having to deal with lottie it’s IMO the easiest way to create amazing looking animations and once you have a workflow it’s not too difficult


Would you be able to share one of these templates as an example?


Any updates here, Mikie? Looks like an interesting project.


Hi guys,

Download link has a zip which has a lowerthirds folder which is the actual template and the a scripts folder which was just some things I shared between all the templates.

There’s a var debug = “true” in the utils.js which will make the animation run if you open index.html in chrome. If you’re running it from caspar then just set this to false. I have the template setup for 1920 x 1080 so you might need to scroll the chrome window to see it. It’ll show on the bottom left.

The findElementLocations method was just a helper method that gave me the target location of each text field so I can pass the correct data into the correct place. On some of the results boards there were 30 odd text fields so this sped things up.

Images can be swapped out dynamically too. I don’t do it in the attached example but the code below should give you an idea of how it works. Just something I learnt the hard way, bodymovin does an optimization where if you share a image file in AE it only exports and references it once which means you can’t update them individually later. So when you have 20 country flags make sure they different flags in AE so you can change them independently.

const imageElements = container.getElementsByTagName("image");
for (let i = 0; i < imageElements.length; i++) {
  const element = imageElements[i];
  if (~element.getAttribute("href").search("images/img_1.png")) {
    element.setAttribute("href", "../flags/" +
      rider1CountryCode + ".png");

I used xml which was a real pain just because the way I parsed the xml into variables was tedious. Ideally use json and everything else should work the same.

In the bodymovin initialization I have “animationData: test” - That test refers to a variable name in the data.js file. Bodymovin actually exports the animation as a json data file but because you can’t load a json file into an html without hosting the file. Cors blocks it. I had to copy the json into a js file and assign it to a variable. That was annoying though because every time I updated in AE and exported I had to remember to copy the json over. Possible we should update the internal casparcg chromium config flags to allow cors which would simplify this. The other option is to have all your templates hosted and then call them by url instead of template name but for me that adds overhead and a point of failure.

Overall I think this is the way forward for me. It allows for super complex animations which were pretty simple to create in AE compared to any html way. You can also run part of an animation. “animation.playSegments([00, 60], true);” which allows you to animate something in and then animate it out again. Bodymovin has it’s quirks and it’s api needs some expanding to allow for more custom things but once you learn to work with it, it becomes real powerful.

If you have any questions or want to jump on a Skype call to go through any of the other templates just drop me a message


1 Like

Thank you for sharing your template. Alas I can not download it, as Chrome tells me, that it is something harmful. Do you have any other way to share your file? WeTransfer?


That’ll expire in 7 days but hopefully works for now!

Thanks a lot. :slight_smile:

Hi @Mikie
Would you mind sharing the templates again once wetransfer link has expired ?
thanks a lot


Can you share template again sir, pls share its!

1 Like

One more ask for re-sharing the file through WeTransfer please, the link has expired.

1 Like

Hi all,

Sorry for taking so long to get to this! I’ve put all the templates we used on GitHub so they won’t expire

Some are more complete than others, I had a few versions of the code backed up (new machine since then) and not sure which version this is exactly. Team Profiles (https://github.com/ScarlettCode/ABSA-Cape-Epic-Templates/blob/master/teamprofile/index.html) looks relatively complete and should give you a good idea of how I structured things.

It’s not pretty and was a pain to work with, but it worked and with some time to improve the concept and create a bit of a framework around it I think it could make for an easy way to create great visuals.

Let me know if you have any questions



Hi Mikie,

Awesome looking work!
I’ve been trying to get this working and walked right into the problems with pre-compositions.
Did you manage to create more complex after effects with pre-compositions in them?

How did you manage to change the dynamic data inside the pre-comps?
Do you have an example in your package where you work with pre-comps?

Kind Regards,

Hi Hylkewolf,

I think the team lists were pre comps. Someone else created the AE effects I just exported them. I’ll have to dig up the AE projects and check. If you can get it exported by lottie then it’ll work with dynamic data. The most painful part is sticking within the support of lottie.

Everything just get nested in the final lottie json. In my files there’s a debug flag. If you set that to true it’ll give you an output for each element showing you the path. Something like [2][4][6]. Pre comps will just be nested further down I think.

If you want to share you AE files I can take a look and see if I can work out what’s causing the issue