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>