<div id="app">
<div id='header'>
 <h1>
      Box Shadow Generator
    </h1>
</div>
  <div id='info-box' :class="{ show: showInfo}">
    <h1>
      Info
    </h1>
    <span class='hide-info' @click="showInfo = false">×</span>
    <h3>Tips</h3>
    <div class='text'>
      <li> Click on the plus button to add a new shadow and change the settings as your like. </li>
      <li>Click on any of the boxes next to the add button to access and change particular shadow settings.  </li>
      <li> Use mousehweel on  any of the circular controls for more precise increase/decrease in value.</li>
    </div>
     <h3>Resources</h3>
    <div class='text'>
     <a href='https://github.com/xiaokaike/vue-color' target=_blank>Vue Color Picker</a>
     <br><a href='https://codepen.io/Brownsugar/pen/NaGPKy' target=_blank>Vue Color Implementation</a>
     <br><a href='https://www.npmjs.com/package/vue-circle-slider' target=_blank>Vue Circular Slider</a>
      <br>Split Vertical icon By <a href='https://thenounproject.com/term/split-vertical/1268414' target=_blank>Bhima</a>
      <br>Spread icon By <a href='https://thenounproject.com/term/spread/1863148' target=_blank>projecthayat</a>
      <br>Blur icon By <a href='https://thenounproject.com/term/blur/705680' target=_blank>abderraouf omara</a>
    </div>

    <h3>Projects</h3>
    <div class='text'>
      <li>Check my other projects at <a href='https://codepen.io/khr2003/' target=_blank>CodePen</a></li>

    </div>
  </div>
  <div id='controls'>
    <div id='reset' @click='resetControls'>
      RESET
    </div>
    <div id='info' @click="showInfo = !showInfo">
     🛈
    </div>

   
    <div id='box-shadows-container'>
      <span v-for='(shadow, index) in boxShadows' :style='{"background-color": shadow.color}' :class='{highlight: (currentShadow == index)}' @click='setShadow(index)'></span>
      <span class='add-transform' @click='addShadow'>+</span>
    </div> 

    <box-shadow-control :data='getData' v-if='boxShadows.length > 0' @delete-shadow='deleteShadow'></box-shadow-control>

  </div>

  <div class='show-effects'>
    <div class='transform-box' :style="style"></div>
  </div>
  <transition name="fade">
    <div id='css' v-show='style["box-shadow"] != ""'>
      <span v-if='style.transform != ""'>box-shadow: {{style["box-shadow"]}};</span>
    </div>
  </transition>

</div>

<template id='box-shadow-control'>
<div class='shadow-control'>
 <div class="control inset">
      <input id='inset-checkbox' type="checkbox" v-model='data.inset'>
      <label for='inset-checkbox'>
       <span class='switch'></span>
    </label>
      <span>Inset Shadow</span>
    </div>
  
  <div class='control color' ref="colorPicker" v-click-outside="hidePicker">
<input type='text' v-model='data.color' @focus='displayPicker = true' readonly/>
<span class='color-box' :style='{"background-color": data.color}'></span>
    <chrome-picker :value="data.color" @input="updatePicker" v-if="displayPicker"/>
  </div>
  
  <div class='control circle' @wheel='handleScroll("xoffset", $event)'>
    <circle-slider v-model="data.xoffset" :min="-50"
  :max="50">data.xoffset</circle-slider>
  <span class='icon xoffset'></span>
  <span class='amount'>{{data.xoffset}}px
    </span>
  </div>
  
  <div class='control circle'@wheel='handleScroll("yoffset", $event)'>
    <circle-slider v-model="data.yoffset" :min="-50"
  :max="50">data.yoffset</circle-slider>
  <span class='icon yoffset'></span>
  <span class='amount'>{{data.yoffset}}px
    </span>
  </div>
  
    <div class='control circle'@wheel='handleScroll("blur", $event)'>
    <circle-slider v-model="data.blur" :min="0"
  :max="100">data.blur</circle-slider>
  <span class='icon blur'></span>
  <span class='amount'>{{data.blur}}px
    </span>
  </div>
  
  <div class='control circle'@wheel='handleScroll("spread", $event)'>
    <circle-slider v-model="data.spread" :min="-50"
  :max="50">data.spread</circle-slider>
  <span class='icon spread'></span>
  <span class='amount'>{{data.spread}}px
    </span>
  </div>
  
  <div class='control delete' @click='$emit("delete-shadow")'>
  DELETE
  </div>

</div>
</template>
@import url("https://fonts.googleapis.com/css?family=Roboto:400,500,900");
@import url("https://fonts.googleapis.com/css?family=Handlee"); 

body {
  background-color: #fafafa;
  font-size: 16px;
  * {
    box-sizing: border-box;
    font-family: "Roboto", sans-serif;
  }
}

#app > #info-box {
  left: 0;
  transform: translateX(-100%);
  opacity: 0;
  background-color: white;
  z-index: 5;
  color: rgba(180, 180, 180, 1);
  font-size: 0.9em;
  
  &.show {
    transform: translateX(0);
    opacity: 1;
  }
  h1
  {
    position: relative;
    font-family: "Handlee";
    color: #3498db;
    
    &::after {
    content: "Info";
      position: absolute;
      top: 50%;
      left: 0%;
      font-size: 1.7em;
      line-height: 1em;
      transform: translate(0%, -50%);
      opacity: 0.1;
      font-weight: bold;
      color: transparentize(#3498db, 0.1);
      
  }
  }
  
  .hide-info
  {
    position: absolute;
    top: 1%;
    right: 1%;
    width: 1em;
    height: 1em;
    cursor: pointer;
    
  }
  h3 {
    font-weight: bold;
    color: rgba(180, 180, 180, 1);
  }
  
  .text {
    
    line-height: 1.5em;
    padding: 0 10px;
    li {
      padding: 10px 0;
      list-style: none;
    }
      a {
        font-weight: bold;
        color: rgba(180, 180, 180, 1);
      }
  }
}

#header
{
  position: fixed;
  top: 0;
  left: 0;
  height: 150px;
  width: 100vw;
  text-align: center;
  
   h1 {
    position: relative;
    padding: 40px 0 60px 0;
    color: darken(#3498db, 25%);
    font-size: 3em;
    font-weight: bold;
    line-height: 1.2em;
    font-family: "Handlee";
    z-index: -2;
    text-shadow: 10px 10px 5px rgba(139, 196, 234, 0.58);
  
  }
}
#controls,
#info-box {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 300px;
  padding: 0 30px;
  overflow-y: auto;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: 2;
  transition: all 0.2s ease-in;
  /* iOS Safari */
  -webkit-touch-callout: none;
  /* Safari */
  -webkit-user-select: none;
  /* Konqueror HTML */
  -khtml-user-select: none;
  /* Firefox */
  -moz-user-select: none;
  /* Internet Explorer/Edge */
  -ms-user-select: none;
  /* Non-prefixed version, currently supported by Chrome and Opera */
  user-select: none;
  &:hover {
    opacity: 1;
  }
  &.transparent:not(:hover):not(.info):not(.add-transform) {
    opacity: 1;
  }
  #reset {
    position: absolute;
    bottom: 1%;
    left: 5%;
    padding: 5px 10px;
    font-size: 0.7em;
    color: #e74c3c;
    border: 1px solid darken(#e74c3c, 5%);
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.2s;
    &:hover {
      background-color: #e74c3c;
      color: white;
    }
  }
  #info {
    position: absolute;
    top: 1%;
    left: 2%;
    font-size: 0.7em;
    color: #3498db;
    height: 1em;
    width: 1em;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.2s;
    font-size: 2em;
    display: flex;
    justify-content: center;
    align-items: center;
    &:hover {
      color: lighten(#3498db, 15%);
    }
  }
 
  h3 {
    width: 100%;
    text-align: left;
    text-transform: capitalize;
    font-size: 1em;
    color: rgba(180, 180, 180, 0.5);
    text-indent: 5%;
    margin-top: 15px;
    margin-bottom: 10px;
  }
  
  #box-shadows-container {
    display: flex;
    flex-wrap: wrap;
    margin-top: 25vh;
    
    span {
      border: 1px solid #3498db;
      width: 20%;
      display: flex;
      justify-content: center;
      align-content: center;
      color: darken(#3498db, 20%);
      margin: 3px;
      height: 25px;
      cursor: pointer;
      transition: all 0.3s;
      opacity: 0.5;
      
      &.highlight, &:hover
      {
        opacity: 1;
      }
      &.add-transform {
        opacity: 1;
      
        &:hover {
          background-color: lighten(#3498db, 10%);
        }
      }
    }
  }
  .shadow-control {
    margin: 30px 0;
    display: flex;
    flex-wrap: wrap;
    
    .control {
      margin: 10px 10px 20px 10px;
      width: 100px;
      height: 100px;
      position: relative;
    
      .amount {
         width: 20%;
        font-size: 0.7em;
        text-align: center;
        position: absolute;
        top: 100%;
        width: 100%;
        left: 0;

        &:hover {
          .delete {
            opacity: 1;
          }
        }
      }
      
      &.inset {
      display: flex;
      margin-bottom: 10px;
      color: rgba(180, 180, 180, 0.5);
      align-items: center;
      width: 100%;
      height: auto;
      
      input {
        display: none;
        &:checked+label {
          background-color: #3498db;
          .switch {
            left: 55%;
          }
        }
      }
      label {
        width: 30px;
        height: 15px;
        border-radius: 10px;
        background-color: gray;
        display: inline-block;
        margin-right: 10px;
        position: relative;
        transition: all 0.3s;
        cursor: pointer;
        span {
          background-color: white;
          height: 80%;
          width: 40%;
          position: absolute;
          border-radius: 50%;
          left: 5%;
          top: 9%;
          transition: all 0.3s; 
        }
      }
    }
      &.circle
      {
        height: 100px;
        width: 100px;
        z-index: 1;
        svg
        {
          width: 100%;
          z-index: 1;
        }
        
        .icon
      {
        position: absolute;
        top: 35%;
        left: 35%;
        width: 30%;
        height: 30%;
        display: block;
        z-index: 5;
        
        &::after
        {
          content: "";
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          filter: sepia(1);
        }
        
        &.xoffset, &.yoffset
        {
        &::after
        {
      background-image: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iTGF5ZXIgMSIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHg9IjBweCIgeT0iMHB4Ij48dGl0bGU+MDM8L3RpdGxlPjxwb2x5Z29uIHBvaW50cz0iNzYuOTggNjIuMTIgMjMuMDIgNjIuMTIgMjMuMDIgNjYuMTIgNDggNjYuMTIgNDggODguMDEgMzkuMzcgODEuMyAzNi45MiA4NC40NiA1MCA5NC42MyA2My4wOCA4NC40NiA2MC42MyA4MS4zIDUyIDg4LjAxIDUyIDY2LjEyIDc2Ljk4IDY2LjEyIDc2Ljk4IDYyLjEyIj48L3BvbHlnb24+PHBvbHlnb24gcG9pbnRzPSI3Ni45OCAzMy44OCA1MiAzMy44OCA1MiAxMS45OSA2MC42MyAxOC43IDYzLjA4IDE1LjU0IDUwIDUuMzcgMzYuOTIgMTUuNTQgMzkuMzcgMTguNyA0OCAxMS45OSA0OCAzMy44OCAyMy4wMiAzMy44OCAyMy4wMiAzNy44OCA3Ni45OCAzNy44OCA3Ni45OCAzMy44OCI+PC9wb2x5Z29uPjxyZWN0IHg9IjIzLjAyIiB5PSI0OCIgd2lkdGg9IjUzLjk1IiBoZWlnaHQ9IjQiPjwvcmVjdD48L3N2Zz4=');
        }
        }
        
        &.xoffset::after
        {
          transform: rotate(90deg);
        }
        
          &.blur::after
        {
          background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDgwMCA4MDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMwMDAwMDAiIGQ9Ik0zODguMTA0LDM3LjM5NWMtOS4wMjEsMTEuNjkyLTIyMC45OTIsMjg4LjYxMS0yMjAuOTkyLDQ5Ny44NDFjMCwxMzIuNzcxLDEwMC4xMjUsMjMyLjg5NiwyMzIuODk3LDIzMi44OTYgICBjMTMyLjc2OCwwLDIzMi44NzgtMTAwLjEyNSwyMzIuODc4LTIzMi44OTZjMC0yMDkuMjMtMjExLjk2NC00ODYuMTQ5LTIyMC45OTItNDk3Ljg0MSAgIEM0MDYuMTk5LDMwLjAyNiwzOTMuNzk5LDMwLjAyNiwzODguMTA0LDM3LjM5NXogTTQwMC4wMDksNzM4LjA2OWMtMTE3LjUzNSwwLTIwMi44MzQtODUuMjk5LTIwMi44MzQtMjAyLjgzNCAgIGMwLTE3MS4zNzMsMTU3LjczMy00MDEuMjAyLDIwMi44MzQtNDYzLjM5NmM0NS4wOSw2Mi4xOTUsMjAyLjgxNSwyOTIuMDIzLDIwMi44MTUsNDYzLjM5NiAgIEM2MDIuODI0LDY1Mi43NzEsNTE3LjUyNCw3MzguMDY5LDQwMC4wMDksNzM4LjA2OXoiPjwvcGF0aD48cGF0aCBmaWxsPSIjMDAwMDAwIiBkPSJNMzg0Ljk3Nyw2ODkuNTU2YzAsOC4yOTQsNi43MjMsMTUuMDMxLDE1LjAzMiwxNS4wMzFjOTguMTI1LDAsMTY5LjMzMy03MS4yMjMsMTY5LjMzMy0xNjkuMzUyICAgYzAtOC4yOTMtNi43MjQtMTUuMDMxLTE1LjAzMS0xNS4wMzFjLTguMjk0LDAtMTUuMDMxLDYuNzM4LTE1LjAzMSwxNS4wMzFjMCw4MC43MDUtNTguNTY5LDEzOS4yODktMTM5LjI3MSwxMzkuMjg5ICAgQzM5MS43LDY3NC41MjQsMzg0Ljk3Nyw2ODEuMjQ3LDM4NC45NzcsNjg5LjU1NnoiPjwvcGF0aD48L2c+PC9zdmc+");
        }
        &.spread::after
        {
          background-image: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjMDAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgOTYgOTYiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDk2IDk2IiB4bWw6c3BhY2U9InByZXNlcnZlIj48Zz48cGF0aCBkPSJNMTIuOTc3LDExLjE2MWMzLjIxMiwwLDYuNDI0LDAsOS42MzcsMGMwLjQ0MSwwLDAuNzc3LTAuMTYxLDEuMDE3LTAuNDAyYzAuMDE2LTAuMDEyLDAuMDI4LTAuMDI2LDAuMDQyLTAuMDQgICBzMC4wMjctMC4wMjcsMC4wMzktMC4wNDJjMC4yNDEtMC4yNCwwLjQwMi0wLjU3NiwwLjQwMi0xLjAxN2MwLTAuMzMzLDAtMC42NjcsMC0xYzAtMC44MTgtMC42ODMtMS41LTEuNS0xLjUgICBjLTQuOTg5LDAtOS45NzksMC0xNC45NjYsMGMtMC44MTgsMC0xLjUsMC42ODItMS41LDEuNWMwLDQuOTg4LDAsOS45NzgsMCwxNC45NjdjMCwwLjgxNywwLjY4MiwxLjUsMS41LDEuNWMwLjMzMywwLDAuNjY2LDAsMSwwICAgYzAuODE2LDAsMS41LTAuNjgzLDEuNS0xLjVjMC0zLjIxMywwLTYuNDI2LDAtOS42NGM3LjAwOCw3LjAwOSwxNC4wMTYsMTQuMDE3LDIxLjAyMiwyMS4wMjNjMC41NzcsMC41NzgsMS41NDMsMC41NzgsMi4xMjEsMCAgIGMwLjIzNS0wLjIzNSwwLjQ3My0wLjQ3MSwwLjcwNy0wLjcwN2MwLjU3OC0wLjU3OCwwLjU3OC0xLjU0MywwLTIuMTIxQzI2Ljk5LDI1LjE3NywxOS45ODIsMTguMTY5LDEyLjk3NywxMS4xNjF6Ij48L3BhdGg+PHBhdGggZD0iTTg4LjM1NCw3LjE2MWMtNC45ODgsMC05Ljk3OCwwLTE0Ljk2NywwYy0wLjQ0MSwwLTAuNzc3LDAuMTYtMS4wMTgsMC40MDFjLTAuMDE2LDAuMDEzLTAuMDI3LDAuMDI2LTAuMDQxLDAuMDQgICBjLTAuMDE0LDAuMDE1LTAuMDI3LDAuMDI3LTAuMDM5LDAuMDQyYy0wLjI0MSwwLjI0LTAuNDAyLDAuNTc2LTAuNDAyLDEuMDE4YzAsMC4zMzMsMCwwLjY2NywwLDFjMCwwLjgxNywwLjY4NCwxLjUsMS41LDEuNSAgIGMzLjIxMywwLDYuNDI2LDAsOS42MzksMEM3Ni4wMTgsMTguMTcsNjkuMDEsMjUuMTc4LDYyLjAwMywzMi4xODVjLTAuNTc4LDAuNTc4LTAuNTc4LDEuNTQzLDAsMi4xMjEgICBjMC4yMzUsMC4yMzYsMC40NzIsMC40NzIsMC43MDcsMC43MDdjMC41NzgsMC41NzgsMS41NDMsMC41NzgsMi4xMjEsMGM3LjAwOC03LjAwOCwxNC4wMTctMTQuMDE2LDIxLjAyMi0yMS4wMjMgICBjMCwzLjIxNCwwLDYuNDI3LDAsOS42NGMwLDAuODE3LDAuNjg0LDEuNSwxLjUsMS41YzAuMzM0LDAsMC42NjgsMCwxLDBjMC44MTcsMCwxLjUtMC42ODMsMS41LTEuNWMwLTQuOTg5LDAtOS45NzksMC0xNC45NjcgICBDODkuODU0LDcuODQzLDg5LjE3MSw3LjE2MSw4OC4zNTQsNy4xNjF6Ij48L3BhdGg+PHBhdGggZD0iTTg4LjM1NCw3MC44NzNjLTAuMzMyLDAtMC42NjYsMC0xLDBjLTAuODE2LDAtMS41LDAuNjg0LTEuNSwxLjVjMCwzLjIxMywwLDYuNDI2LDAsOS42MzkgICBjLTcuMDA4LTcuMDA4LTE0LjAxNi0xNC4wMTQtMjEuMDIyLTIxLjAyMWMtMC41NzgtMC41NzgtMS41NDMtMC41NzgtMi4xMjEsMGMtMC4yMzUsMC4yMzQtMC40NzIsMC40NzMtMC43MDcsMC43MDcgICBjLTAuNTc4LDAuNTc4LTAuNTc4LDEuNTQzLDAsMi4xMjFjNy4wMDgsNy4wMDgsMTQuMDE3LDE0LjAxNiwyMS4wMjIsMjEuMDIxYy0zLjIxMywwLTYuNDI2LDAtOS42MzksMGMtMC44MTYsMC0xLjUsMC42ODQtMS41LDEuNSAgIGMwLDAuMzM0LDAsMC42NjgsMCwxYzAsMC44MTgsMC42ODQsMS41LDEuNSwxLjVjNC45ODksMCw5Ljk3OSwwLDE0Ljk2NywwYzAuODE3LDAsMS41LTAuNjgyLDEuNS0xLjVjMC00Ljk4OCwwLTkuOTc5LDAtMTQuOTY3ICAgQzg5Ljg1NCw3MS41NTcsODkuMTcxLDcwLjg3Myw4OC4zNTQsNzAuODczeiI+PC9wYXRoPjxwYXRoIGQ9Ik0zMy4yOTEsNjAuOTljLTAuMzEzLTAuMzEzLTAuNjYyLTAuNDM4LTEuMDAyLTAuNDM4Yy0wLjAyLTAuMDAyLTAuMDM5LDAtMC4wNTktMC4wMDJjLTAuMDIxLDAuMDAyLTAuMDM5LDAtMC4wNiwwLjAwMiAgIGMtMC4zNCwwLTAuNjg5LDAuMTI1LTEuMDAyLDAuNDM4Yy03LjAwOCw3LjAwOC0xNC4wMTYsMTQuMDE0LTIxLjAyMiwyMS4wMjFjMC0zLjIxMywwLTYuNDI2LDAtOS42MzljMC0wLjgxOC0wLjY4NC0xLjUtMS41LTEuNSAgIGMtMC4zMzQsMC0wLjY2NywwLTEsMGMtMC44MTgsMC0xLjUsMC42ODItMS41LDEuNWMwLDQuOTg4LDAsOS45NzcsMCwxNC45NjdjMCwwLjgxNiwwLjY4MiwxLjUsMS41LDEuNWM0Ljk4NywwLDkuOTc3LDAsMTQuOTY2LDAgICBjMC44MTcsMCwxLjUtMC42ODQsMS41LTEuNWMwLTAuMzM0LDAtMC42NjgsMC0xYzAtMC44MTgtMC42ODMtMS41LTEuNS0xLjVjLTMuMjEzLDAtNi40MjUsMC05LjYzNywwICAgYzcuMDA4LTcuMDA4LDE0LjAxNS0xNC4wMTYsMjEuMDIxLTIxLjAyM2MwLjU3OC0wLjU3NiwwLjU3OC0xLjU0MywwLTIuMTIxQzMzLjc2NCw2MS40NjEsMzMuNTI2LDYxLjIyNSwzMy4yOTEsNjAuOTl6Ij48L3BhdGg+PHBhdGggZD0iTTQ4LjQ0OCwzNC44NjdjLTAuMTM3LTAuMDMzLTAuMjgyLTAuMDU0LTAuNDQ4LTAuMDQ1Yy0wLjE2Ni0wLjAwOS0wLjMxMiwwLjAxMy0wLjQ0OSwwLjA0NiAgIEMzMS4wNDIsMzYuMTk3LDMxLjE4Niw2MC4yNzEsNDgsNjEuMThjNy40MzgsMC40MDIsMTIuODExLTYuMzMyLDEzLjE4LTEzLjE3OUM2MS41NzMsNDAuNzI2LDU1LjEzOSwzNS40NDEsNDguNDQ4LDM0Ljg2N3oiPjwvcGF0aD48L2c+PC9zdmc+");
        }
      }
      
      }
      &.color {
        height: auto;
        position: relative;
        flex-grow: 1;
        width: 100%;
        
        >input {
          width: 100%;
          padding: 6px;
          border-radius: 5px;
          border: 1px solid rgba(0, 0, 0, 0.3);
          outline: 0;
        }
        >span {
          position: absolute;
          right: 1px;
          top: 1px;
          height: calc(100% - 2px);
          width: 15%;
          background: gray;
          border-radius: 0 5px 5px 0;
          pointer-events: none;
        }
        .vc-chrome {
          position: absolute;
          top: 35px;
          right: 0;
          z-index: 9;
          width: 100%;
        }
      }
        &.delete {
          margin-top: 30px;
        
          height: auto;
        width: 100%;
           padding: 5px 10px;
              font-size: 0.7em;
              color: #e74c3c;
              border: 1px solid darken(#e74c3c, 5%);
              border-radius: 5px;
              cursor: pointer;
              transition: all 0.2s;
              text-align: center;
              &:hover {
                background-color: #e74c3c;
                color: white;
              }
          }
    }
  }
}

.show-effects {
  position: fixed;
  left: 70%;
  z-index: 1;
  top: 50%;
  transform: translate(-50%, -50%);
  
  width: 30vw;
  height: 30vh;
  &.transform-3d {
    transform-style: preserve-3d;
  }
  .transform-box {
    width: 100%;
    left: 0%;
    top: 0%;
    height: 100%;
    background-color: #2980b9;
    position: absolute;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    font-size: 2em;
    transition: all 0.2s;
  }
}

#css {
  position: fixed;
  bottom: 1vh;
  width: calc(90vw - 235px);
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 1vw / 2vh;
  right: 5vw;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  font-size: 1em;
  color: black;
  z-index: 1;
  opacity: 0.3;
  transition: all 0.2s;
  padding: 10px;
  &:hover {
    opacity: 1;
  }
  span {
    padding: 5px;
  }
}

// Transition
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}


/*
Split Vertical icon designed by Bhima on the @NounProject. https://thenounproject.com/term/split-vertical/1268414

spread icon designed by projecthayat on the @NounProject. https://thenounproject.com/term/spread/1863148

Blur icon designed by abderraouf omara on the @NounProject. https://thenounproject.com/term/blur/705680
*/
View Compiled
// https://stackoverflow.com/a/42389266/529024
Vue.directive('click-outside', {
  bind: function(el, binding, vnode) {
    this.event = function(event) {
      if (!(el == event.target || el.contains(event.target))) {
        vnode.context[binding.expression](event);
      }
    };
    document.body.addEventListener('click', this.event)
  },
  unbind: function(el) {
    document.body.removeEventListener('click', this.event)
  },
});

var chrome = VueColor.Chrome;
Vue.component("box-shadow-control", {
  template: "#box-shadow-control",
  props: ["data"],
  components: {
    'chrome-picker': chrome
  },
  data() { 
    return {
      displayPicker: false
    }
  },
  methods: {
    handleScroll: function(item, e) {
      var element = e.target;
      var max = (item == 'blur') ? 100 : 50;
      var min = (item == 'blur') ? 0 : -50;
      
      var current = this.data[item];

      // Scrolling up
      if (e.deltaY < 0) {
        if (current < max)
          this.data[item] = this.data[item] + 1;
      }
      // Scrolling down
      if (e.deltaY > 0) {
        if (current > min)
          this.data[item] = this.data[item] - 1;

      }
    },
    updatePicker: function(color) {
      if (color.rgba.a == 1) {
        this.data.color = color.hex;
      } else {
        this.data.color = "rgba(" + color.rgba.r + ", " + color.rgba.g + ", " + color.rgba.b + ", " + color.rgba.a + ")";
      }
    },
    hidePicker: function() {
      this.displayPicker = false;
    }
  }
});

new Vue({
  el: "#app",

  data() {
    return {
      style: {
        "box-shadow": ""
      },
      showInfo: false,
      currentShadow: 0,
      boxShadows: [{
        inset: false,
        xoffset: 10,
        yoffset: 10,
        blur: 0,
        spread: 0,
        color: "black"
      }],
      boxShadowTemplate: {
        inset: false,
        xoffset: 10,
        yoffset: 10,
        blur: 0,
        spread: 0,
        color: "black"
      }
    };
  },
  computed: {
    getData: function() {
      return this.boxShadows[this.currentShadow];
    }
  },
  methods: {
    resetControls: function(e) { 
      Object.assign(this.$data, this.$options.data.apply(this));
    },
    addShadow: function() {
      // this code >> JSON.parse(JSON.stringify(transform)) << helps copy object by value not by reference
      var newShadow = JSON.parse(JSON.stringify(this.boxShadowTemplate));

      //newShadow.id = this.uid();
      this.boxShadows.push(newShadow);
      this.setShadow(this.boxShadows.length - 1);
    },
    setShadow: function(shadowIndex) {
      this.currentShadow = shadowIndex;
    },
    deleteShadow: function() {
// First delete element
this.boxShadows.splice(this.currentShadow, 1);

  // Second set other elements (if any)
  var length = this.boxShadows.length;
  if(length > 0)
    this.setShadow(length - 1);
  
    },
    getStyle: function() {
        var final = [];
        // Loop through set box shadows and "flatten"
        this.boxShadows.forEach(shadow => {
          var shadowFinal = [];

          // Loop through each box shadow set and format accordingly
          for (const item in shadow) {

            // if inset is set add the word inset
            if (item == 'inset') {
              if (shadow[item] == true)
                shadowFinal.push("inset");
            } else if (item == 'color') {
              // Color does not require "px" affix so add as is
              shadowFinal.push(shadow[item]);
            } else {
              // For all other properites add "px"
              shadowFinal.push(shadow[item] + "px");
            }
          }

          // Join flatten properties
          final.push(
            shadowFinal.join(" ")
          );
        });

        // Join everything together and assign
        this.style["box-shadow"] = final.join(", ");
      }
  },
  watch: {
    boxShadows: {
      handler: function(){
        this.getStyle();
      },
      deep: true
    }
  },
   mounted() {
   this.getStyle();
  }
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/vue-color/2.7.0/vue-color.min.js
  3. https://unpkg.com/vue-circle-slider