Lottie/Bodymovin HTML template help needed

graphics
html
template
server
development

#1

Very new to coding and just started out designing an HTML template.
Used Lottie/Bodymovin as base/animation and managed to get working in casparcg with dynamic text fields
(only works if i manually change the values within the HTML file.)

I’m currently having difficulty getting inputs from the client.
Is there any way i could tell casparcg to input the json data into the HTML/JS and somehow parse the string and change the variable so it can work as a dynamic graphics?

Help would be much appreciated.

Server version 2.1.0.3437


#3

Should have worded it a little better.
What I’m trying to do is use the function update() ,parse the string then assign each value to individual global variables.

I’ve been trying to do this

var text1 = "hello"
var text2 = "world"

demo_data.layers[2].t.d.k[0].s.t = text1;
demo_data.layers[4].t.d.k[0].s.t = text2;

and the graphics showed up perfectly, but i wanted a dynamic graphics, so added the following function.

var json1
var json2

function update(str) {
        var json = JSON.parse(str);
        json1 = json.f0
        json2 = json.f1
    }

demo_data.layers[2].t.d.k[0].s.t = json1;
demo_data.layers[4].t.d.k[0].s.t = json2;

There are no errors that i can see from the server log but the graphics won’t show up.
Thanks


#4

I think I kinda see your problem, but I’d recommend you this:

  1. Take a look ar @indr’s HTML producer tutorial, which is quite helpful an thorough. It might seem a bit slow for a seasoned web developer, but introduces a couple of concepts around the functions CasparCG invokes while displaying a template.

  2. Definitely check WebCG Framework, also by @indr. I’ve done plenty of templates with it and frankly simplifies a lot of the code behind the scenes, so you can focus on setting the texts in the right places. Also, it integrates a development mode where you can test everything right in the browser.

  3. This is a really simple template that I’ve done for one of our shows. It implements play(), stop(), update() and uses WebCG Framework. I hope it can help a bit.


#5

You can use JQuery to change things dynamically.

You have a lot of “g” tags an generally you have “tspan” on the text. Just change choose the “g” tag number and and change the text of the “tspan”. You can change all things in the animation of the SVG… it’s very cool.

The only thing is the first time you play the template is not smut, after that is perfect!


#6

I’d also recommend using WebCG, makes handling commands and data nice and easy.

Lottie player has a function that can change/update text (updateDocumentData) but it only works when the animation is running.
If you want to update the text when nothing is happening, I’d recommend having a few frames where nothing happens so you can play this and the text will update.
There are also a few other options in updateDocumentData you can configure such as font size, colour, justify…

I use classes to target elements rather than id’s. To set a class name in After Effects, go to the text layer, right click and select rename. for a class rename it to .f0 or if you want to use an id name it #f0.

This is a stripped-down version how I implement lottie animations in templates, hope it helps.

// Define animation setting. These are in and out points for the different sections of the animation using frame numbers.
const animSettings = {
  "play": {
    "in": 1,
    "out": 26
  },
  "update": {
    "in": 27,
    "out": 29
  },
  "stop": {
    "in": 36,
    "out": 61
  }
}

// Init lottie
const animData = require('./json/animation.json');
const animContainer = document.getElementById('lottie-container');
const anim = lottie.loadAnimation({
  container: animContainer, // The dom element that will contain the animation
  renderer: 'svg',
  loop: false,
  autoplay: false,
  animationData: animData // Path to the animation json
});

// Handle update/data using WebCG
webcg.on('data', function(data) {
  // only play the update animation if we have already started the animation
  if (anim.currentFrame !== 0 && anim.isPaused) {
    anim.playSegments([animSettings.update.in, animSettings.update.out], true);
  }

  // Update animation text
  const animElementsLength = anim.renderer.elements.length;
  for (let i = 0; i < animElementsLength; i++) {
    const animElement = anim.renderer.elements[i];
    // Check the animation element has a class name and that the WebCG data has a key with the same class name
    if (
      animElement.hasOwnProperty('data') && animElement.data.hasOwnProperty('cl') &&
      data && data.hasOwnProperty(animElement.data.cl)
    ) {
      const cl = animElement.data.cl;
      try {
        animElement.canResizeFont(true); // Let lottie resize text to fit the text box
        animElement.updateDocumentData({ t: data[cl] ? data[cl].text || data[cl] : ''}, 0); // Update the text
      } catch (err) {}
    }
  }
});

webcg.on('play', function() {
  anim.playSegments([animSettings.play.in, animSettings.play.out], true);
});

webcg.on('stop', function() {
  anim.playSegments([animSettings.stop.in, animSettings.stop.out], true);
});



#7

We use this in production just with Jquery.

The ScoreBug is updated in real time, even the score and time. you can change all before animation or change colors, sizes, etc in real time or before animation.

You even can hide parts and fade/cut it when you want. You can test in chrome before to see what are the parts you need to change, if you have a text and export it with the ID “text” you can use:

$("#text tspan").html(“Example”);


#8

Hi. I’m using updateDocumentData to get this job done, as documented at https://github.com/airbnb/lottie-web/issues/896

My update function is as follow:

function update(str) {
   dataCaspar = JSON.parse(str || "null");
   anim.renderer.elements[0].updateDocumentData({t: dataCaspar["f0"]});
   anim.renderer.elements[1].updateDocumentData({t: dataCaspar["f1"]});
   //anim.renderer.elements[2].updateDocumentData({t: dataCaspar["f2"], s:40}, 0);
}

Hope ii helps,
cheers


#9

Thanks guys for sharing all that information.
I’m not a real programmer, so after a lot of trial and error I got a template generated with bodymovin to update dynamically. But when I play the template in caspar cg, sometimes kind of random, the template does not update and plays in it’s original state and does not stop after the intro.

In my AE-Comp all the layers start at frame 0, but the in-animation starts after 7 frames. Is that enough time for the template to update?

My HTML Template:

<!DOCTYPE html>
<html lang="en">
<head>
  
  <!--  Meta  -->
  <meta charset="UTF-8" />
  <title>Bodymovin Demo</title>
 <style type="text/css">

html, body {
  background: transparent;
  width: 99.6%; 
  height: 99.6%;
 overflow: hidden; 
}
html {
    /* Set default box-sizing to border-box for easier sizing of elements */
    box-sizing: border-box;
}

*, *:before, *:after {
    /* Make box-sizing property easy to change by components if required */
    box-sizing: inherit;
}


    </style> 

 
</head>
<body>
  
  <div id="lottie-container"> </div>
  
  <!-- Scripts -->
 <script src="webcg-framework.umd.js"></script>
  <script src="scripts/lottie.js"></script>
  <script src="scripts/01_PLID - 1L INFO.js"></script>
</body>
</html>

My java-script:

 
  // Define animation setting. These are in and out points for the different sections of the animation using frame numbers.
const animSettings = {"play": {"in": 0,"out": 35},
  "update": {
    "in": 35,
    "out": 38
  },
  "stop": {
    "in": 39,
    "out": 60
  }
}

// Init lottie
const animData = '01_PLID - 1L INFO.json';
const animContainer = document.getElementById('lottie-container');
const anim = lottie.loadAnimation({
  container: animContainer, // The dom element that will contain the animation
  renderer: 'svg',
  loop: false,
  autoplay: false,
  path: animData // Path to the animation json
});

// Handle update/data using WebCG
webcg.on('data', function(data) {
  // only play the update animation if we have already started the animation
  if (anim.currentFrame !== 0 && anim.isPaused) {
    anim.playSegments([animSettings.update.in, animSettings.update.out], true);
  }

// Update animation text
  const animElementsLength = anim.renderer.elements.length;
  for (let i = 0; i < animElementsLength; i++) {
    const animElement = anim.renderer.elements[i];
    // Check the animation element has a class name and that the WebCG data has a key with the same class name
    if (
      animElement.hasOwnProperty('data') && animElement.data.hasOwnProperty('cl') &&
      data && data.hasOwnProperty(animElement.data.cl)
    ) {
      const cl = animElement.data.cl;
      try {
        //animElement.canResizeFont(true); // Let lottie resize text to fit the text box
        animElement.updateDocumentData({ t: data[cl] ? data[cl].text || data[cl] : ''}, 0); // Update the text
      } catch (err) {}
    }
  }
});

webcg.on('play', function() {
  anim.playSegments([animSettings.play.in, animSettings.play.out], true);
});

webcg.on('stop', function() {
  anim.playSegments([animSettings.stop.in, animSettings.stop.out], true);
});


Best regards
Florian


#10

Hello,

for a few weeks I’m trying to get a Bodymovin animation to work in HTML5, and update the text within it with CasparCG.

I have an exported JSON-file, where the layers have been named “f0” and “f1”. When I implement the Lottie/Bodymovin basics, and run the HTML in CasparCG, the animation works fine. It shows the placeholder texts in the animation.

I have tried to get many examples to work, but so far I can’t get it right… One time I managed to play the animation and make the placeholder texts disappear. Also I can’t get the examples in this topic to work for me. I think I tried to use the WebCG examples correctly…

Are there any tutorials on how to get this working step-by-step?