Теперь нам нужно разместить саму планету вращающуюся вокруг солнца. Для этого мы будем использовать отдельный подшаблон earth.
Добавим подшаблон earth в конец файла :templates/blocks/planet.tmpl
Файл :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>
Рассмотрим содержимое добавленного кода.
В самом начале мы устанавливаем опцию autoUpdate равным значению true. Для того, что бы фреймворк автоматически выполнял обновление шаблона при изменении его аргументов.
Теперь перейдем к секции //~ARGUMENTS. Здесь полностью выполняется расчет позиции нашего движущегося объекта по окружности. Аргумент feq задает частоту обновления перерисовки. Аргумент period определяет период вращения объекта в секундах. Позиция планеты рассчитывается аргументами leftPlanet и topPlanet в относительных координатах от 0 до 1, в зависимости от аргумента time, который будет меняться на стороне браузера и хранить в себе время в миллисекундах от начала запуска.
Так же отметим, что мы меняем значение стиля z-index для подшаблона earth. Когда высота объекта меньше 0.5 мы устанавливаем значение z-index равным 0, таким образом мы выполняем эффект скрытия планеты за солнцем. Все это выполняется в расчете параметра fcfStyleInner.
Аргумент pause будет использоваться после, для остановки и воспроизведения анимации.
Теперь выполним рендеринг подшаблона earth в основном шаблоне.
Файл :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>
...
Результат добавления подшаблона earth представлен на картинке
Теперь осталось только запустить счет аргумента time. Для этого создадим файл враппера подшаблона :templates/blocks/planet+earth.tmpl командой или плагинами.
$ cd [PROJECT_DIRECTORY]/templates/blocks
$ fcfmngr create wrapper planet+earth
Откройте файл :templates/blocks/planet+earth.wrapper.js и измените его содержимое
Файл :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);
}
};
}
});
Собственно сам код враппера очень прост.
Методами getArg и setArg класса fcf.NClient.Wrapper выполняется получение и установка значения аргумента шаблона на стороне браузера.
В методе initialize мы выполняем первый запуск таймера, который увеличивает значение аргумента шаблона time на разницу времени от предыдущего запуска. А аргумент шаблона "pause" просто останавливает обновление шаблона и увеличение аргумента time.