<div id="app">
   <div class="icon-container">
      <div id="eaicon" class="shape-square bg-dark">
         <div class="background bg-redorange"></div>
         <div class="icon">
            <img class="face" src="https://cldup.com/MitITBt1_i.png">
            <img class="eyebase" src="https://cldup.com/FN7dGVFgVA.png">
            <img class="eyes" src="https://cldup.com/CRO0fbUPUk.png">
            <img class="mouth" src="https://cldup.com/EFgudoA6nX.png">
         </div>
         <div class="border bg-redorange"></div>
      </div>
   </div>
   <form id="editor">
      <fieldset class="general">
         <legend>General</legend>
         <div>
            <label for="icon_shape">Shape:</label>
            <select id="icon_shape">
               <option value="shape-square">Square</option>
               <option value="shape-rounded">Rounded</option>
               <option value="shape-circle">Circle</option>
            </select>
         </div>
         <div>
            <label for="icon_background_color">Background Color:</label>
            <select id="icon_background_color">
               <option value="bg-lime">Lime</option>
               <option value="bg-green">Green</option>
               <option value="bg-yellow">Yellow</option>
               <option value="bg-orange">Orange</option>
               <option value="bg-cyan">Cyan</option>
               <option value="bg-black">Black</option>
               <option value="bg-redorange" selected>Redorange</option>
               <option value="bg-blue">Blue</option>
               <option value="bg-purple">Purple</option>
               <option value="bg-red">Red</option>
               <option value="custom">Custom</option>
            </select>
         </div>
         <div name="icon_background_color_custom" style="display: none;">
            <label for="icon_background_color_custom_color">Background Custom Color:</label>
            <input id="icon_background_color_custom_color" type="text"></input>
         </div>
         <div>
            <label for="icon_border_color">Border Color:</label>
            <select id="icon_border_color">
               <option value="bg-lime">Lime</option>
               <option value="bg-green">Green</option>
               <option value="bg-yellow">Yellow</option>
               <option value="bg-orange">Orange</option>
               <option value="bg-cyan">Cyan</option>
               <option value="bg-black">Black</option>
               <option value="bg-redorange" selected>Redorange</option>
               <option value="bg-blue">Blue</option>
               <option value="bg-purple">Purple</option>
               <option value="bg-red">Red</option>
               <option value="custom">Custom</option>
            </select>
         </div>
         <div name="icon_border_color_custom" style="display: none;">
            <label for="icon_border_color_custom_color">Border Custom Color:</label>
            <input id="icon_border_color_custom_color" type="text"></input>
         </div>
      </fieldset>
      <fieldset class="eyes">
         <legend>Eyes</legend>
         <div>
            <label for="eyes_shape">Shape:</label>
            <select id="eyes_shape">
               <option value="normal">Normal</option>
               <option value="stick">Stick</option>
               <option value="circle">Circle</option>
               <option value="circle2">Circle2</option>
               <option value="phonecat">電話猫</option>
            </select>
         </div>
         <div>
            <label for="eyes_hue">Hue:</label>
            <input id="eyes_hue" type="range" value="0" min="0" max="360"></input>
            <output name="eyes_hue_value" id="eyes_hue_value">0</output>
         </div>
         <div>
            <label for="eyes_saturation">Saturation:</label>
            <input id="eyes_saturation" type="range" value="100" min="0" max="300"></input>
            <output name="eyes_saturation_value" id="eyes_saturation_value">100</output>
         </div>
         <div>
            <label for="eyes_brightness">Brightness:</label>
            <input id="eyes_brightness" type="range" value="100" min="0" max="300"></input>
            <output name="eyes_brightness_value" id="eyes_brightness_value">100</output>
         </div>

      </fieldset>
      <fieldset class="mouth">
         <legend>Mouth</legend>
         <div>
            <label for="mouth_shape">Shape:</label>
            <select id="mouth_shape">
               <option value="none">None</option>
               <option value="open" selected>Open</option>
               <option value="smile">Smile</option>
               <option value="close">Closed</option>
               <option value="anger">Anger</option>
               <option value="circle">Circle</option>
               <option value="phonecat">電話猫</option>
            </select>
         </div>
      </fieldset>
      <fieldset class="eyebrows">
         <legend>Eyebrows</legend>
         <div>
            <label for="">Shape:</label>
            <select id="" disabled>
               <option value="">Unavailable</option>
            </select>
         </div>
      </fieldset>
      <fieldset class="hair">
         <legend>Hair</legend>
         <div>
            <label for="">Color:</label>
            <select id="" disabled>
               <option value="">Unavailable</option>
            </select>
         </div>
      </fieldset>
      <fieldset class="options">
         <legend>Options</legend>
         <div>
            <label for="bleeding">Bleeding:</label>
            <input type="checkbox" id="option_bleeding" name="bleeding" value="bleeding" disabled />
            <!-- https://mstdn.maud.io/users/pikepikeid/statuses/100702747059289318 -->
         </div>
      </fieldset>
      <fieldset class="ebi">
         <legend>EBI</legend>
         <span id="ebi">🦐</span>
      </fieldset>
   </form>
</div>

<footer>
   <p>
      <span class="title">CUSTOM EAI 2D</span> by
   </p>
   <address>
      <a href="//mizle.net" target="_blank"><img src="//github.com/eai04191.png">Eai</a>.
   </address>
</footer>
// $width: 256px;
// $height: 256px;
$width: 512px;
$height: 512px;

$dark: #242f3d;
$light: #e5eaf0;

$lime: #90ba3c;
$green: #55943c;
$yellow: #ded357;
$orange: #eea557;
$cyan: #57cbde;
$black: #808080;
$redorange: #de6957;
$blue: #3f4ed9;
$purple: #574ede;
$red: #de4657;

:root {
   font-family: "Open Sans", sans-serif;
   font-weight: 400;
   body {
      background-color: $dark;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      animation: gradation 60s infinite;
   }
   footer {
      display: flex;
      color: #9396a4;
      background: #34363f;
      border-top: 1px solid #3f414b;
      position: fixed;
      left: 0;
      bottom: 0;
      width: 100%;
      padding: 0.5rem;
      box-sizing: border-box;
      .title {
         font-weight: 700;
      }
      p {
         margin: 0;
         max-width: 1920px;
      }
      address {
         font-style: inherit;
         a {
            color: inherit;
         }
         img {
            width: 1rem;
            height: 1rem;
            border-radius: 12%;
            margin: 0 0.25rem;
         }
      }
   }
}

@keyframes gradation {
   0% {
      background-color: rgba($lime, 0.25);
   }
   10% {
      background-color: rgba($green, 0.25);
   }
   20% {
      background-color: rgba($yellow, 0.25);
   }
   30% {
      background-color: rgba($orange, 0.25);
   }
   40% {
      background-color: rgba($cyan, 0.25);
   }
   50% {
      background-color: rgba($black, 0.25);
   }
   60% {
      background-color: rgba($redorange, 0.25);
   }
   70% {
      background-color: rgba($blue, 0.25);
   }
   80% {
      background-color: rgba($purple, 0.25);
   }
   90% {
      background-color: rgba($red, 0.25);
   }
   100% {
      background-color: rgba($lime, 0.25);
   }
}

:root {
   .bg-dark {
      background-color: $dark;
   }

   .bg-lime {
      background-color: $lime;
   }
   .bg-green {
      background-color: $green;
   }
   .bg-yellow {
      background-color: $yellow;
   }
   .bg-orange {
      background-color: $orange;
   }
   .bg-cyan {
      background-color: $cyan;
   }
   .bg-black {
      background-color: $black;
   }
   .bg-redorange {
      background-color: $redorange;
   }
   .bg-blue {
      background-color: $blue;
   }
   .bg-purple {
      background-color: $purple;
   }
   .bg-red {
      background-color: $red;
   }
}

#app {
   overflow: hidden;
   position: relative;
   padding: 80px;
   width: 70%;
   max-width: 1000px;
   color: white;
   &::before {
      background-color: rgba($dark, 0.75);
      position: absolute;
      top: 0;
      left: 0;
      content: " ";
      display: block;
      width: 100%;
      height: 100%;
      filter: blur(1px);
   }

   .icon-container {
      position: relative;
      width: 100%;
      height: 100%;
      &::before {
         font-family: "Open Sans", sans-serif;
         font-weight: 700;
         content: "PREVIEW";
         position: absolute;
         top: -2rem;
         left: 0;
         font-size: 4rem;
         line-height: 1;
         color: rgba($dark, 0.25);
      }
      #eaicon {
         position: relative;
         width: $width;
         height: $height;
         overflow: hidden;
         margin: auto;
         margin-bottom: 40px;
         .background {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            filter: blur(20px);
         }
         .border {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
            mask-size: cover;
            // TODO: 内側のシャドウ
            // box-shadow: inset 0 0 10px 2px rgba(0, 0, 0, 0.1);
         }
         .icon {
            .face {
               width: $width;
               height: $height;
               position: relative;
               filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.5));
            }
            .eyebase,
            .eyes,
            .mouth {
               width: $width;
               height: $height;
               position: absolute;
               top: 0;
               left: 0;
            }
         }

         &.shape-square {
            .border {
               mask-image: url(https://cldup.com/N3d-dGMJo0.png);
            }
         }
         &.shape-rounded {
            &,
            .background,
            .border,
            .face img {
               border-radius: 12%;
            }
            .border {
               mask-image: url(https://cldup.com/A7B1owThlI.png);
            }
         }
         &.shape-circle {
            &,
            .background,
            .border,
            .face img {
               border-radius: 50%;
            }
            .border {
               mask-image: url(https://cldup.com/09o5ejxIeB.png);
            }
         }
      }
   }
   #editor {
      display: flex;
      flex-wrap: wrap;
      position: relative;
      margin: auto;
      &::before {
         font-family: "Open Sans", sans-serif;
         font-weight: 700;
         content: "EDITOR";
         position: absolute;
         bottom: -2rem;
         right: 0;
         font-size: 4rem;
         line-height: 1;
         color: rgba($dark, 0.25);
      }
      fieldset {
         flex-grow: 1;
         display: flex;
         flex-direction: column;
         margin: 0 2px;
         margin-bottom: 10px;
         box-sizing: border-box;
         padding: 1rem;
         legend {
            padding: 0 0.5rem;
         }
         div {
            display: flex;
            flex-direction: row;
            align-items: center;
            input,
            select {
               width: 10rem;
               height: 2rem;
            }
            label {
               flex-grow: 1;
            }
            output {
               width: 3rem;
            }
         }
         &.general {
         }
         &.eyes {
            min-width: calc(50% - 4px);
         }
         &.mouth {
         }
         &.eyebrows {
         }
         &.hair {
         }
         &.ebi {
            text-align: center;
            span {
               font-size: 3rem;
               line-height: 1;
               margin: 0;
               cursor: default;
               user-select: none;
            }
         }
      }
   }
   .animation-spin {
      animation: spin 1.5s cubic-bezier(1, -0.6, 0, 1.65);
   }

   @keyframes spin {
      0% {
         transform: rotate(0deg);
      }
      100% {
         transform: rotate(360deg);
      }
   }
}
View Compiled
document.addEventListener(
   "DOMContentLoaded",
   function() {
      // General
      document.getElementById("icon_shape").onchange = eShape;
      document.getElementById(
         "icon_background_color"
      ).onchange = eBackgroundColor;
      document.getElementById(
         "icon_background_color_custom_color"
      ).onchange = eBackgroundColorCustom;
      document.getElementById("icon_border_color").onchange = eBorderColor;
      document.getElementById(
         "icon_border_color_custom_color"
      ).onchange = eBorderColorCustom;

      // Eyes
      document.getElementById("eyes_shape").onchange = eEyesShape;
      document.getElementById("eyes_hue").oninput = eEyesHue;
      document.getElementById("eyes_saturation").oninput = eEyesSaturation;
      document.getElementById("eyes_brightness").oninput = eEyesBrightness;

      // Mouth
      document.getElementById("mouth_shape").onchange = eMouthShape;

      // Other
      document.getElementById("ebi").onmouseover = eEbi;
   },
   false
);

function eShape(event) {
   removeShapeClass();
   addShapeClass(event.target.value);

   function removeShapeClass() {
      const eaicon = document.getElementById("eaicon");
      // アロー関数何もわからん
      eaicon.className.split(" ").forEach(function(c) {
         if (c.match(/shape-*/)) {
            eaicon.classList.remove(c);
         }
      });
   }
   function addShapeClass(shape) {
      const eaicon = document.getElementById("eaicon");
      eaicon.classList.add(shape);
   }
}

function eBackgroundColor(event) {
   removeBackgroundColorClass();
   if (event.target.value == "custom") {
      openBackgroundColorCustom();
   } else {
      addBackgroundColorClass(event.target.value);
   }

   function removeBackgroundColorClass() {
      const background = document.querySelector("#eaicon .background");
      background.className.split(" ").forEach(function(c) {
         if (c.match(/bg-*/)) {
            background.classList.remove(c);
         }
      });
   }
   function addBackgroundColorClass(color) {
      const background = document.querySelector("#eaicon .background");
      background.classList.add(color);
   }

   function openBackgroundColorCustom() {
      const backgroundColorCustom = document.querySelector(
         "[name='background_color_custom']"
      );
      backgroundColorCustom.style.display = "inherit";
   }
}

function eBackgroundColorCustom(event) {
   const background = document.querySelector("#eaicon .background");
   background.style.backgroundColor = event.target.value;
}

function eBorderColor(event) {
   removeBorderColorClass();
   if (event.target.value == "custom") {
      openBorderColorCustom();
   } else {
      addBorderColorClass(event.target.value);
   }

   function removeBorderColorClass() {
      const border = document.querySelector("#eaicon .border");
      border.className.split(" ").forEach(function(c) {
         if (c.match(/bg-*/)) {
            border.classList.remove(c);
         }
      });
   }
   function addBorderColorClass(color) {
      const border = document.querySelector("#eaicon .border");
      border.classList.add(color);
   }

   function openBorderColorCustom() {
      const borderColorCustom = document.querySelector(
         "[name='border_color_custom']"
      );
      borderColorCustom.style.display = "inherit";
   }
}

function eBorderColorCustom(event) {
   const border = document.querySelector("#eaicon .border");
   border.style.backgroundColor = event.target.value;
}

function eEyesShape(event) {
   const value = event.target.value;
   const eyes = document.querySelector("#eaicon .icon .eyes");
   const eyebase = document.querySelector("#eaicon .icon .eyebase");

   switch (value) {
      case "stick":
         eyebase.style.visibility = "hidden";
         eyes.src = "https://cldup.com/B01QF5P5eJ.png";
         break;
      case "circle":
         eyebase.style.visibility = "hidden";
         eyes.src = "https://cldup.com/9P3fLi7XMh.png";
         break;
      case "circle2":
         eyebase.style.visibility = "hidden";
         eyes.src = "https://cldup.com/Jv8_8PpQic.png";
         break;
      case "phonecat":
         eyebase.style.visibility = "hidden";
         eyes.src = "https://cldup.com/SlYAJzrZ_S.png";
         break;
      case "normal":
      default:
         eyebase.style.visibility = "visible";
         eyes.src = "https://cldup.com/CRO0fbUPUk.png";
         break;
   }
}

function eEyesHue(event) {
   const value = event.target.value;
   const eyes = document.querySelector("#eaicon .icon .eyes");
   document.getElementById("eyes_hue_value").value = value;
   eyes.style.filter = eyes.style.filter.replace(/hue-rotate\(\d+deg\)/g, "");
   eyes.style.filter += `hue-rotate(${value}deg)`;
}

function eEyesSaturation(event) {
   const value = event.target.value;
   const eyes = document.querySelector("#eaicon .icon .eyes");
   document.getElementById("eyes_saturation_value").value = value;
   eyes.style.filter = eyes.style.filter.replace(/saturate\(\d+%\)/g, "");
   eyes.style.filter += `saturate(${value}%)`;
}

function eEyesBrightness(event) {
   const value = event.target.value;
   const eyes = document.querySelector("#eaicon .icon .eyes");
   document.getElementById("eyes_brightness_value").value = value;
   eyes.style.filter = eyes.style.filter.replace(/brightness\(\d+%\)/g, "");
   eyes.style.filter += `brightness(${value}%)`;
}

function eMouthShape(event) {
   const value = event.target.value;
   const mouth = document.querySelector("#eaicon .icon .mouth");

   switch (value) {
      case "none":
         mouth.src = "";
         break;
      case "smile":
         mouth.src = "https://cldup.com/DipipKtMUt.png";
         break;
      case "open":
         mouth.src = "https://cldup.com/_Cc07lJcE6.png";
         break;
      case "anger":
         mouth.src = "https://cldup.com/oaz8IJZ1aN.png";
         break;
      case "close":
         mouth.src = "https://cldup.com/zcucjx3bXw.png";
         break;
      case "circle":
         mouth.src = "https://cldup.com/VA9yQrEuMu.png";
         break;
      case "phonecat":
         mouth.src = "https://cldup.com/hNjRvYeosx.png";
         break;
   }
}

function eEbi(event) {
   const ebi = document.getElementById("ebi");

   ebi.addEventListener("animationend", function(event) {
      removeAnimationClass(ebi);
   });

   addAnimationClass(ebi, "spin");

   function removeAnimationClass(element) {
      element.className.split(" ").forEach(function(c) {
         if (c.match(/animation-*/)) {
            element.classList.remove(c);
         }
      });
   }

   function addAnimationClass(element, animation) {
      element.classList.add(`animation-${animation}`);
   }
}
Run Pen

External CSS

  1. https://fonts.googleapis.com/css?family=Open+Sans:400,700

External JavaScript

  1. https://cdn.rangetouch.com/1.0.5/rangetouch.js