Hi i’m using performance.now()
for progress with setInterval
i want to cover all the all values that is why using performance.now()
Covered values for between 1 and 2:
1.1995
1.5997000000011177
1.9999000000003726
2.3996000000014903
Note: covered values will decrease as i decrease interval Value from 400 ms
var progressStart = null, intervalId = null;
function timeUpdateCallback() {
if (progressStart === null) {
progressStart = performance.now();
}
const elapsed = performance.now() - progressStart;
// const progress = (elapsed / duration) * 100;
const currentTime = (elapsed / 1000); // Convert to seconds
return currentTime;
}
const range = document.getElementById("range");
const rangeWidth = range.offsetWidth;
console.log('rangeWidth',rangeWidth)
// https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers
const scale = (num, in_min, in_max, out_min, out_max) => {
return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
};
range.addEventListener("input", (e) => {
const value = +e.target.value;
const label = e.target.nextElementSibling;
const rangeWidth = getComputedStyle(e.target).getPropertyValue("width");
const labelWidth = getComputedStyle(label).getPropertyValue("width");
// remove px
const numWidth = +rangeWidth.substring(0, rangeWidth.length - 2);
console.log('numWidth',numWidth);
const numLabelWidth = +labelWidth.substring(0, labelWidth.length - 2);
const max = +e.target.max;
const min = +e.target.min;
const left =
value * (numWidth / max) -
numLabelWidth / 2 +
scale(value, min, max, 10, -10);
label.style.left = `${left}px`;
label.innerHTML = value;
});
function startProgress(){
intervalId = setInterval(()=>{
let p = timeUpdateCallback();
console.log('p:',p)
range.value = Math.floor(p * 1000 / rangeWidth);
console.log(`range.value:`,range.value);
if(range.value == 100){
range.value = 0;
}
range.dispatchEvent(new Event('input'));
},400);
}
startProgress();
document.getElementById('stop').addEventListener('click',()=>{
console.log('stopped at:',range.value);
clearInterval(intervalId);
})
document.getElementById('start').addEventListener('click',()=>{
console.log('started at:',range.value);
startProgress();
})
@import url("https://fonts.googleapis.com/css2?family=Lato&display=swap");
* {
box-sizing: border-box;
}
body {
background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
font-family: "Lato", sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
h2 {
position: absolute;
top: 10px;
}
.range-container {
position: relative;
}
input[type="range"] {
width: 300px;
margin: 18px 0;
-webkit-appearance: none;
}
input[type="range"]:focus,input[type="range"]:active {
outline: none;
cursor: grabbing !important;
}
input[type="range"] + label {
background-color: #fff;
position: absolute;
top: -25px;
left: 110px;
width: 80px;
padding: 5px 0;
text-align: center;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
/* Chrome & Safari */
input[type="range"]::-webkit-slider-runnable-track {
background: transparent;
border-radius: 4px;
width: 100%;
height: 10px;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 120px;
width: 2px;
background: red;
cursor: grab;
}
input[type="range"]::-webkit-slider-thumb::before {
content: "";
display: block;
width: 20px;
height: 20px;
background-color: yellow;
position: absolute;
top: 30%;
left: 30;
}
<h2>Custom Range Slider</h2>
<div class="range-container">
<input type="range" name="range" step="10" id="range" min="0" max="100" data-red="yellow"/>
<label for="range">50</label>
</div>
<button id="stop">Stop</button>
<button id="start">Start</button>
Steps to re-produce:
- while progress stop the progress check ‘P:’ value in console.log
- start the progress after sometime ‘:p’ value will differ and slider jumps
My expectation: i’m doing it for timeline cursor progress as shown in below image