JSFiddle - React, Tailwind, and code Playground
by Felis Catus
HTML
<div class="wingspeaker">
<div class="spk hidden">
<svg class="rightwing" viewBox="0 0 105 77">
<path id="rightwing" d="M100,18.8l-4.9-7.9L72.5,29.7l4.4,5.5c-1.3,1.3-1.9,3.2-1.6,5c0.5,2.8,3.1,4.7,5.9,4.2 c2.8-0.5,5.2-3.1,4.8-5.9c0-0.2-0.1-0.4-0.2-0.6c0.4,0.1,0.9,0.1,1.4,0c2.4-0.4,4.6-2.7,4.2-5.1c-0.1-0.3-0.2-0.7-0.3-1 c0.5,0.1,1.1,0.1,1.6,0c2.4-0.4,4.6-2.7,4.2-5.1c0-0.2-0.1-0.4-0.2-0.6c0.1,0,0.1,0,0.2,0c2.4-0.4,4.6-2.7,4.2-5.1 C101,20.2,100.6,19.4,100,18.8z" fill="#003E5C"/>
</svg>
<svg class="leftwing" viewBox="0 0 105 77">
<path id="leftwing" d="M33.3,31.1L11.1,11.8L6,19.6c-0.6,0.6-1,1.4-1.1,2.2C4.5,24.2,6.6,26.5,9,27c0.1,0,0.1,0,0.2,0 C9.1,27.2,9,27.4,9,27.6c-0.4,2.4,1.7,4.8,4.1,5.2c0.6,0.1,1.1,0.1,1.7,0c-0.1,0.3-0.3,0.6-0.3,1c-0.4,2.4,1.7,4.8,4.1,5.2 c0.5,0.1,0.9,0.1,1.4,0c-0.1,0.2-0.1,0.4-0.2,0.6c-0.5,2.8,1.9,5.4,4.7,6c2.8,0.5,5.4-1.3,5.9-4.1c0.3-1.8-0.3-3.8-1.5-5.1 L33.3,31.1z" fill="#003E5C" />
</svg>
<svg class="speaker" viewBox="0 0 105 77">
<g id="speaker">
<polygon fill="#003E5C" points="76.1,76.5 29.4,77 27,1.5 79,0 "/>
<polygon fill="#004E74" points="75.2,75.6 30.2,76.1 27.9,2.6 78,1.2 "/>
<path fill="#003E5C" d="M69.8,55c-0.1,8.9-9.2,15.7-18.1,15.6c-8.9-0.1-16.1-7.4-16-16.2c0.1-8.9,7.3-17.6,16.3-17.5
C60.9,37,69.9,46.1,69.8,55z"/>
<path fill="#FFFFFF" d="M68.8,54.8c-0.1,8.4-8.7,14.9-17.1,14.8c-8.5-0.1-15.2-7-15.1-15.4c0.1-8.4,6.9-16.6,15.4-16.5
C60.4,37.8,68.9,46.4,68.8,54.8z"/>
<path fill="#2E414D" d="M60.1,54.2c0,3.8-4,6.8-7.8,6.8s-7-3.2-6.9-7c0-3.8,3.2-7.6,7.1-7.6S60.1,50.3,60.1,54.2z"/>
<path fill="#2E414D" d="M45.3,44.5c0,0.8-0.8,1.4-1.6,1.4s-1.4-0.7-1.4-1.4c0-0.8,0.6-1.6,1.4-1.5C44.5,42.9,45.3,43.7,45.3,44.5z
"/>
<path fill="#2E414D" d="M62.3,44.2c0,0.8-0.8,1.4-1.6,1.4c-0.8,0-1.4-0.7-1.4-1.4c0-0.8,0.6-1.6,1.4-1.5
C61.5,42.6,62.3,43.4,62.3,44.2z"/>
<path fill="#2E414D"...
CSS
@keyframes left-flap{
0% {transform: rotate(0deg);}
50%{transform: rotate(-50deg);}
100%{transform: rotate(0deg);}
}
@keyframes right-flap{
0% {transform: rotate(0deg);}
50%{transform: rotate(50deg);}
100%{transform: rotate(0deg);}
}
@keyframes speaker-wobble{
0% {transform: translatey(0px);}
50%{transform: translatey(-3px);}
100%{transform: translatey(0px);}
}
.wingspeaker{
position:absolute;
overflow:visible;
width:105px;
height:77px;
}
.wingspeaker>.spk>svg{
position:absolute;
width:100%;
height:100%;
top:0px;
left:0px;
}
.wingspeaker:nth-child(2){
transform: translate(200px, 50px) rotate(30deg) scale(0.7);
}
.leftwing{
transform-origin:30px 35px;
transform:rotate(-20deg);
}
.rightwing{
transform-origin: 75px 35px;
transform:rotate(20deg);
}
.spk{
position:relative;
width:100%;
height:100%;
transition:transform 200ms cubic-bezier(.31,.53,.85,1.31);
transform:scale(1);
}
.spk.hidden{
transform:scale(0);
}
.ani-active .leftwing{
animation:left-flap 600ms infinite;
}
.ani-active .rightwing{
animation:right-flap 600ms infinite;
}
.ani-active .spk{
animation:speaker-wobble 1200ms infinite;
}
JavaScript
(function loloaded(){
function showSpeaker(speaker,show){
var spk=speaker.querySelector(".spk");
if(show)
{
spk.classList.remove('hidden');
speaker.classList.add('ani-active');
}
else
{
speaker.classList.remove('ani-active');
setTimeout(function(){spk.classList.add('hidden');},500);
}
}
setTimeout(function(){showSpeaker(document.querySelectorAll('.wingspeaker')[0],true);},1000);
setTimeout(function(){showSpeaker(document.querySelectorAll('.wingspeaker')[0],false);},3000);
setTimeout(function(){showSpeaker(document.querySelectorAll('.wingspeaker')[1],true);},1300);
setTimeout(function(){showSpeaker(document.querySelectorAll('.wingspeaker')[1],false);},2700);
}());