start . me .
Directory path . web .

HTML Document File : custom-slider.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>custom GUI: slider</title>
</head>
<body>

<style> body { overscroll-behavior: none; } .handle{ touch-action: none; } </style>

<button id="togglevh1">vertical or horizontal toggle</button>
<br><br>

<input type="range" id="islider1" value="0">
<br><br>

<div class="slider" id="slider1"></div>

<br>

<input type="range" id="islider2" value="0">
<br><br>

<div class="slider" id="slider2"></div>

<style>
.slider { background-color: grey; }
.slider > .handle { position: relative; background-color: lightgrey; }
</style>

<script>

slider1.vertical_or_horizontal = false
setup_slider(slider1)
islider1.max=slider1.max

slider2.vertical_or_horizontal = true
setup_slider(slider2)
islider2.max=slider2.max

togglevh1.onclick = function(){ slider1.vertical_or_horizontal = !slider1.vertical_or_horizontal; setup_slider(slider1) }

islider1.oninput = function(){ slider1.value_set( this.value ) }
islider2.oninput = function(){ slider2.value_set( this.value ) }

slider1.input_event = function(slider){ islider1.value = slider.value_get }
slider2.input_event = function(slider){ islider2.value = slider.value_get }

function setup_slider(slider){

  let value_initial=0
  if(slider.value_get!=undefined)
    value_initial=slider.value_get

  slider.value_set = set

  slider.innerHTML = '<div class="handle"></div>'
  let handle = slider.handle = slider.querySelector('.handle')

  let vertical_or_horizontal = slider.vertical_or_horizontal
  // related
  let top_or_left = slider.top_or_left = vertical_or_horizontal?'top':'left'
  let left_or_top = slider.left_or_top = vertical_or_horizontal?'left':'top'
  let height_or_width = vertical_or_horizontal?'height':'width'
  let width_or_height = vertical_or_horizontal?'width':'height'
  
  // setup slider DOM

  let height=200
  let size=height/10
  slider.style[height_or_width]=height+'px'
  slider.style[width_or_height]='50px' //size+'px'
  handle.style[height_or_width]='40px' //size+'px'
  handle.style[width_or_height]='100%'

  slider.max=height-40//slider.style.height-handle.style.height//height-size
  handle.style[left_or_top]='0px'

  // setup "drag&drop" / "grab-move"
  
  /* adapted from:
  https://plnkr.co/edit/nfeuFthe9CWbPVoe?p=preview&preview
  https://javascript.info/pointer-events */

  let clientY_or_clientX = vertical_or_horizontal?'clientY':'clientX'
  let offsetHeight_or_offsetWidth = vertical_or_horizontal?'offsetHeight':'offsetWidth'

  let shiftY

  handle.onpointerdown = function(event) {
    event.preventDefault()

    shiftY = event[clientY_or_clientX] - handle.getBoundingClientRect()[top_or_left]

    // events
    handle.setPointerCapture(event.pointerId)

    handle.onpointermove = handle_move_event

    handle.onpointerup = function(event){ handle.onpointermove = null }
  }

  function handle_move_event(event){
    // get
    let value = event[clientY_or_clientX] - shiftY - slider.getBoundingClientRect()[top_or_left]
    set(value)
  }
  function set(value){
    // clamp
    if (value < 0) {
      value = 0
    }
    let value_max = slider[offsetHeight_or_offsetWidth] - handle[offsetHeight_or_offsetWidth]
    if (value > value_max) {
      value = value_max
    }
    // set
    handle.style[top_or_left]=value+'px'
    slider.value_get=value
    if(slider.input_event)slider.input_event(slider)
  }

  set(value_initial)

}
</script>


<script src="/web/show-source.js"></script>

</body>
</html>