JSFiddle - React, Tailwind, and code Playground

by Torwan

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"></script>

<svg class="labSVG" xmlns="http://www.w3.org/2000/svg"	viewBox="0 0 600 600"	>
<defs>
<linearGradient id="frontGrad" gradientUnits="userSpaceOnUse" x1="300" y1="100" x2="300" y2="600">
	<stop  offset="0.5" style="stop-color:#005DE9"/>
	<stop  offset="0.8" style="stop-color:#ED1E79"/>
</linearGradient>  
  <mask id="liquidMask">
<path class="liquidMask" fill="#FFFFFF" d="M337,273.9V129h-74v144.8c-37,14.7-63.1,50.8-63.1,93c0,55.2,44.8,100,100,100
		s100-44.8,100-100C400,324.7,373.9,288.6,337,273.9z"/>  
  </mask>
  <clipPath id="sphereMask">
  <circle fill="red" stroke="none" stroke-width="0.4957" stroke-miterlimit="10" cx="300" cy="367" r="100"/>    
  </clipPath>
  <filter id="goo" color-interpolation-filters="sRGB">
      <feGaussianBlur in="SourceGraphic" stdDeviation="7 7" result="blur" />
      <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -7" result="cm" />
    
        <feComposite in="SourceGraphic" in2="cm" />
  	</filter>
</defs>
<g class="liquidMaskGroup" clip-path="url(#sphereMask)">
  <path class="liquidBack" fill="none" d="M1199.9,365.1c-41.8,0-79.4,9.8-107.4,8.1c-38.9-2.3-54.5-16.4-83.6-19.9
	c-29.1-3.5-71.5,3.4-110.4,1c-28-1.7-56.4-13.7-98.2-13.7c-41.8,0-70.2,12-98.2,13.7c-38.9,2.3-81.4-4.6-110.4-1
	c-29.1,3.5-44.7,17.5-83.6,19.9c-28,1.7-65.7-8.2-107.5-8.2c-41.8,0-79.5,9.9-107.5,8.2c-38.9-2.3-54.5-16.3-83.6-19.9
	c-29.1-3.5-72,3.4-110.9,1c-28-1.7-56.7-13.7-98.7-13.7V438h1200L1199.9,365.1z"/>
  <g class="liquidBubblesGroup" fill="url(#frontGrad)" clip-path="url(#sphereMask)">
    <path class="liquidFront" fill="url(#frontGrad)" ...

CSS

body{
  background-color:#000;
  overflow:hidden;
}
body, html {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
}

.labSVG{
  
  width:100%;
  height:100%;
  /* max-height:600px; */
}
.flask{
  stroke:#f7f7f7;
}
.liquidBack{
  fill:#0248AD;
}
/*
.liquidFront, .liquidBubblesGroup{
  fill:#005DE9;
}
*/
.pop{
  stroke:#005DE9;
}

.darkBubbleGroup{
  fill:#171717;
}

JavaScript

var select = function(s) {
      return document.querySelector(s);
    }, liquidFront = select('.liquidFront'), liquidMaskGroup = select('.liquidMaskGroup'), liquidBack = select('.liquidBack'), bubble0 = select('.bubble0'), bubble1 = select('.bubble1'), bubble2 = select('.bubble2'), bubble3 = select('.bubble3'), bubble4 = select('.bubble4'), pop = select('.pop'), bubblePop0 = select('.bubblePop0'), bubblePop1 = select('.bubblePop1'), bubblePop2 = select('.bubblePop2'), liquidBubblesGroup = select('.liquidBubblesGroup'), darkBubble = document.getElementsByClassName('darkBubble');
var xLink = "http://www.w3.org/1999/xlink";
var pop1 = pop.cloneNode(true);
var pop2 = pop.cloneNode(true);
liquidMaskGroup.appendChild(pop1);
liquidMaskGroup.appendChild(pop2);

var isDevice = (/android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent.toLowerCase()));

if(!isDevice){
  
  TweenMax.set(liquidBubblesGroup, {
    filter:'url(#goo)',
    '-webkit-filter':'url(#goo)'
  })
}




var mainTimeline = new TimelineMax();

var frontLiquidTimeline = new TimelineMax({repeat:-1});
frontLiquidTimeline.to(liquidFront, 3, {
  x:-600,
  ease:Linear.easeNone
})

var backLiquidTimeline = new TimelineMax({repeat:-1});
backLiquidTimeline.from(liquidBack, 3, {
  x:-800,
  ease:Linear.easeNone
})

var b0 = new TimelineMax({repeat:-1, delay:0, repeatDelay:2, onRepeat:doRepeat, onRepeatParams:[bubble0]});
b0.timeScale(1)
b0.to(bubble0, 0.8, {
  attr:{
    cy:'-=80'
  },
  ease:Sine.easeOut
} )

.to(bubble0, 0.8, {
  attr:{
    cy:'+=80'
  },
  ease:Sine.easeIn
})


var b1 = new TimelineMax({repeat:-1, delay:3, repeatDelay:5, onRepeat:doRepeat, onRepeatParams:[bubble1]});
b1.timeScale(1)
b1.to(bubble1, 0.7, {
  attr:{
    cy:'-=120'
  },
  ease:Sine.easeOut
} )

.to(bubble1, 0.7, {
  attr:{
    cy:'+=120'
  },
  ease:Sine.easeIn
})


var b2 = new TimelineMax({repeat:-1, delay:1, repeatDelay:6, onRepeat:doRepeat, onRepeatParams:[bubble2]});
b2.timeScale(1)
b2.to(bubble2, 1, {
  attr:{
  ...