Celebration waterfall exercise
by AntowaKartowa
HTML
<main>
<div class="emojiWrapper">
<div class="emojiSpaceContainer">
<div class="emojiSpace">
</div>
</div>
</div>
<img
class="avatar"
src="https://sandpack-bundler.vercel.app/img/avatars/002.png"
alt="user avatar"
/>
<h1>Someone Bought You A Coffee!</h1>
</main>
CSS
:root {
--emojis: 'ππβππΈππβπ';
--emojis-qty: 5;
--emoji-i: 0;
--emoji-height: 1.5em;
--emoji-width: 1.5em;
--emoji-wrapper-height: 120px;
--fall-duration: 3s;
--deviation: .4em;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
html,
body {
height: 100%;
}
body {
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
input,
button,
textarea,
select {
font: inherit;
}
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}
#root,
#__next {
isolation: isolate;
}
/* Basic theme styles */
body {
padding: 16px;
font-family: "Wotfard", sans-serif;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
border-bottom: 3px solid hsl(0deg 0% 25%);
}
th[scope="col"] {
text-align: right;
border-right: 3px solid hsl(0deg 0% 25%);
border-bottom: none;
padding-right: 8px;
}
tr:not(:last-of-type) th[scope="col"],
tr:not(:last-of-type) td {
border-bottom: 1px solid hsl(0deg 0% 50%);
}
/* Custom fonts */
@font-face {
font-family: "Wotfard";
src: url("https://sandpack-bundler.vercel.app/fonts/wotfard/wotfard-semibold-webfont.woff2")
format("woff2");
font-weight: 600;
font-style: normal;
font-display: fallback;
}
@font-face {
font-family: "Wotfard";
src: url("https://sandpack-bundler.vercel.app/fonts/wotfard/wotfard-medium-webfont.woff2")
format("woff2");
font-weight: 500;
font-style: normal;
font-display: fallback;
}
@font-face {
font-family: "Wotfard";
src: url("https://sandpack-bundler.vercel.app/fonts/wotfard/wotfard-regular-webfont.woff2")
format("woff2");
font-weight: 400;
font-style: normal;
font-display: fallback;
}
:root {
--font-family: "Wotfard", sans-serif;
}
body {
background: hsl(210deg 30% 90%);
padding: 16px;
}
main {
background:...
JavaScript
const EMOJI_RANGE = 5;
const EMOJI_WIDTH_EM = 1.5;
const MIN_GAP_EM = 0.3;
const MAX_GAP_EM = 1;
const space = document.querySelector('.emojiSpace');
const width = space.getBoundingClientRect().width;
const em = parseFloat(getComputedStyle(space).fontSize)
var sections_qty = Math.floor(width / (em * (EMOJI_WIDTH_EM + MIN_GAP_EM)));
var gap = width / sections_qty - em * EMOJI_WIDTH_EM;
if (gap / em > MAX_GAP_EM) sections_qty++;
var shiftPercent = (100 / sections_qty).toFixed(2, 10);
_.range(sections_qty + 1).forEach((__, i) => {
const isOdd = i % 2;
const emoji = document.createElement('span');
emoji.classList.add('emoji');
emoji.ariaHidden = true;
emoji.style.setProperty('--left', i * shiftPercent + '%');
emoji.style.setProperty('--emoji-i', _.random(0, 4));
const fallDuration = isOdd ? _.random(1.5, 2) : _.random(0.9, 1.4);
emoji.style.setProperty('--fall-duration', fallDuration.toFixed(1, 10) + 's');
space.appendChild(emoji);
});