Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
melanie_lauber
Active Participant
It's getting colder and colder and Christmas is nearing. While we keep our bodies warm with winter jackets, hats and scarves, we warm our hearts with that special, warm Christmas feeling. That feeling however, is rarely related to anything IT. But what if I tell you, you may surprise your Fiori users with just that; they login, and the Fiori Launchpad is snowing...



 

Snowing Effect Credit


First of I'd like to point out that the snowing effect itself has not been created by me and was just found by me via codepen.io. Please see the original snow effect javascript and author here: snowing effect @ codepen.

Developing a "special" Fiori Launchpad Plugin


You may guessed it; I'm talking about a plugin for the Fiori Launchpad. To develop a plugin in Fiori is very similar to developing an app, with a few differences. Let's go through all the steps.

Prerequisite


First of, as a prerequisite, in your SAP Web IDE you must enable following extension: SAP Fiori Launchpad Extensibility


Step 1: Create a project for the plugin


Create a new project from template and choose the now available "SAP Fiori Launchpad Plugin" template. More details can be found at SAP Help. This will generate all necessary files for the plugin, the most important one being Component.js, similar to an app.
I called my project Snow with namespace snow.

Step 2: "Convert" codepen original to Fiori


Now we don't just have access to direct HTML files and especially the plugin, is something that is loaded into the Fiori Launchpad shell - so we can't just copy-n-paste what we have in codepen. Instead we need to turn the snowing effect (or rather all the snowflakes) into an object we can call. I solved it the following way:
I created a new folder in the project called controller and a file Flake.js - my snowflake controller. Flake.js gets most of the javascript code from codepen, but "fiorified", like below:
sap.ui.define([
"sap/ui/base/Object"
], function(Object) {
"use strict";

return Object.extend("snow.controller.Flake", {

init: function(x,y) {
var maxWeight = 5,
maxSpeed = 3;

this.x = x;
this.y = y;

this.r = this.randomBetween(0, 1);
this.a = this.randomBetween(0, Math.PI);

this.aStep = 0.01;
this.weight = this.randomBetween(2, maxWeight);
this.alpha = (this.weight / maxWeight);
this.speed = (this.weight / maxWeight) * maxSpeed;
},

randomBetween: function(min, max, round) {
var num = Math.random() * (max - min + 1) + min;
if (round) {
return Math.floor(num);
} else {
return num;
}
},

distanceBetween: function(vector1, vector2) {
var dx = vector2.x - vector1.x,
dy = vector2.y - vector1.y;
return Math.sqrt(dx * dx + dy * dy);
},

update: function() {
this.x += Math.cos(this.a) * this.r;
this.a += this.aStep;
this.y += this.speed;
}

});
});

Simply put: what we had in codepen as functions are now instead methods of our Flake object and global variables are instead object properties.
Please note: you won't find the init or the loop function from the original in above code: init creates all the snowflakes and loop displays and animates them: both we cannot do from the controller directly.

Step 3: Create Flake objects to create snowing effect


So far we just have a controller that can simulate snowflakes. Now we need to use this object and display the snowflakes in our Fiori Launchpad. For this we have to modify the existing Component.js file.

3.1 Import Flake controller


sap.ui.define([
"sap/ui/core/Component",
"sap/ui/Device",
"snow/controller/Flake"
], function (Component, Device, Flake) {

return Component.extend("snow.Component", {

First step: we need access to our Flake controller (line 4 and 5 above) as well as the Device object.

3.2 Create all snowflakes for the snowing effect:


Inside the init() lifecycle method of our Component, we can now do what the original did in its init function (more or less):
init: function () {
//var rendererPromise = this._getRenderer();

// define snow variables
this._numFlakes = 200;
this._windowW = Device.resize.width; //window.innerWidth;
this._windowH = Device.resize.height; //window.innerHeight;
this._flakes = [];

// get canvas to paint in: there seems to be only one in
// in the Fiori Launchpad so this should always work
var canvas = $("canvas").get(0);
if(!canvas) {
// stop processing in case we don't have a canvas!
return;
}
this._ctx = canvas.getContext("2d");

// first loop to create all Flake objects
var i = this._numFlakes, flake, x, y;
while (i--) {
// create new flake
flake = new Flake();
// get random location
x = flake.randomBetween(0, this._windowW, true);
y = flake.randomBetween(0, this._windowH, true);
flake.init(x, y);
// add flake
this._flakes.push(flake);
}
// start looping all flakes to move them
this.loop();
},

You may noticed that the code now deviates quite a bit from the original. The main reason -as said- is that we don't just have an HTML file to enhance but instead we work with our plugin's lifecycle methods. Reading the comments provided in the code above should explain how the code changed and why it needs to be in this order.
One important thing to understand is the jQuery code to get the canvas:
var canvas = $("canvas").get(0);

What the above simply does, is searching the rendered HTML for any canvas tags: <canvas>. Luckily for us, the Fiori Launchpad indeed uses a canvas and that is in fact the only reason, why we can convert this codepen example into a Fiori plugin. The Flake controller we created gives the snowflakes a position and can change it and the loop function (next step) draws them into the canvas. Without the canvas we cannot draw nor animate the snowflakes, to create the snowing effect. That's why the plugin will not do anything, if no canvas object in the rendered HTML code was found!

3.3 Let it snow: display and move the snowflakes


The very last code bit above calls this.loop() which is an equivalent to the loop function in the original, for us, added as a method to the Component.js:
loop: function() { 
var i = this._flakes.length,
flakeA;

// clear canvas
this._ctx.save();
this._ctx.setTransform(1, 0, 0, 1, 0, 0);
this._ctx.clearRect(0, 0, this._windowW, this._windowH);
this._ctx.restore();

// loop through the flakes and "animate" them
while (i--) {
flakeA = this._flakes[i];
flakeA.update();

this._ctx.beginPath();
this._ctx.arc(flakeA.x, flakeA.y, flakeA.weight, 0, 2 * Math.PI, false);
this._ctx.fillStyle = "rgba(255, 255, 255, " + flakeA.alpha + ")";
this._ctx.fill();

if (flakeA.y >= this._windowH) {
flakeA.y = -flakeA.weight;
}
}
// continue animation...
requestAnimationFrame( this.loop.bind(this) );
},

And here we are: a snowing effect drawn onto the Fiori Launchpad canvas.

Step 4: Test the plugin!


Before we fully leave development, we of course should test the plugin and make sure it's running and -most importantly- doesn't cause any errors. Testing a plugin is a bit different from an app: we have to run a sandbox launchpad (which the template wizard already took care of), which will load our plugin: please find a detailed guide here at SAP Help.

Use your Plugin


Once you tested the plugin and everything works fine, you can deploy your plugin and add it to your Fiori Lauchpad. Depending on your system landscape you may need to do different steps, but find below an example for using SAP Cloud Platform.

Deploy the Plugin to SAP Cloud Platform

This blog post also has a guide (at the very end) on how to add a plugin to a SAP Cloud Platform Fiori Launchpad Portal site.
26 Comments
Labels in this area