Setting the width of an image in a HTML5 template

As a guiding note: I would never send such information from the client. Because it makes the client too dependent on the template. Adapting the size of a background element to the text length can be done inside the template using javascript or some css tricks. To be able to set that from the client, it would need to know what font and size the template uses. And that should always be left to the template, so that you can use a different template, without changeant anything in the client (beside telling it to use the other template).

Are you sending the unit along with the value? like "1920px" or "100vw" instead of just "1920".

I agree with you, but sometimes the templates need to be a bit flexible. It doesn’t make sense to switch templates just to change the text’s color. If it’s done correctly and in a controlled way, templates should be more dynamic. A background width is not one of those cases though.

Dear didi, dear rrebuffo,

Or should I call you HTML-Gods?! :grinning:

Thanks rrebuffo for the hint with the unit. I obviously got the whole HTML idea wrong. Of course I haven’t sent the unit alongside the value. Doing this it works brilliantly. :+1:
That’s the problem if you only have my semi-knowledge.

And thank you didi for your remarks which I appreciate very much. Of course you’re right. Putting this logic or funtionality into the HTML itself should be the better way.
The challenge is that I don’t have the actual draft from our design department. So I can’t really work with the template. So I use my time to fiddle around with Caspar and HTML to get used to it and to check out what works for me and what doesn’t.

I’m looking forward to getting the actaul draft. Maybe I come back to you then to get it as dynamic as possible. Thanks. :grinning:

By the way:
This is a great forum. You always get an immediate and qualified answer to any request. Perfect help (not only) for beginners like me.

Cheers
Ingo

1 Like

hahaha. I an far away to be called like that. I was hit by the Flash EOL like a shock, around October last year and started with HTML template building beginning of this year. So I am still digging in the dark most of the time.

The good thing with JavaScript is, that it is very similar to ActionScript (Flash) so that at least the syntax is not completely new to me…

1 Like

Okay. Another question to the HTML-Gods :grinning:

I now got the draft from our design department. They did a pretty good job graphically but didn’t work with a timeline as I expected it.
They actually load an animation class (i.e. “animation_in”). For the out animation they remove the animation class from the document and load another class (“animation_out”). Pretty weird for me but works fine with two buttons.

My challenge is now to “press” these button from caspar.js script. And here ends my js knowledge.

 <script type="text/javascript">
    jQuery(document).ready(function() {

    	
    	jQuery('.start_animation').on('click', function(e){
    		e.preventDefault();
    		jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
    	})
    	
    	jQuery('.stop_animation').on('click', function(e){
    		e.preventDefault();
    		jQuery('body').addClass('animation_out');
    	})
    });
  </script>

Could anybody help me here?

I tried to put the following into the caspar.js

function play(str) {
  parseCaspar(str); // Parse templateData into an XML object
  dataInsert(dataCaspar); // Insert data
  jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
}

I also tried

   jQuery(document).ready(function() {
    		jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
    });
	

Both unsucessful. No error message but no function either.

I’m not quite sure if I can call functions in anothetr script like that. Could anybody help?

Thanks.
Ingo

Sometimes when doing CSS animations by swapping classes the browser cannot keep up and it helps to force a repaint - which in turn will trigger the CSS transitions.

See for instance this:

Thanks Tuomo,

I don’t quite get it.
You suggest to insert a dummy command into caspar.js to force the template to repaint?
Something like:

function play(str) {
  parseCaspar(str); // Parse templateData into an XML object
  dataInsert(dataCaspar); // Insert data
	jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
	var elem = document.scrollingElement;
}

I tried that but it doesn’t help.

I’m still not sure if my call for the jQuery function is correct.
Is it possible to use that call this way?

Ingo

Now that does not “do” anything yet.

The actual thing from the example is <some-element>.offsetHeight; -part. Hard to tell details, since we do not know what your parseCaspar(str) and dataInsert(dataCaspar) functions are doing and what your template HTML is like…

And there is jQuery involved, which… nevermind…:roll_eyes:

OK.
Unfortunately I can’t give you the whole template but here is at least the caspar.js I’m using:

/*
*   Data sent from CasparCG Client as templateData
*   is pushed into corresponding HTML id element
*
*   Usage:
*   insert a script reference in the HTML template header.
*   ex: <script type="text/javascript" src="CasparCG.js"></script>
*   Make sure that the id that you refer to is the innermost tag.
*   Everything within that tag id will be replaced by the value sent from CasparCG
*
*   put together by Tomas Linden
*   modified by Øjvind Søgaard Andersen
*
   Structure of data sent from CasparCG:
   <templateData>
      <componentData id="#idCaspar#">
         <data id="text" value="#valCaspar#" />
      </componentData>
      :
      :
      <componentData id="#idCaspar#">
         <data id="text" value="#valCaspar#" />
      </componentData>
   </templateData>
*/


// Global variable for data from CasparCG
var dataCaspar = {};

// Replace characters that could become a problem if left as is
function escapeHtml(unsafe) {
  return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}

// Parse templateData into an XML object
function parseCaspar(str) {
  var xmlDoc;
  if (window.DOMParser) {
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(str, "text/xml");
  }
  dataCaspar = XML2JSON(xmlDoc.documentElement.childNodes);
}


// Make the XML templateData message into a more simple key:value object
function XML2JSON(node) {
  var data = {}; // resulting object
  for (k = 0; k < node.length; k++) {
    var idCaspar = node[k].getAttribute("id");
    var valCaspar = node[k].childNodes[0].getAttribute("value");
    if (idCaspar != undefined && valCaspar != undefined) {
      data[idCaspar] = valCaspar;
    };
  }
  return data;
}

// Main function to insert data
function dataInsert(dataCaspar) {
  for (var idCaspar in dataCaspar) {
    var idTemplate = document.getElementById(idCaspar);
    if (idTemplate != undefined) {
      idTemplate.innerHTML = escapeHtml(dataCaspar[idCaspar]);
    }
  }
}

// Call for a update of data from CasparCG client
function update(str) {
  parseCaspar(str); // Parse templateData into an XML object
  dataInsert(dataCaspar); // Insert data
}

// insert data from CasparCg client when activated
function play(str) {
  parseCaspar(str); // Parse templateData into an XML object
  dataInsert(dataCaspar); // Insert data
  jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
}

// Call for a next from CasparCG client
function next() {
 
}

// Call for a stop from CasparCG client
function stop() {
	jQuery('body').addClass('animation_out');
}

// Call for a update and jump to preview (out)
function preview(str) {
  parseCaspar(str); // Parse templateData into an XML object
  dataInsert(dataCaspar); // Insert data
}

And the part of the HTML that includes scripts

  
  <script type="text/javascript" charset="utf-8" src="jquery.min.js"></script>
  <script type="text/javascript">
    jQuery(document).ready(function() {
    	
    	jQuery('.start_animation').on('click', function(e){
    		e.preventDefault();
    		jQuery('body').removeClass('animation_in animation_out').addClass('animation_in');
    	})
    	
    	jQuery('.stop_animation').on('click', function(e){
    		e.preventDefault();
    		jQuery('body').addClass('animation_out');
    	})
    });
  </script>
  <script type="text/javascript" charset="utf-8" src="CasparCG.js"></script>
.
.
.
	<button class="start_animation" style="position: absolute; left: 30px; top: 30px; width: 100px; height: 30px;">START</button>
	<button class="stop_animation" style="position: absolute; left: 30px; top: 70px; width: 100px; height: 30px;">STOP</button>

The recent template contains two buttons that start and stop the animations. It’s done by loading the classes “animation_in” and “animation_out”.
All I try to do is call the “addClass” function from the caspar.js instead of the buttons.

Sorry I cannot get more precise but it’s copyright related material in the HTML.

Ingo

Ok, so…

CasparCG Client calls the play() function in the template when it’s started with the PLAY command (F2). This happens automatically.

To me, it looks like your template should already work. It has the play() function implemented and it is swapping the CSS classes… No need to do any further “button clicks” anywhere.

:thinking:

But it doesn’t.

The buttons are only for testing the template in the browser.
I’m aware that I don’t need them.

Is it necessary to include the jQuery script into the caspar.js as well or do they “know” each other via the HTML document?

Ingo

I try to avoid jQuery as corona…

I would do:

document.body.classList='animation_in'

But, that’s just me :slight_smile:

jQuery wasn’t my choice :grinning:

The template was delivered that way by the designer.

Sorry

Sorry, but cannot help further with details. Have you tried to add some console.log('here we go') messages somewhere to see how far is your javascript logic running, if for some reason it stops. You should see these messages in your CasparCG console.

No I haven’t done that yet.

I’ll investigate on that.

Thanks.

Ingo

…and always try inside a Caspar, not in a browser.

As well as the console.log diagnostic tool you can also use an instance of Chrome running on the Caspar server that links into the running CasparCG templates.

The following link shows a post from hreinnbeck with very clear guidance on how to connect the Chrome to CasparCG. Once you open the template you have access to the console, console log, all error reports, timing data etc, and an ability to inspect objects and variables.

1 Like

Hello again,

I’d like to say thank you to all who helped me with this topic.

It works fine now.
The actual problem was that the PLAY function in my caspar.js was never triggered although I sent a play command. I suppose that the play command from my client was sent before the template was completely loaded.
Now I leave a little pause of about half a second between ADD and PLAY command and everything works fine. Funny thing was that CCG console logged PLAY OK in any case.

Thank you all for your support. :grinning:

Cheers
Ingo

That just means that the PLAY commands was successfully sent (or queued to be sent) to the template but does not indicate that it actually fired in the template itself since there is no communication back from it.

You should look your template over and see why you need such a big delay as 500ms. The PLAY command is queued until the template should be fully loaded.

Hi hreinnbeck

I tried to reproduce the error today but can’t.
It now works with or without the delay although nothing has changed. :thinking:
Pretty strange. Maybe the reboot of the complete system this morning made the difference.

Anyway let’s hope it runs stable now.

Ingo