<svg class="mainSVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
<defs>
  <polygon id="liquid"></polygon>
  <clipPath id="mainMask">
    <polygon points="402.1 325.43 367.12 334.05 340.15 357.94 327.38 391.63 331.72 427.4 352.19 457.05 384.09 473.79 420.12 473.79 452.02 457.05 472.49 427.4 476.83 391.63 464.05 357.94 437.08 334.05 402.1 325.43" fill="#fff" stroke="#000" stroke-miterlimit="10"/>
    </clipPath>
    <clipPath id="liquidMask">
      <use xlink:href="#liquid" />
      </clipPath>
  </defs>
      <g id="pipette1" class="glass" fill="none" stroke="#aaccfb" stroke-miterlimit="10" stroke-width="4" transform="translate(0, 38)">
<polygon class="liquid" stroke="none" points="34.28 79.01 34.28 94.68 27.91 104.62 27.91 111.41 23.32 114 18.73 111.41 18.73 104.62 12.36 94.68 12.36 79.01 34.28 79.01" fill="#5299f9"/>
<rect id="level" class="liquid" stroke="none" x="12.36" y="48.05" width="22" height="32" fill="#5299f9"/> 
        <g opacity="0.5">
          <polyline points="12.07 28.65 12.07 11.51 12.07 6.83 14.07 4 15.84 2 19.94 2 27.21 2 31.06 2 32.57 4 34.57 7.16 34.57 12.01 34.57 28.65" fill="none" stroke="#003459" stroke-miterlimit="10" stroke-width="4"/>
        <polygon points="42.05 39.01 4.59 39.01 2 36.43 2 32.19 2 31.53 4.59 28.95 4.59 28.95 42.05 28.95 44.64 31.53 44.64 36.43 42.05 39.01" fill="none" stroke="#003459" stroke-miterlimit="10" stroke-width="4"/>
        <polyline points="34.28 39.01 34.28 94.68 27.91 104.62 27.91 111.41 23.32 114.41 18.73 111.41 18.73 104.62 12.36 94.68 12.36 39.01" fill="none" stroke="#003459" stroke-miterlimit="10" stroke-width="4"/>

          </g>

        <g id="pipetteShine" opacity="0.25" stroke="none">
        <polygon points="21.63 11.58 18.15 13.1 18.25 9.3 21.73 7.79 21.63 11.58" fill="#fff"/>
        <polygon points="17.88 90.03 17.86 90.03 16.87 89.04 16.87 47.02 18.87 47.02 18.87 89.04 17.88 90.03" fill="#fff"/>
      </g>
    </g>  
 
  <g id="flask" class="glass" fill="#AACCFB" stroke="#AACCFB" stroke-miterlimit="10" stroke-width="6" >
<!--         <path d="M438.68,219.23v99.08a90,90,0,1,1-77.36,0V219.23" />
        <line x1="341.31" y1="219.23" x2="458.69" y2="219.23" /> -->
        <polyline points="444.09 221.01 444.09 320.09 476.46 348.76 491.79 389.2 486.58 432.13 462.02 467.72 423.73 487.81 380.48 487.81 342.19 467.72 317.62 432.13 312.41 389.2 327.75 348.76 360.12 320.09 360.12 221.01"  stroke-linecap="round" stroke-width="8"/>
        <line x1="343.42" y1="221.01" x2="460.79" y2="221.01"  stroke-width="8"/>   
  
      </g>  
  <g id="drip">
      <polygon class="liquid" points="3.3 4.06 0 13.72 1.86 18.5 7.93 21.59 14.11 18.92 15.79 13.72 12.33 3.7 7.89 0 3.3 4.06"/>
      <polygon points="6.71 6.76 5.22 7.96 4.88 6.08 6.37 4.88 6.71 6.76" fill="#fff" opacity="0.5"/>

    </g>
  <!-- <circle class="liquid" cx="399" cy="420" r="4" /> -->
  <rect  id="droplet" class="liquid" x="399" y="420" width="6" height="6" />
  <g clip-path="url(#mainMask)">
  <use xlink:href="#liquid" x="770" y="0" class="poly darkLiquid" opacity="0.3"/>
<use xlink:href="#liquid" class="poly" y="0"/>  
    
  <g id="bubbleGroup" stroke-width="0" fill="#FFF" opacity="1"  clip-path="url(#liquidMask)">
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
  <rect x="300" y="380" width="3" height="3" />
</g>
</g>      

      <g id="flaskShine" opacity="0.25" stroke="none">
        <polygon points="375.69 300 372.19 296.51 372.19 238.68 375.69 235.18 379.18 238.68 379.18 296.51 375.69 300" fill="#fff"/>
        <rect x="414" y="233" width="16" height="80" rx="0" ry="6" fill="#fff" opacity="0.1"/>    
        <polygon points="368.47 362.44 351.13 369.58 354.5 351.13 371.84 344 368.47 362.44" fill="#fff"/>
        <polygon points="453 407.77 464.55 422.2 443.58 452.6 421.36 464.21 417.62 459.38 434.66 444.52 453 407.77" fill="#fff"/>
      </g>  
</svg>

<!-- <a href="https://greensock.com"><img class="gsap-3-logo" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-3-logo.svg" width="150" /></a> -->
:root {
  --main-color: #E6098B;
  --bg-color: #030912;
}
body {
 background-color: var(--bg-color);
 overflow: hidden;
 text-align:center;
  display: flex;
  align-items: center;
  justify-content: center; 
}

body,
html {
 height: 100%;
 width: 100%;
 margin: 0;
 padding: 0;
}

svg {
 width: 100%;
 height: 100%;
 visibility: hidden;
 
}

.liquid {
  fill:var(--main-color);
}
#bubbleGroup {
  stroke: var(--main-color);
  fill: #222932
}
.poly {
  fill: #3A86FF;
}

.glass {
  opacity: 0.2
}

#flask {
  opacity: 0.5;
  fill:#003459;
  stroke: #003459;
}

.gsap-3-logo {
width: 20vw;
max-width: 150px;
position: fixed;
bottom: 15px;
right: 15px;
}
let select = s => document.querySelector(s),
    selectAll = s => document.querySelectorAll(s),
    mainSVG = select('.mainSVG'),
    liquid = select("#liquid"),
    pointArray = [],
    pointValueXArray = [],
    pointValueYArray = [],
    liquidWidth = 300,
    numPoints = 30,
    dripOffset = 0.0258,
    rippleDuration = 4.6,
    rippleAmount = '+=8',
    startValX = 250,
    startValY = 400,
    colorArray = ['#E6098B', '#FFBE0B', '#FB5607', '#8338EC', '#3A86FF', '#51E5FF', '#04A777', '#F75C03', '#F71735'],
    allBubbles = gsap.utils.toArray('#bubbleGroup rect')

gsap.set(mainSVG, {
  visibility: 'visible'
})
gsap.set('.darkLiquid', {
  scaleX: -1,
  transformOrigin: '50% 50%'
})
for(let i = 0; i < numPoints; i++) {
  let p = liquid.points.appendItem(mainSVG.createSVGPoint());
  pointArray.push(p);
  pointValueXArray.push( (i < numPoints - 2) ? startValX : ( i == numPoints - 2 ) ? 600 : 200 );
  startValX += ( liquidWidth / (numPoints-2) ); 
  pointValueYArray.push( (i < numPoints - 2) ? startValY : 800 )
}

gsap.set(pointArray, {
  x: gsap.utils.wrap(pointValueXArray),
  y: gsap.utils.wrap(pointValueYArray)
})

gsap.set('#level', {
  transformOrigin: '50% 100%'
})
gsap.set('#bubbleGroup rect, #droplet', {
  transformOrigin: '50% 50%'
})
gsap.fromTo(allBubbles, {
  x: 'random(0, 200)',
  y: 'random(0, 120)',
  scale:'random(0.5, 3)',
  rotation: 'random(20, 180)',
  opacity: 1
}, {
  duration: 1,
  rotation: 'random(180, 360)',
  repeatRefresh: true,
  stagger: {
    each: 0.52,
    repeat: -1
  },
  scale: 0.1,
  y: '-=30',
  opacity: 0.1,
}).seek(100)

const makeDrip = () => {

  let currentColor = gsap.utils.random(colorArray);
  gsap.to(':root', {'--main-color': currentColor});
  
  let tl = gsap.timeline({
    defaults: {
      ease: CustomWiggle.create('', {type: 'easeOut', wiggles: gsap.utils.random(9, 12)})
    }
  });

  tl.fromTo('#pipette1', {
    x: 600,
    opacity: 0
  }, {
    duration: 1,
    x: 376,
    opacity: 1,
    ease: 'expo.inOut'
  })
.fromTo('#pipette1', {
    rotation: -95,
    transformOrigin: '50% 100%'
  }, {
    rotation: 0,
    transformOrigin: '50% 100%',
    duration: 1.5,
    ease: 'elastic(1.5, 0.83)'
  }, 0)
    .addLabel('pipetteReady')
    .fromTo('#drip', {
    scale: 0
  }, {
    duration: 1,
    scale: 1,
    transformOrigin: '50% 0%',
    ease: 'elastic(1, 0.8)'
  })
  .to('#level', {
    duration: 1,
    scaleY: 0.5,
    ease: 'elastic(1, 0.8)'
  },'pipetteReady')
    .fromTo('#drip', {
      x: 399,
      y: 155
    }, {
      x: 399,
      y: 430,
      duration: 0.38,
      ease: 'power1.in'
  })
    .addLabel('splash')
    .to('.poly', {
      fill:currentColor,
    ease: 'sine'
  }, 'splash')
    .to('#bubbleGroup', {
      stroke:currentColor,
      ease: 'sine'
  }, 'splash')
  .to(pointArray, {
    duration: gsap.utils.random(3, 5),
    y: (i) => {
      return rippleAmount
    },
    stagger: {
      each: dripOffset,
      from: 'center'
    },
  }, 'splash')  
  .to('#bubbleGroup', {
    duration: 4,
    y: '+=random(5, 10)',
    ease: 'wiggle({type:easeOut, wiggles:10})'
  }, 'splash')
  .to('#droplet', {
    duration: 0.23,
    y: 'random(-30, -60, 1)',
    rotation: 'random(20, 290)',
    ease: 'power1',
  }, 'splash')  
.to('#droplet', {
    duration: 0.23,
    y:0,
    rotation: '+=30',
    ease: 'power1.in',
  }, 'splash+=0.23')  
  .fromTo('#droplet', {
    scale: 1
  }, {
    duration: 0.23,
    scale: 0,
    transformOrigin: '50% 100%',
    ease: 'expo.in' 
  }, 'splash+=0.23')  
  .to('#level', {
    duration: 1,
    scaleY: 1,
    ease: 'expo.in'
  }, 'splash')  
  .to('#pipette1', {
    duration: 1,
    rotation: 23,
    x: 100,
    opacity: 0,
    ease: 'expo.in'
  }, 'splash')  
  
  gsap.delayedCall(4, makeDrip);
}

makeDrip()

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/gsap@3.0.1/dist/gsap.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/CustomEase3.min.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/CustomWiggle3.min.js