Как создать скролл на странице, работающий при помощи перетаскивания кнопки?

Хотелось бы понять как можно сделать скролл с помощью перетаскивания кнопки. В пример приведу такой сайт: http://lookbook.wedze.com/winter-2016-2017/


Ответы (1 шт):

Автор решения: ᅠhᅠ

Ну тут только самому сидеть пробовать чтобы разобраться.

let tid = null, rid = null

knob.addEventListener('mousedown', startDragging)

function startDragging(e) {
  e.preventDefault()

  clearTimeout(tid)
  cancelAnimationFrame(rid)

  document.body.style.cursor = 'grabbing'
  list.classList.add('dragging')

  let list_top = list.getBoundingClientRect().top,
      max = 2, sy = e.y,
      ease_value = 0.1,
      
      current_values = { knob_y: 0,list_y: list_top },
      end_values = { knob_y: 0, list_y: list_top }

  update()

  document.body.addEventListener('mousemove', continueDragging)
  document.body.addEventListener('mouseup', stopDragging)

  function continueDragging(e) {
    end_values.knob_y = e.y - sy
    end_values.list_y = -end_values.knob_y * (max * 2) + list_top
  }

  function stopDragging(e) {
    let current = Math.max(-max, Math.min(0, Math.round(list.getBoundingClientRect().top / innerHeight)))

    end_values.knob_y = 0
    end_values.list_y = current * innerHeight

    tid = setTimeout(() => cancelAnimationFrame(rid), 2000)
    document.body.style.cursor = 'grab'
    list.classList.remove('dragging')

    document.body.removeEventListener('mousemove', continueDragging)
    document.body.removeEventListener('mouseup', stopDragging)
  }

  function update() {
    current_values.knob_y += ease(end_values.knob_y, current_values.knob_y, ease_value)
    current_values.list_y += ease(end_values.list_y, current_values.list_y, ease_value)

    translateY(knob, current_values.knob_y)
    translateY(list, current_values.list_y)

    rid = requestAnimationFrame(update)
  }

  function ease(s, e, v) {
    return +((s - e) * v).toFixed(2)
  }

  function translateY(el, v) {
    el.style.transform = `translateY(${100 / innerHeight * v}vh)`
  }
}
* {
  margin: 0;
  padding: 0;
}

body {
  height: 100vh;
  overflow: hidden;
  cursor: grab;
}

.list {
  list-style: none;
}

.item {
  height: 100vh;
  width: 100vw;
}

.content {
  width: inherit;
  height: inherit;
  transition: 0.5s;
}

.dragging .content {
  transform: scale(0.7);
}

.content_1 {
  background-color: lightblue;
}

.content_2 {
  background-color: tomato;
}

.content_3 {
  background-color: lightgreen;
}

.knob {
  --size: calc(20px + 2vw + 2vh);
  position: fixed;
  right: 10vw;
  top: calc(50vh - var(--size) / 2);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background-color: black;
}
<ul id="list" class="list">
  <li class="item">
    <div class="content content_1"></div>
  </li>

  <li class="item">
    <div class="content content_2"></div>
  </li>

  <li class="item">
    <div class="content content_3"></div>
  </li>
</ul>

<div id="knob" class="knob"></div>


Без изинга и немного попроще

knob.addEventListener('mousedown', startDragging)

function startDragging(e) {
  e.preventDefault()

  document.body.style.cursor = 'grabbing'
  list.classList.add('dragging')
  knob.style.transition = `0s`
  list.style.transition = `0s`

  let list_top = list.getBoundingClientRect().top,
      max = 2, sy = e.y

  document.body.addEventListener('mousemove', continueDragging)
  document.body.addEventListener('mouseup', stopDragging)

  function continueDragging(e) {
    let y = e.y - sy
    knob.style.transform = `translateY(${y}px)`

    y = -y * (max * 2) + list_top
    list.style.transform = `translateY(${y}px)`
  }

  function stopDragging(e) {
    let current = Math.max(-max, Math.min(0, Math.round(list.getBoundingClientRect().top / innerHeight)))

    knob.style.transition = `0.5s`
    list.style.transition = `0.5s`
    knob.style.transform = `translateY(${0}px)`
    list.style.transform = `translateY(${current * innerHeight}px)`

    list.classList.remove('dragging')
    document.body.style.cursor = 'grab'
    document.body.removeEventListener('mousemove', continueDragging)
    document.body.removeEventListener('mouseup', stopDragging)
  }
}
* {
  margin: 0;
  padding: 0;
}

body {
  height: 100vh;
  overflow: hidden;
  cursor: grab;
}

.list {
  list-style: none;
}

.item {
  height: 100vh;
  width: 100vw;
}

.content {
  width: inherit;
  height: inherit;
  transition: 0.5s;
}

.dragging .content {
  transform: scale(0.7);
}

.content_1 {
  background-color: lightblue;
}

.content_2 {
  background-color: tomato;
}

.content_3 {
  background-color: lightgreen;
}

.knob {
  --size: calc(20px + 2vw + 2vh);
  position: fixed;
  right: 10vw;
  top: calc(50vh - var(--size) / 2);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background-color: black;
}
<ul id="list" class="list">
  <li class="item">
    <div class="content content_1"></div>
  </li>

  <li class="item">
    <div class="content content_2"></div>
  </li>

  <li class="item">
    <div class="content content_3"></div>
  </li>
</ul>

<div id="knob" class="knob"></div>

→ Ссылка