<svg width="500" height="500" viewBox="0 0 500 500">
  <defs>
    <path id="eyebrow" d="M-10,0 Q0,-10 10,0" stroke="white" stroke-width="3" fill="none" />
    <path id="nose" stroke="#fff" stroke-width="3" fill="none" d="M1 1c17 28 22 40-1 40" />
  </defs>

  <rect id="bg" x="0" y="0" width="500" height="500" fill="#212121" stroke="none"  />
  <g id="head-holder" transform="translate(250 250) scale(1.5)">
    <circle id="head" cx="0" cy="0" r="120" fill="none" stroke="white" stroke-width="3" fill="black" />

    <circle id="left-eye" cx="-35" cy="-20" r="8" fill="none" stroke="white" stroke-width="5" fill="none" />
    <circle id="right-eye" cx="35" cy="-20" r="8" fill="none" stroke="white" stroke-width="5" fill="none" />

    <use href="#eyebrow" x="-35" y="-40" transform="scale(-1, 1)" />

    <use href="#eyebrow" x="-35" y="-40" />

    <use href="#nose" x="-5" y="-20" />
    <g id="mouth-holder" transform="translate(-250 -200)"><path id="mouf" d="M 200,250 Q 250,250 300,250" stroke="pink" stroke-width="12" stroke-linecap="round" fill="none" /></g>
    
  </g>
</svg>
<div class="buttonHolder">
  <button id="smile-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">smile</button>
  <button id="meh-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">meh</button>
  <button id="mad-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">mad</button>
  <button id="sad-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">sad</button>
  <button id="evil-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">evil</button>
  <button id="wow-button" class="text-black bg-gray-200 py-2 px-4 my-5 hover:bg-gray-300 rounded">wow</button>
</div>
body {
  background: #212121
}
// ui
const smileButton = document.querySelector("#smile-button");
const madButton = document.querySelector("#mad-button");
const sadButton = document.querySelector("#sad-button");
const mehButton = document.querySelector("#meh-button");
const evilButton = document.querySelector("#evil-button");
const wowButton = document.querySelector("#wow-button");

// graphics
const mouf = document.querySelector("#mouf");
const eyebrow = document.querySelector("#eyebrow");
const leftEye = document.querySelector("#left-eye");
const rightEye = document.querySelector("#right-eye");

const tweenDur = 0.5;

const mouthPoints = {
  leftX: 200,
  leftY: 250,
  rightX: 300,
  rightY: 250,
  midX: 250,
  midY: 250
};

const mouthMeh = {
  leftX: 210,
  leftY: 250,
  rightX: 290,
  rightY: 250,
  midX: 250,
  midY: 250
};

const mouthSmile = {
  leftX: 210,
  leftY: 225,
  rightX: 290,
  rightY: 225,
  midX: 250,
  midY: 275
};

const mouthFrown = {
  leftX: 210,
  leftY: 250,
  rightX: 290,
  rightY: 250,
  midX: 250,
  midY: 225
};

const mouthWow = {
  leftX: 248,
  leftY: 250,
  rightX: 252,
  rightY: 250,
  midX: 250,
  midY: 250
};

const eyebrowPoints = {
  leftX: -10,
  leftY: 0,
  rightX: 10,
  rightY: 0,
  midX: 0,
  midY: -10
};

const eyebrowMeh = {
  leftX: -10,
  leftY: 0,
  rightX: 10,
  rightY: 0,
  midX: 0,
  midY: -10
};

const eyebrowFrown = {
  leftX: -10,
  leftY: -5,
  rightX: 10,
  rightY: 5,
  midX: 0,
  midY: -5
};

const eyebrowSmile = {
  leftX: -10,
  leftY: 5,
  rightX: 10,
  rightY: -5,
  midX: 0,
  midY: 5
};

const eyebrowWow = {
  leftX: -10,
  leftY: -10,
  rightX: 10,
  rightY: -20,
  midX: 0,
  midY: -30
};

const eyePoints = {
  r: 8
};

const eyesWideOpen = {
  r: 14
};

const eyesNormal = {
  r: 9
};

const eyesBeedie = {
  r: 3
};

initUI();

function initUI() {
  smileButton.addEventListener("click", () => {
    smile();
  });
  madButton.addEventListener("click", () => {
    mad();
  });
  sadButton.addEventListener("click", () => {
    sad();
  });
  mehButton.addEventListener("click", () => {
    meh();
  });
  evilButton.addEventListener("click", () => {
    evil();
  });

  wowButton.addEventListener("click", () => {
    wow();
  });
}

function changeMouth(newPoints) {
  gsap.to(mouthPoints, {
    leftX: newPoints.leftX,
    leftY: newPoints.leftY,
    rightX: newPoints.rightX,
    rightY: newPoints.rightY,
    midX: newPoints.midX,
    midY: newPoints.midY,
    duration: tweenDur,
    ease: "sine.inOut",
    onUpdate: () => {
      updateMouth();
    }
  });
}

function changeEyebrow(newPoints) {
  gsap.to(eyebrowPoints, {
    leftX: newPoints.leftX,
    leftY: newPoints.leftY,
    rightX: newPoints.rightX,
    rightY: newPoints.rightY,
    midX: newPoints.midX,
    midY: newPoints.midY,
    duration: tweenDur,
    ease: "sine.inOut",
    onUpdate: () => {
      updateEyebrows();
    }
  });
}

function changeEyes(newPoints) {
  gsap.to(eyePoints, {
    r: newPoints.r,
    duration: tweenDur,
    ease: "sine.inOut",
    onUpdate: () => {
      updateEyes();
    }
  });
}
function smile() {
  changeMouth(mouthSmile);
  changeEyebrow(eyebrowSmile);
  changeEyes(eyesNormal);
}

function mad() {
  changeMouth(mouthFrown);
  changeEyebrow(eyebrowFrown);
  changeEyes(eyesBeedie);
}

function sad() {
  changeMouth(mouthFrown);
  changeEyebrow(eyebrowSmile);
  changeEyes(eyesNormal);
}

function meh() {
  changeMouth(mouthMeh);
  changeEyebrow(eyebrowMeh);
  changeEyes(eyesNormal);
}

function evil() {
  changeMouth(mouthSmile);
  changeEyebrow(eyebrowFrown);
  changeEyes(eyesBeedie);
}

function wow() {
  changeMouth(mouthWow);
  changeEyebrow(eyebrowWow);
  changeEyes(eyesWideOpen);
}

function updateMouth() {
  const pathString = `M ${mouthPoints.leftX},${mouthPoints.leftY} Q ${mouthPoints.midX},${mouthPoints.midY}  ${mouthPoints.rightX},${mouthPoints.rightY}`;
  mouf.setAttribute("d", pathString);
}

function updateEyebrows() {
  const pathString = `M ${eyebrowPoints.leftX},${eyebrowPoints.leftY} Q ${eyebrowPoints.midX},${eyebrowPoints.midY}  ${eyebrowPoints.rightX},${eyebrowPoints.rightY}`;
  eyebrow.setAttribute("d", pathString);
}

function updateEyes() {
  leftEye.setAttribute("r", eyePoints.r);
  rightEye.setAttribute("r", eyePoints.r);
}
Run Pen

External CSS

  1. https://codepen.io/aokorodu/pen/poBNOgp.css

External JavaScript

  1. https://unpkg.com/gsap@3/dist/gsap.min.js
  2. https://cdn.tailwindcss.com