<svg id="loveSliderSVG" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
<defs>
</defs>
<!-- <rect width="100%" height="100%"/> -->
<line class="trackBg" x1="50" x2="750" y1="366" y2="366" stroke="#FFFCF9" stroke-linecap="round" stroke-linejoin="round" stroke-width="15"/>
<line class="trackMiddle" x1="50" x2="750" y1="366" y2="366" stroke="#2E6783" stroke-linecap="round" stroke-linejoin="round" stroke-width="6" opacity="1"/>
<line class="track" x1="50" x2="750" y1="366" y2="366" stroke="#ff595e" stroke-linecap="round" stroke-linejoin="round" stroke-width="6"/>
<g id="heartChat" class="heartChat">
<path d="M115.44,92H81.15a8.32,8.32,0,0,0-5.9,2.45l-9.9,9.9a1,1,0,0,1-1.34,0l-9.9-9.9A8.35,8.35,0,0,0,48.2,92H13.91A10.44,10.44,0,0,1,3.5,81.6V13.91A10.45,10.45,0,0,1,13.91,3.5H115.44a10.44,10.44,0,0,1,10.41,10.41V81.6A10.43,10.43,0,0,1,115.44,92Z" fill="none"/>
<path d="M115.44,92H81.15a8.32,8.32,0,0,0-5.9,2.45l-9.9,9.9a1,1,0,0,1-1.34,0l-9.9-9.9A8.35,8.35,0,0,0,48.2,92H13.91A10.44,10.44,0,0,1,3.5,81.6V13.91A10.45,10.45,0,0,1,13.91,3.5H115.44a10.44,10.44,0,0,1,10.41,10.41V81.6A10.43,10.43,0,0,1,115.44,92Z" fill="none" stroke="#FFFCF9" stroke-miterlimit="10" stroke-width="5" />
<mask id="heartFillMask">
<rect class="heartFill" x="-54" y="72" width="237" height="91" fill="#FFF"/>
</mask>
<path id="heartBg" d="M76.16,23a13.23,13.23,0,0,0-10.83,5.63,13.24,13.24,0,0,0-24.08,7.62c0,18.06,24.08,34.92,24.08,34.92S89.41,54.33,89.41,36.27A13.25,13.25,0,0,0,76.16,23Z" fill="#FFF" opacity="0.1"/>
<g mask="url(#heartFillMask)" >
<path id="XXpinkHeart" d="M76.16,23a13.23,13.23,0,0,0-10.83,5.63,13.24,13.24,0,0,0-24.08,7.62c0,18.06,24.08,34.92,24.08,34.92S89.41,54.33,89.41,36.27A13.25,13.25,0,0,0,76.16,23Z" fill="#ff595e"/>
<g id="shineGroup">
<path d="M89.34,37.92c-1.39,17.42-24,33.26-24,33.26s-1.8-1.26-4.42-3.46C66.39,64.18,83.07,52.53,89.34,37.92Z" fill="#7f474b" opacity="0.32"/>
<path d="M60.15,26a14.06,14.06,0,0,0-1.72-.1c-7.33,0-13.48,5.38-15.1,12.63,0-.43-.06-.86-.06-1.3,0-6.88,5.27-12.46,11.77-12.46A11.2,11.2,0,0,1,60.15,26Z" fill="#fff" opacity="0.5"/>
<path d="M81,26.29c-.39-.12-.79-.22-1.2-.31-5.22-1.1-10.21.87-12.18,4.51a5.62,5.62,0,0,1,.1-.7c.78-3.7,5.17-5.9,9.79-4.92A10.26,10.26,0,0,1,81,26.29Z" fill="#fff" opacity="0.5"/>
</g>
</g>
</g>
<circle class="follower" cx="0" cy="0" r="0" fill="#62B6CB" fill-opacity="1" stroke="#FFFCF9" stroke-width="0"/>
<circle class="liquidFollower" cx="0" cy="0" r="0" fill="#62B6CB" fill-opacity="1" stroke="#FFFCF9" stroke-width="0"/>
<rect class="dragger" x="-100" y="105" width="290" height="220" fill="#62B6CB" fill-opacity="0" stroke="#FFFCF9" stroke-width="0"/>
</svg>
body {
background-color: #175676;
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;
overflow: visible;
}
class App {
select = e => document.querySelector(e);
selectAll = e => document.querySelectorAll(e);
mainTl = gsap.timeline();
heartFill = this.select('.heartFill');
maxDrag = 705;
heartFillMaxPosY = -50;
draggerProp = gsap.getProperty('.dragger');
trackTween = null;
constructor(){
let followerVX = 0;
let liquidFollowerY = 0;
let followerProp = gsap.getProperty('.follower');
gsap.set('.heartFill', {
transformOrigin:'50% 0%'
})
this.myDragger = Draggable.create('.dragger', {
type:'x',
bounds:{minX:0, maxX:this.maxDrag, minY:0, maxY:0},
onDrag:this.onDrag,
onPress: (e) => {
gsap.to('.heartChat', {
duration: 0.1,
scale: 0.98
})
},
onRelease: (e) => {
gsap.to('.heartChat', {
duration: 0.6,
scale: 1,
ease: 'elastic(0.93, 0.35)'
})
},
onThrowUpdate:this.onDrag,
inertia:true,
callbackScope: this,
overshootTolerance:0,
throwResistance: 8000
})
gsap.set('.heartChat', {
x: -18,
y: 235,
transformOrigin:'50% 105%'
})
gsap.to('.follower', {
x:'+=0',
repeat:-1,
modifiers:{
x: gsap.utils.unitize((x) => {
followerVX += (this.draggerProp('x') - followerProp('x')) * 0.08;
liquidFollowerY += (this.draggerProp('x') - followerProp('x')) * 0.98;
followerVX *= 0.79;
liquidFollowerY *= 0.4;
return followerProp('x') + followerVX;
})
}
})
gsap.to('.liquidFollower', 31, {
x:'+=0',
repeat:-1,
modifiers:{
x: (x) => {
liquidFollowerY += (this.draggerProp('x') - gsap.getProperty('.liquidFollower', 'x')) * 0.98;
liquidFollowerY *= 0.54;
return followerProp('x') + liquidFollowerY ;
}
}
})
gsap.to('.heartChat', {
rotation:'+=0',
repeat:-1,
ease: 'linear',
modifiers:{
rotation: gsap.utils.unitize((rotation) => {
let val = rotation+followerVX*0.595
return -val;
})
}
})
gsap.to('.heartFill', {
rotation:'+=0',
repeat:-1,
ease: 'linear',
modifiers: {
rotation: gsap.utils.unitize((rotation) => {
let val = rotation+liquidFollowerY*0.5;
return (val)
})
}
})
this.onDrag();
}
onDrag(){
//console.log(this.particlePool)
let posX = this.draggerProp('x');
let progress = posX / this.maxDrag;
gsap.to('.heartChat', 0.1, {
x: posX - 18
})
let percent = progress * 100;
let percentY = progress * this.heartFillMaxPosY;
//console.log(`0% ${percent}%`)
this.trackTween = gsap.to('.track', {
drawSVG: `100% ${percent}%`,
ease: 'elastic(0.4, 0.16)'
})
gsap.to('.heartFill', {
duration: 0.1,
y: percentY
})
if(progress == 1){
//you reached the end
}
}
}
gsap.set('#loveSliderSVG', {
visibility: 'visible'
})
new App();
This Pen doesn't use any external CSS resources.