Programming arguments and adding a starry sky

In this step, we will add twinkling stars to our background. This will be done using programmatic arguments that are generated by fcf.argProg().

We are faced with the task of randomly placing the stars in the background and desynchronizing the animation of the twinkling of the stars. To do this, we will create a program argument stars (an array of stars parameters) and a regular argument starsCount, which will store the number of stars.

Modify the template file :templates/blocks/planet.tmpl

... //~ARGUMENTS { fcfStyleInner: fcf.argVal("display: block; overflow: hidden; width: @{{args.width}}@; height: @{{args.height}}@"), width: "100%", height: "300px", starsCount: 100, stars: fcf.argProg(), } ...

Now let's create a hook handling file using fcfmngr or plugins. In which we will form the stars argument.

$ cd [PROJECT_DIRECTORY]/templates/blocks $ fcfmngr create hooks planet

And we will change the property hooksProgrammableArgument, adding the code for generating information about our stars.

File :templates/blocks/planet.hooks.js

... // // Object of hooks for programmatically populated arguments. The function can be asynchronous // hooksProgrammableArgument: { // // Hook of the assembly of a programmatically populated argument created by the fcf.argProg() method with the name ARG_NAME // The function can be asynchronous // @result Returns the value of an argument or a Promise object // stars: (a_taskInfo) => { let stars = []; for(let i = 0; i < a_taskInfo.args.starsCount; ++i) { stars.push({ left: 100*Math.random(), top: 100*Math.random(), duration: 2+8*Math.random(), delay: 2*Math.random(), }); } return stars; }, }, ...

The stars argument now contains an array of information about each star. We did not specify starsCount in the dependencies of the stars argument, despite the fact that its assembly clearly depends on this value. Since, by default, the assembly sequence of template arguments follows the order:

  1. System arguments (starting with the fcf prefix)
  2. URL arguments
  3. Arguments - values
  4. Arguments - templates
  5. Program arguments

If the organization of the arguments and their relationships were different, we might have to add a dependency when declaring an argument in the fcf.argProg() option (the dependencies parameter).

Now let's display our data. Using the Javascript for code construct in the %{{ }}% construct.

File :templates/blocks/planet.tmpl

... //~TEMPLATE <div class="planet-container"> <div class="star-container"> %{{ for(let i = 0; i < args.stars.length; ++i) { }}% <div class="star" style="left:@{{args.stars[i].left}}@%; top: @{{args.stars[i].top}}@%; animation-duration: @{{args.stars[i].duration}}@s; animation-delay: @{{args.stars[i].delay}}@s;"></div> %{{ } }}% </div> <div class="planet-sun-container"> <div class="planet-sun-container-item"> <div class="planet-sun"></div> </div> </div> </div> ...

As you can see from the modified file excerpt, our stars array contains the style parameters for each star, which is a regular DOM element.

Now let's look at the result of our work in the browser.

Example with stars

One of the main tasks of program arguments is to unload the template logic so that all calculations remain in separate modules, and simple and readable code is responsible for the formation of HTML.