<!--
Inspired by Alex Bender
https://dribbble.com/shots/11654096-Download-Like-Animation
-->
<div class="like">
<svg class="lines" viewBox="0 0 64 64">
<line x1="32" y1="32" x2="32.0" y2="00.0"/>
<line x1="32" y1="32" x2="14.1" y2="05.2"/>
<line x1="32" y1="32" x2="02.4" y2="18.4"/>
<line x1="32" y1="32" x2="-0.2" y2="36.4"/>
<line x1="32" y1="32" x2="07.3" y2="52.8"/>
<line x1="32" y1="32" x2="22.6" y2="62.6"/>
<line x1="32" y1="32" x2="40.3" y2="62.6"/>
<line x1="32" y1="32" x2="55.5" y2="52.8"/>
<line x1="32" y1="32" x2="63.1" y2="36.4"/>
<line x1="32" y1="32" x2="60.4" y2="18.5"/>
<line x1="32" y1="32" x2="49.0" y2="04.7"/>
</svg>
<div class="circle"></div>
<svg class="hearth" viewBox="0 0 24 24">
<path d="
M 16.50 4.50
C 19.54 4.50 22.00 6.95 22.00 9.96
C 22.00 13.54 19.86 16.82 15.05 20.00
L 12.27 21.82
C 12.11 21.93 11.89 21.93 11.73 21.82
L 8.95 20.00
C 4.14 16.82 2.00 13.54 2.00 9.96
C 2.00 6.95 4.46 4.50 7.50 4.50
C 9.32 4.50 10.99 5.390 12.00 6.82
C 13.01 5.39 14.68 4.50 16.50 4.50
Z
"/>
</svg>
<svg class="drop" viewBox="0 0 24 24">
<path d="
M 15.00 14.00
C 15.00 15.66 13.66 17.00 12.00 17.00
C 10.34 17.00 9.00 15.66 9.00 14.00
C 9.00 11.75 11.63 8.00 12.00 8.00
C 12.38 8.00 15.00 11.75 15.00 14.00
Z
"/>
</svg>
</div>
<!-- background -->
<svg class="background" width="800" height="600" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M145.794 161.461l-.597 15.577c-.059 1.538-1.762 2.436-3.065 1.615l-13.191-8.305c-1.303-.821-1.229-2.744.133-3.462l13.788-7.271c1.362-.718 2.991.307 2.932 1.846zm541.372 173.611l-14.19 6.452c-1.402.637-2.968-.482-2.819-2.015l1.508-15.515c.149-1.532 1.901-2.329 3.153-1.434l12.683 9.064c1.253.895 1.067 2.81-.335 3.448z" stroke="#fff" stroke-opacity=".25" stroke-width="2"/>
<rect x="371.383" y="71.127" width="18" height="18" rx="2" transform="rotate(13.677 371.383 71.127)" stroke="#fff" stroke-opacity=".25" stroke-width="2"/>
<rect x="189.25" y="411.352" width="18" height="18" rx="2" transform="rotate(62.035 189.25 411.352)" stroke="#fff" stroke-opacity=".25" stroke-width="2"/>
<circle cx="625" cy="531" r="2" fill="#fff" fill-opacity=".25"/>
<path d="M597.914 89.594a1 1 0 10-1.828.812l1.828-.812zm-5.241 28.467a.998.998 0 101.654-1.122l-1.654 1.122zM597 90l-.914.406.003.006.01.024.044.104a26.42 26.42 0 01.696 1.88c.402 1.23.831 2.839.978 4.422.149 1.61-.01 3.036-.616 4.027-.552.905-1.593 1.631-3.701 1.631v2c2.642 0 4.414-.961 5.408-2.588.941-1.54 1.064-3.49.9-5.254-.166-1.792-.643-3.558-1.068-4.86a29.717 29.717 0 00-.753-2.034l-.052-.123a.41.41 0 01-.015-.033l-.004-.01-.001-.002-.001-.002L597 90zm-3.5 12.5c-1.301 0-2.384.239-3.235.74a3.843 3.843 0 00-1.72 2.126c-.558 1.646-.16 3.672.446 5.455.622 1.835 1.546 3.646 2.303 4.984a40.667 40.667 0 001.265 2.086l.082.124.023.033a.035.035 0 00.006.009l.002.003v.001l.828-.561.828-.561-.001-.002-.004-.006-.018-.026-.073-.111a37.75 37.75 0 01-1.197-1.974c-.729-1.287-1.585-2.976-2.15-4.641-.583-1.717-.778-3.191-.446-4.17.152-.447.414-.794.841-1.046.448-.264 1.146-.463 2.22-.463v-2zM375.165 480.285a1 1 0 10-.761-1.849l.761 1.849zm-28.521 3.616a1 1 0 001.755.961l-1.755-.961zm28.141-4.54l-.38-.925v-.001.001l-.003.001-.019.007-.084.033a17.822 17.822 0 01-1.599.509c-1.065.285-2.493.569-3.988.588-1.499.02-3.001-.228-4.27-.945-1.243-.702-2.34-1.897-2.989-3.933l-1.906.608c.794 2.489 2.205 4.102 3.911 5.066 1.68.95 3.568 1.226 5.28 1.204 1.715-.022 3.317-.345 4.479-.656a19.94 19.94 0 001.796-.573l.108-.042a.917.917 0 00.03-.012l.009-.004.003-.001h.002l-.38-.925zm-13.332-4.665c-.393-1.232-.964-2.185-1.791-2.728-.874-.573-1.843-.566-2.727-.268-.854.287-1.691.861-2.467 1.537-.786.685-1.568 1.527-2.309 2.421-1.483 1.788-2.862 3.851-3.864 5.455a70.7 70.7 0 00-1.531 2.574l-.088.157-.023.041a.066.066 0 00-.006.012l-.002.003v.001l.876.48.878.481v-.001l.001-.002.005-.008.02-.037.082-.148a67.899 67.899 0 011.485-2.493c.98-1.57 2.305-3.549 3.706-5.238.701-.844 1.406-1.599 2.084-2.19.688-.6 1.294-.982 1.792-1.15.468-.157.761-.105.991.046.278.182.654.632.982 1.663l1.906-.608z" fill="#fff" fill-opacity=".25"/>
</svg>
<!-- dribbble - twitter -->
<a class="dribbble" href="https://dribbble.com/TaminoMartinius" target="_blank">
<img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg" alt=""/>
</a>
<a class="twitter" target="_top" href="https://twitter.com/TaminoMartinius">
<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72">
<path d="M67.812 16.141a26.246 26.246 0 0 1-7.519 2.06 13.134 13.134 0 0 0 5.756-7.244 26.127 26.127 0 0 1-8.313 3.176A13.075 13.075 0 0 0 48.182 10c-7.229 0-13.092 5.861-13.092 13.093 0 1.026.118 2.021.338 2.981-10.885-.548-20.528-5.757-26.987-13.679a13.048 13.048 0 0 0-1.771 6.581c0 4.542 2.312 8.551 5.824 10.898a13.048 13.048 0 0 1-5.93-1.638c-.002.055-.002.11-.002.162 0 6.345 4.513 11.638 10.504 12.84a13.177 13.177 0 0 1-3.449.457c-.846 0-1.667-.078-2.465-.231 1.667 5.2 6.499 8.986 12.23 9.09a26.276 26.276 0 0 1-16.26 5.606A26.21 26.21 0 0 1 4 55.976a37.036 37.036 0 0 0 20.067 5.882c24.083 0 37.251-19.949 37.251-37.249 0-.566-.014-1.134-.039-1.694a26.597 26.597 0 0 0 6.533-6.774z"/>
</svg>
</a>
:root {
--size: 50px;
--color-primary: #E18A6D;
--color-secondary: #FFFFFF;
--color-hearth: var(--color-secondary);
--color-drop: var(--color-primary);
--color-circle: var(--color-secondary);
--size-hearth: var(--size);
--size-drop: var(--size);
--size-circle: calc(var(--size) * 1.33);
--size-lines: calc(var(--size) * 2.66);
--ratio-hearth: 1;
--ratio-hearth-scale: 1;
--ratio-scale: 1;
--ratio-rotate: 1;
--ratio-offset-drop: 1;
--offset-drop: calc(var(--size) * 2);
--line-length: 5;
--line-offset: 35;
--opacity-circle: 0.15;
--opacity-drop: 0;
--opacity-lines: 0;
}
body {
background: linear-gradient(to right, #AD5389, #3C1053);
overflow: hidden;
}
.hearth,
.drop,
.like,
.circle,
.lines,
.background {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hearth {
width: calc(var(--size-hearth) * var(--ratio-hearth));
height: calc(var(--size-hearth) / var(--ratio-hearth));
transform:
translate(-50%, -50%)
scaleX(var(--ratio-rotate))
scale(var(--ratio-hearth-scale))
;
path {
fill: var(--color-hearth);
}
}
.drop {
width: var(--size-drop);
height: var(--size-drop);
transform:
translate(-50%, calc(-50% + var(--offset-drop) * -1 * var(--ratio-offset-drop)))
scaleX(var(--ratio-rotate))
scale(var(--ratio-hearth-scale))
;
opacity: var(--opacity-drop);
path {
fill: var(--color-drop);
}
}
.like {
width: var(--size-circle);
height: var(--size-circle);
transform:
translate(-50%, -50%)
scale(var(--ratio-scale))
;
cursor: pointer;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}
.circle {
width: var(--size-circle);
height: var(--size-circle);
border-radius: 9999px;
background-color: var(--color-circle);
opacity: var(--opacity-circle);
}
.lines {
width: var(--size-lines);
height: var(--size-lines);
opacity: var(--opacity-lines);
line {
stroke-dasharray: var(--line-length) 30;
stroke-dashoffset: var(--line-offset);
stroke: var(--color-drop);
stroke-width: 2px;
stroke-linecap: round;
}
}
.plus-one {
--ratio-offset-y: 0;
--ratio-offset-x: 0;
--ratio-scale: 0;
background-color: var(--color-primary);
position: absolute;
top: 50%;
left: 50%;
border-radius: 9999px;
transform:
translate(-50%, -70%)
translate(calc(var(--size) * var(--ratio-offset-x)), calc(var(--size) * -2 * var(--ratio-offset-y)))
rotate(calc(-20deg * var(--ratio-offset-x)))
scale(var(--ratio-scale))
;
&:after {
content: '+1';
color: var(--color-secondary);
font-family: 'Varela Round', sans-serif;
font-size: var(--size);
padding: 0.25em;
}
}
.background {
opacity: 0.25;
pointer-events: none;
}
// dribbble - twitter
.dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
img {
display: block;
height: 28px;
}
}
.twitter {
position: fixed;
display: block;
right: 64px;
bottom: 14px;
svg {
width: 32px;
height: 32px;
fill: #1da1f2;
}
}
View Compiled
gsap.registerPlugin(MorphSVGPlugin);
const like = document.querySelector('.like');
const background = document.querySelector('.background');
const hearthPath = document.querySelector('.hearth path').getAttribute('d');
const drop = document.querySelector('.drop path');
const dropPath = drop.getAttribute('d');
const size = gsap.getProperty(like, '--size');
const colorDrop = gsap.getProperty(like, '--color-drop');
const colorCircle = gsap.getProperty(like, '--color-circle');
const lineLength = gsap.getProperty(like, '--line-length');
const lineOffset = gsap.getProperty(like, '--line-offset');
const opacityCircle = gsap.getProperty(like, '--opacity-circle');
const playspeed = 1;
const keyframes = [
/* 0 */ 0.00,//s
/* 1 */ 0.20,//s
/* 2 */ 0.25,//s
/* 3 */ 0.35,//s
/* 4 */ 0.40,//s
/* 5 */ 0.50,//s
/* 6 */ 0.55,//s
/* 7 */ 0.65,//s
/* 8 */ 0.70,//s
/* 9 */ 0.75,//s
/* 10 */ 0.90,//s
/* 11 */ 1.10,//s
/* 12 */ 1.25,//s
/* 13 */ 1.42,//s
/* 14 */ 1.60,//s
];
const timespan = (start, end) => ({
delay: keyframes[start] * (1 / playspeed),
duration: (keyframes[end] - keyframes[start]) * (1 / playspeed),
});
const handleClick = () => {
const plusOne = document.createElement('div');
plusOne.classList.add('plus-one');
like.appendChild(plusOne);
gsap.killTweensOf(like);
gsap.killTweensOf(drop);
/* Drop */
// Fall
gsap.fromTo(like, {
'--ratio-offset-drop': 1,
'--opacity-drop': 0,
}, {
'--opacity-drop': 1,
'--ratio-offset-drop': 0,
...timespan(0, 2),
});
// Morph
gsap.fromTo(drop, {
morphSVG: dropPath,
}, {
morphSVG: { shape: hearthPath, shapeIndex: 3 },
...timespan(2, 3),
})
// Fade
gsap.to(like, {
'--opacity-drop': 0,
...timespan(3, 5),
});
// Reset
gsap.to(drop, {
morphSVG: dropPath,
...timespan(5, 5),
});
/* Hearth */
// Rotate
gsap.fromTo(like, {
'--ratio-rotate': 1,
}, {
'--ratio-rotate': 0.25,
...timespan(0, 2),
});
gsap.to(like, {
'--ratio-rotate': 1,
...timespan(2, 5),
});
// Scale
gsap.fromTo(like, {
'--ratio-hearth-scale': 1,
}, {
'--ratio-hearth-scale': 0.9,
...timespan(1, 2),
});
gsap.to(like, {
'--ratio-hearth-scale': 1.4,
...timespan(2, 6),
});
gsap.to(like, {
'--ratio-hearth-scale': 0.95,
...timespan(6, 9),
});
gsap.to(like, {
'--ratio-hearth-scale': 1.05,
...timespan(9, 10),
});
gsap.to(like, {
'--ratio-hearth-scale': 1,
...timespan(10, 11),
});
/* Like */
// Scale
gsap.fromTo(like, {
'--ratio-scale': 1,
}, {
'--ratio-scale': 0.5,
...timespan(1, 3),
});
gsap.to(like, {
'--ratio-scale': 1.2,
...timespan(3, 5),
});
gsap.to(like, {
'--ratio-scale': 0.95,
...timespan(5, 8),
});
gsap.to(like, {
'--ratio-scale': 1,
...timespan(8, 10),
});
/* Circle */
// tint
gsap.fromTo(like, {
'--color-circle': colorCircle,
'--opacity-circle': opacityCircle,
}, {
'--color-circle': colorDrop,
'--opacity-circle': 1,
...timespan(3, 5),
});
// reset
gsap.to(like, {
'--color-circle': colorCircle,
'--opacity-circle': opacityCircle,
...timespan(11, 14),
});
/* Lines */
// Fade in
gsap.fromTo(like, {
'--opacity-lines': 0,
'--line-length': lineLength,
'--line-offset': lineOffset,
}, {
'--opacity-lines': 1,
...timespan(3, 4),
});
// Out
gsap.to(like, {
'--line-offset': 15,
...timespan(4, 6),
});
// Collapse
gsap.to(like, {
'--line-length': 0,
'--line-offset': 1,
...timespan(6, 8),
});
// Fade out
gsap.to(like, {
'--opacity-lines': 0,
...timespan(7, 8),
});
// Reset
gsap.to(like, {
'--line-length': lineLength,
'--line-offset': lineOffset,
...timespan(8, 8),
});
/* Plus-One */
// scale
gsap.to(plusOne, {
'--ratio-scale': 0.5,
ease: 'elastic',
...timespan(4, 14),
});
gsap.to(plusOne, {
'--ratio-offset-y': 1,
ease: 'none',
...timespan(4, 14),
});
gsap.to(plusOne, {
'--ratio-offset-x': .5,
ease: 'sine.inOut',
...timespan(5, 8),
});
gsap.to(plusOne, {
'--ratio-offset-x': -.25,
ease: 'sine.inOut',
...timespan(8, 11),
});
gsap.to(plusOne, {
'--ratio-offset-x': .15,
ease: 'sine.inOut',
...timespan(11, 13),
});
gsap.to(plusOne, {
'--ratio-offset-x': 0,
ease: 'sine.inOut',
...timespan(13, 14),
});
gsap.to(plusOne, {
opacity: 0,
ease: 'none',
...timespan(12, 14),
onComplete: () => {
plusOne.remove();
}
});
/* Background */
// Scale
gsap.fromTo(background, {
scale: 1,
}, {
scale: 1.1,
ease: 'sine.inOut',
...timespan(3, 5),
});
gsap.to(background, {
scale: 1,
ease: 'elastic',
...timespan(5, 14),
});
};
like.addEventListener('click', handleClick);
handleClick();
View Compiled
This Pen doesn't use any external CSS resources.