JSFiddle - React, Tailwind, and code Playground

by mrjordy

HTML

<div class="scrubber">
  <div class="scrubber-bar">
    <div class="scrubber-progress"></div>
    <div class="scrubber-handle"></div>
  </div>
</div>

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
  <polygon id="triangle" fill="lightblue" />
</svg>

CSS

.scrubber {
  width: 200px;
  height: 10px;
  background-color: lightgray;
  position: relative;
  margin-bottom: 20px;
}

.scrubber-bar {
  width: 100%;
  height: 100%;
}

.scrubber-progress {
  height: 100%;
  background-color: green;
  width: 0;
}

.scrubber-handle {
  width: 20px;
  height: 20px;
  background-color: white;
  border: 2px solid green;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(-50%, -50%);
}

svg {
  margin-top: 20px;
}

JavaScript

$(document).ready(function() {
  var triangle1 = $('#triangle1');
  var triangle2 = $('#triangle2');
  var controlX1 = 100; // Initial control point X coordinate for triangle1
  var controlX2 = 300; // Initial control point X coordinate for triangle2

  updateTriangle(triangle1, controlX1);
  updateTriangle(triangle2, controlX2);

  $('.scrubber-handle').on('mousedown', function(event) {
    var scrubber = $(this).parent();
    var scrubberWidth = scrubber.width();
    var triangle = $(this).hasClass('handle1') ? triangle1 : triangle2;
    var controlX = $(this).hasClass('handle1') ? controlX1 : controlX2;

    $(document).on('mousemove', function(event) {
      var offsetX = Math.max(0, Math.min(event.pageX - scrubber.offset().left, scrubberWidth));
      var percent = offsetX / scrubberWidth;
      controlX = percent * 400; // Scale to triangle width (400)

      updateTriangle(triangle, controlX);
      updateScrubber(progressBar, percent);
    });
  });

  $(document).on('mouseup', function() {
    $(document).off('mousemove');
  });

  function updateTriangle(triangle, x) {
    var points = [
      { x: x, y: 0 },
      { x: 0, y: 200 },
      { x: 400, y: 200 }
    ];

    triangle.attr('points', points.map(function(point) {
      return point.x + ',' + point.y;
    }).join(' '));
  }

  function updateScrubber(progressBar, percent) {
    progressBar.width((percent * 100) + '%');
  }
});