Adding a moving planet and getting to know the wrapper

Now we need to place the planet itself orbiting the sun. For this we will use a separate 'earth' subtemplate.

Add the 'earth' subtemplate to the end of the file :templates/blocks/planet.tmpl

File :templates/blocks/planet.tmpl

... //~OPTIONS earth { autoUpdate: true, } //~ARGUMENTS earth { fcfClassInner: "planet-earth-container", fcfStyleInner: fcf.argVal("z-index: @{{args.topPlanet > 0.5 ? 2 : 0}}@"), feq: 60, period: 10, time: 0, pause: false, leftPlanet: fcf.argVal("@{{(Math.sin(Math.PI * args.time / args.period / 1000 * 2) + 1) / 2 * 0.5 + 0.25}}@"), topPlanet: fcf.argVal("@{{(Math.cos(Math.PI * args.time / args.period / 1000 * 2) + 1) / 2 * 0.5 + 0.25}}@"), } //~TEMPLATE earth <div class="planet-earth" style="left: @{{100*args.leftPlanet}}@%; top: @{{100*args.topPlanet}}@%;"></div>

Let's take a look at the content of the added code.

At the very beginning, we set the autoUpdate option to true. In order for the framework to automatically update the template when its arguments change.

Now let's move on to the //~ARGUMENTS section. Here, the calculation of the position of our moving object along the circumference is completely performed. The feq argument specifies the refresh rate for the redraw. The period argument specifies the rotation period of the object, in seconds. The position of the planet is calculated by the leftPlanet and topPlanet arguments in relative coordinates from 0 to 1, depending on the time argument, which will change on the browser side and store the time in milliseconds from the start of the launch.

Also note that we are changing the z-index style for the earth subtemplate. When the height of the object is less than 0.5 we set the z-index value to 0, thus we perform the effect of hiding the planet behind the sun. All this is done in the calculation of the fcfStyleInner parameter.

The pause argument will be used after, to pause and play the animation.

Now let's render the 'earth' subtemplate in the main template.

Файл :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> @{{ render.template("+earth"); }}@ </div> ...

The result of adding the earth subtemplate is shown in the picture.

Now all that remains is to start counting the time argument. To do this, create a sub-template wrapper file :templates/blocks/planet+earth.tmpl using the command or plugins.

$ cd [PROJECT_DIRECTORY]/templates/blocks $ fcfmngr create wrapper planet+earth

Open the file :templates/blocks/planet+earth.wrapper.js and change its content

File :templates/blocks/planet+earth.wrapper.js

fcf.module({ name: "templates/blocks/planet+earth.wrapper.js", dependencies: ["fcf:NClient/Wrapper.js"], module: function(Wrapper){ return class WrapperEx extends Wrapper{ constructor(a_initializeOptions){ super(a_initializeOptions); } async initialize(){ await super.initialize() this.timer(); } timer(){ let self = this; if (!this.getArg("pause")){ let time = (new Date()).getTime(); let diff = this._lastTime ? time - this._lastTime : 1 / this.getArg("feq") * 1000; this.setArg("time", this.getArg("time") + diff); this._lastTime = time; } else { this._lastTime = undefined; } setTimeout(()=>{ self.timer(); }, 1 / this.getArg("feq") * 1000); } }; } });

Actually, the wrapper code itself is very simple.

The getArg and setArg methods of the fcf.NClient.Wrapper class get and set the value template argument on the browser side.

In the initialize method, we execute the first timer start, which increments the time template argument by the time difference from the previous start. And the "pause" template argument simply stops updating the template.