Menu overlay

by enagu

HTML

<div class="menu">
  <div class="header">
    <h3 class="title">Configuration</h3>
    <div class="search">
      <input type="text" class="input-search" placeholder="search configuration">
    </div>
  </div>
  <div class="content">
    <div class="section">
      
    </div>
    <div class="section-content">
      <div class="configurations">
        <div class="configurations-submenu">
          <div class="submenu-header">
            <span class="submenu-title">
              Scroll
            </span>
          </div>
          <div class="configuration"><input type="radio" name="scroll_type">Normal</div>
          <div class="configuration"><input type="radio" name="scroll_type">Stop on hover</div>
        </div>
        
        <div class="configuration"><input type="checkbox">hide timestamps in vod chat</div>
        
        <div class="configurations-submenu">
          <div class="submenu-header">
            <span class="submenu-title">
              Quick ban
            </span>
          </div>
          <div class="configuration key-selection">
            <div class="key-holder">Control</div>
            <div class="key-description"> + click on user to ban</div>
          </div>
        </div>
        
        <div class="configurations-submenu">
          <div class="submenu-header">
            <span class="submenu-title">
              Initial Position
            </span>
          </div>
          <div class="configuration overlay-position-size">          
            <div class="flex-vertical">
              <div class="flex-horizontal">
                <!-- Fixed square (screen) -->
                <div class="overlay-position">
                  <!-- movable square -->
                  <div class="overlay-position-movable"></div>
                </div>

                <!-- intial width -->
                <input type="range" id="range-overlay-height" orient="vertical"  />
              </div>
              
              <!-- intial...

SCSS

$second-bg: rgb(31, 31, 35);
$main-bg: rgb(24, 24, 27);
$screen-simulated-width: 113px;
$screen-simulated-height: 39px;
$screen-simulated-padding-bottom: 10px;

.menu {
  background-color: $main-bg;
  color: #fff;

  .header {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 15px;
    
    .search {
     .input-search {
       
     } 
    }
    
    .title {
      
    }
  }
  
  .section-content {
    &:last-child {
      padding-bottom: 1.5rem;
      background-color: #1f1f23;
    }
  
    .configurations {
      background-color: $second-bg;
      
      > * {
        margin-top: 15px;
      }
      
      .configurations-submenu {
        .submenu-header {
            /* border-bottom: 1px solid; */
            padding: 5px;
        }
        
        > .configuration {
          margin-left: 15px;
        }
        
        .overlay-position-size {
          .overlay-position {
            position: relative;
            width: $screen-simulated-width;
            height: $screen-simulated-height;
            background-color: #fff;
            padding-bottom: $screen-simulated-padding-bottom;

            .overlay-position-movable {
              position: absolute;
              background-color: #6e6e6eaa;
              right: 0;
              width: 10%;
              height: 46%;
              top: 0;
              cursor: move;
            }

            input[type=range][orient=vertical] {
              $height: $screen-simulated-height + $screen-simulated-padding-bottom;
            }
          }

          #range-overlay-width {
            width: $screen-simulated-width;
          }
        }
      }
      
      .key-selection {
        display: flex;
        flex-direction: row;
        align-items: center;
        
        .key-holder {
          background-color: #00000045;
          border: 1px solid #4a4a4a;
          padding: 2px;
        }
        
        .key-description {
          padding: 0...

JavaScript

const removePX = (str) => str.substr(0, str.length - 2);
const removePerc = (str) => str.substr(0, str.length - 1);

var key_holders = [...document.querySelectorAll(".key-holder")];
var last_key_holder_pressed = null;

function changeKey(keydown_ev) {
  last_key_holder_pressed.innerText = keydown_ev.key;
  document.removeEventListener('keydown', changeKey);
}

key_holders.forEach(k => k.addEventListener("click", click_ev => {
	last_key_holder_pressed = click_ev.target;  
  document.addEventListener('keydown', changeKey);
}));

/* TODO:
 * 	- Default initial background color (alpha transparency)
*/

/** Set the initial position handlers */
(function() {
	let movablePositionOverlay = document.querySelector('.overlay-position-movable');
  let overlayMovableParent = movablePositionOverlay.parentElement;
  let parentBounds = overlayMovableParent.getBoundingClientRect();
  let grip = 10;
  
  function dragElement(elmnt) {
    var dx, dy, pos3, pos4, maxT, maxR = 0;
      // otherwise, move the DIV from anywhere inside the DIV:
      elmnt.onmousedown = dragMouseDown;

    function dragMouseDown(e) {
      e = e || window.event;
      e.preventDefault();
      // get the mouse cursor position at startup:
      pos3 = e.clientX;
      pos4 = e.clientY;
      document.onmouseup = closeDragElement;
      // call a function whenever the cursor moves:
      document.onmousemove = elementDrag;
      
      let movableBounds = movablePositionOverlay.getBoundingClientRect();
      maxR = parentBounds.width - elmnt.offsetWidth;
      maxT = parentBounds.height - elmnt.offsetHeight;
    }

    function elementDrag(e) {
      e = e || window.event;
      e.preventDefault();
      // calculate the new cursor position:
      dx = pos3 - e.clientX;
      dy = pos4 - e.clientY;
      
      let top = elmnt.offsetTop - dy;
      let left = elmnt.offsetLeft - dx;
      
      // if the value is outside the simulated screen
      // set it to some default value
      if (dy > 0 && top <...