Template:Vilnius-Lithuania/JS/WaveScript

/* Prerequisites:

*      Have an animWave div with an svg with a animWavePath path inside
* (
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg"><path id="animWavePath" d="" fill="#fafafc"/></svg>
)
*      Have a setWaveParams function which returns a waveParams object (width, height, waveWidth, waveHeight, waveDelta, speed, wavePoints)
*/

var wave; var waveParams; function initializeWaveAnimation(el) {

   waveParams = setWaveParams();
   el.style.backgroundImage = "unset";
   wave = document.getElementById("animWavePath");
   function calculateWavePoints(factor) {
       let points = [];
       
       for (let i = 0, n = waveParams.wavePoints; i <= n; i++) {
           let x = i/n * waveParams.waveWidth;
           let sinSeed = (factor + (i + i % n)) * waveParams.speed * 100;
           let sinHeight = Math.sin(sinSeed / 100) * waveParams.waveDelta;
           let yPos = Math.sin(sinSeed / 100) * sinHeight  + waveParams.waveHeight;
           points.push({x: x, y: yPos});
       }
       return points;
   }
   function buildPath(points) {
       let SVGString = "M " + points[0].x + " " + points[0].y;
       let cp0 = {
           x: (points[1].x - points[0].x) / 2,
           y: (points[1].y - points[0].y) + points[0].y + (points[1].y - points[0].y)
       };
       SVGString += " C " + cp0.x + " " + cp0.y + " " + cp0.x + " " + cp0.y + " " + points[1].x + " " + points[1].y;
       let prevCp = cp0;
       let inverted = -1;
       for (let i = 1; i < points.length-1; i++) {
           // let cpLength = Math.sqrt(prevCp.x * prevCp.x + prevCp.y * prevCp.y);
           let cp1 = {
               x: (points[i].x - prevCp.x) + points[i].x,
               y: (points[i].y - prevCp.y) + points[i].y
           };
           SVGString += " C " + cp1.x + " " + cp1.y + " " + cp1.x + " " + cp1.y + " " + points[i+1].x + " " + points[i+1].y;
           prevCp = cp1;
           inverted = -inverted;
       };
       SVGString += " L " + waveParams.width + " " + waveParams.height;
       SVGString += " L 0 " + waveParams.height + " Z";
       return SVGString;
   }
   let lastUpdate = window.Date.now();
   let totalTime = 0;
   function tick(timeElapsed) {
       totalTime += (timeElapsed-lastUpdate) / 1000;
       lastUpdate = timeElapsed;
       
       let factor = totalTime*Math.PI;
       wave.setAttribute("d", buildPath(calculateWavePoints(factor)));
       
       window.requestAnimationFrame(tick);
   };
   tick(performance.now());

} function setWaveParams_default(){

   let container = document.body;
   return {
       width: container.offsetWidth,
       height: container.offsetHeight,
       waveWidth: container.offsetWidth,
       waveHeight: window.innerHeight,
       waveDelta: 15,
       speed: 0.15,
       wavePoints: 6,
   };

}


let animElement = document.getElementById("animWave"); if (animElement != null) {

   if (window.setWaveParams == null){
       var setWaveParams = setWaveParams_default;
   }
   initializeWaveAnimation(animElement);
   window.addEventListener("resize", ()=>{
       waveParams = setWaveParams();
   });

}