<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()
This Pen doesn't use any external CSS resources.