Animated field background for Mastodon

https://musicians.today/@cambraca/109348586727335970

by cambraca

HTML

<ul>
  <li>Preview:<br>
    <textarea id="preview" placeholder="What's on your mind?"></textarea>
  </li>
  <li>SVG:<br>
    <textarea id="svg">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 180">
<rect class="bar bar1" x="50"  y="70" width="40" height="100"/>
<rect class="bar bar2" x="110" y="90" width="40" height="80"/>
<rect class="bar bar3" x="170" y="40" width="40" height="130"/>
<rect class="bar bar4" x="230" y="70" width="40" height="100"/>
<rect class="bar bar5" x="290" y="30" width="40" height="140"/>
<rect class="bar bar6" x="350" y="130" width="40" height="40"/>
<rect class="bar bar7" x="410" y="60" width="40" height="110"/>
<style>
.bar {
animation-duration: 5s;
animation-iteration-count: infinite;
animation-timing-function: steps(5);
transform-origin: 0 170px;
fill: rgba(181, 190, 204, .125);
}

.bar1 {animation-name: bar1}
.bar2 {animation-name: bar2}
.bar3 {animation-name: bar3}
.bar4 {animation-name: bar4}
.bar5 {animation-name: bar5}
.bar6 {animation-name: bar6}
.bar7 {animation-name: bar7}

@keyframes bar1 {0% {transform:scaleY(1)} 20% {transform:scaleY(1.3)} 40% {transform:scaleY(0.7)} 60% {transform:scaleY(1.0)} 80% {transform:scaleY(0.8)} }
@keyframes bar2 {0% {transform:scaleY(1)} 20% {transform:scaleY(0.9)} 40% {transform:scaleY(1.1)} 60% {transform:scaleY(0.9)} 80% {transform:scaleY(0.4)} }
@keyframes bar3 {0% {transform:scaleY(1)} 20% {transform:scaleY(0.8)} 40% {transform:scaleY(0.6)} 60% {transform:scaleY(0.5)} 80% {transform:scaleY(0.9)} }
@keyframes bar4 {0% {transform:scaleY(1)} 20% {transform:scaleY(1.2)} 40% {transform:scaleY(0.6)} 60% {transform:scaleY(0.7)} 80% {transform:scaleY(0.9)} }
@keyframes bar5 {0% {transform:scaleY(1)} 20% {transform:scaleY(0.7)} 40% {transform:scaleY(0.8)} 60% {transform:scaleY(0.7)} 80% {transform:scaleY(0.9)} }
@keyframes bar6 {0% {transform:scaleY(1)} 20% {transform:scaleY(0.9)} 40% {transform:scaleY(1.4)} 60% {transform:scaleY(1.0)} 80% {transform:scaleY(0.8)} }
@keyframes...

CSS

ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  gap: 10px;
  margin: 0;
  padding: 0;
}
textarea {
  width: 500px;
  height: 200px;
  background-position: center bottom;
  background-size: contain;
  background-repeat: no-repeat;
}

JavaScript

let svg = '';

function doit() {
  const css = document.getElementById('css');
  const insvg = document.getElementById('svg').value.trim();
  if (svg === insvg)
    return;
  if (!insvg.startsWith('<svg')) {
    css.value = 'Invalid SVG';
    return;
  }
  svg = insvg;
  const url = 'url(data:image/svg+xml;base64,' + btoa(svg) + ')';
  const t = document.querySelector('textarea');
  t.style.backgroundImage = url;
  css.value = `textarea.autosuggest-textarea__textarea:focus {
    background-position: center bottom;
    background-size: contain;
    background-repeat: no-repeat;
    background-image: ${url}
}`;
}

setInterval(doit, 1000);