0

I have this circular DIV tag with height and width of 160px (the green div). I calculated the radius which is 80px and its circumference which is 877.93px. That white line outside of red div which is going around the red circular div you see is audio progress bar.

Now I want to make this circular, green Div which is behind the red Div tag clickable so that if user clicks on any point in front of the progress bar on this gradient Div tag, it moves the progress bar to that point by changing audio.currentTime.

So far, I have this code but what I get is not accurate at all and it also relies on the center of the green circular Div. So if user clicks anywhere closer to center, the calculation won't be so accurate.

That white progress bar is a Div itself and made by DaisyUI. White progress bar moves based on the audio.currentTime and if audio time updates it moves forward and backward accordingly.

Can anyone here help me with this problem please?

If there is any information missing in this thread please let me know.

var app = angular.module('app', []);
app.controller('Tab1Controller', function($scope) {
  $scope.audioProgress = 0;
  $scope.startX = 0;
  $scope.startValue = 0;
  $scope.progressbar = document.getElementById('progressBar');

  $scope.play = function() {
    const audio = document.getElementById('audio');
    if (audio.paused) {
      audio.play();
      $scope.playIcon = 'pause';
      audio.addEventListener('timeupdate', () => {
        if (audio.duration <= 60) {
          $scope.audioProgress = Math.floor((audio.currentTime / audio.duration * 100));
        } else {
          $scope.audioProgress = Math.floor((audio.currentTime / audio.duration * 100));
        }
      });
      return;
    } else {
      audio.pause();
      $scope.playIcon = 'play';
    }
  };

  $scope.onMouseDown = function(event) {
    $scope.startDrag(event.clientX);
  };

  $scope.onTouchStart = function(event) {
    $scope.startDrag(event.touches[0].clientX);
  };

  $scope.startDrag = function(startX) {
    // Get the initial mouse position and progress value
    $scope.startX = startX;
    $scope.startValue = parseInt($scope.audioProgress, 10);

    // Register drag events
    document.addEventListener('mousemove', $scope.drag);
    document.addEventListener('mouseup', $scope.dragEnd);
    document.addEventListener('touchmove', $scope.drag, {
      passive: false
    });
    document.addEventListener('touchend', $scope.dragEnd, {
      passive: false
    });
  };

  $scope.drag = function(event) {
    const audio = document.getElementById('audio');
    const circle = document.getElementById('progressBar');
    const rect = circle.getBoundingClientRect();
    const clientY = (event instanceof MouseEvent ? event.clientY : event.touches[0].clientY);
    const clientX = (event instanceof MouseEvent ? event.clientX : event.touches[0].clientX);
    const delta = (clientX) - $scope.startX;
    let newValue = $scope.startValue + (delta / 10);
    newValue = Math.min(Math.max(newValue, 0), 100);
    const dx = clientX - (rect.left + rect.width / 2);
    const dy = clientY - (rect.top + rect.height / 2);
    const angleInRadians = Math.atan2(dy, dx);
    let angleInDegrees = angleInRadians * (180 / Math.PI + 90);
    if (angleInDegrees < 0) {
      angleInDegrees = 877.93 + angleInDegrees;
    }
    audio.currentTime = (angleInDegrees / 360) * audio.duration;
  };

  $scope.dragEnd = function() {
    // Unregister drag events
    document.removeEventListener('mousemove', $scope.drag);
    document.removeEventListener('mouseup', $scope.dragEnd);
    document.removeEventListener('touchmove', $scope.drag);
    document.removeEventListener('touchend', $scope.dragEnd);
  };

});
.bg-red {
  background-color: #dc2626;
}

.w-md {
  width: 135px;
}

.h-md {
  height: 135px;
}

.rounded-full {
  border-radius: 9999px;
}

.absolute {
  position: absolute;
}

.flex {
  display: flex;
}

.justify-center {
  justify-content: center;
}

.items-center {
  align-items: center;
}

.rounded-half {
  border-radius: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>
<link href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2/dist/tailwind.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/daisyui@2.51.6/dist/full.css" rel="stylesheet" />

<div ng-app="app" ng-controller="Tab1Controller" style="width: 160px;height: 160px;" class="bg-green-600 relative rounded-half z-9899989 flex justify-center items-center">
  <div ng-mousedown="onMouseDown($event)" ng-touchstart="onTouchStart($event)" draggable="true" class="radial-progress rounded-full text-accent mx-auto shadow-round-spread" ng-init="progressbar = {}" id="progressBar" style="--value: {{audioProgress}}; --size: 10rem; --thickness: 0.7rem">
    <!--  -->
  </div>
  <div ng-click="play()" class="bg-red" style="width: 135px; height: 135px; border-radius: 50%; position: absolute; display: flex; justify-content: center; align-items: center;">
    <!-- icon Play -->
    <i ng-class="{'ion-pause -translate-x-2': playIcon === 'pause', 'ion-play -translate-x-1': playIcon !== 'pause'}" class="text-6xl ion-play text-accent pl-4 rounded-full bg-red"></i>
  </div>
</div>
<audio src="https://cdn.pixabay.com/download/audio/2023/04/27/audio_d6ce814591.mp3?filename=reflected-light-147979.mp3" controls id="audio" class="hidden invisible opacity-0"></audio>

enter image description here

Uncle John
  • 48
  • 8
  • As a plain HTML and JS question, I can strongly recommend turning this into a runnable snippet. – Mike 'Pomax' Kamermans May 05 '23 at 15:48
  • show all your code (html css js ) – paliz May 05 '23 at 15:51
  • @Mike'Pomax'Kamermans Sorry the code was angular but now I edited my question and it is runnable. I just want to make that progress bar you see it as a weird bluish color, draggable by click on the progress bar container or touch event. – Uncle John May 20 '23 at 13:03
  • @paliz Thanks for giving this suggestion. i edited my question and all available styles and html codes are all there. – Uncle John May 20 '23 at 13:04
  • Remember to run it though =D (you're trying to load a modules as "not a module" right now, so there's a big console error that obscures the snippet itself) – Mike 'Pomax' Kamermans May 20 '23 at 14:33
  • @Mike'Pomax'Kamermans, Oops sorry! Thanks for pointing that out, that was an issue with ionic js library which I removed it – Uncle John May 20 '23 at 23:14
  • Just looking at what your code does, it does not appear to update the progress bar while it's playing, is that intentional for the purpose of the example? Also, just so folks understand, is the question purely about what should happen when the progress bar is click-dragged or touch-dragged? Because you might be running into [this problem](https://stackoverflow.com/a/46866433/740553) at the moment. – Mike 'Pomax' Kamermans May 21 '23 at 15:58

0 Answers0