requestAnimationFrame is good solution to creating javascript based animations. But i can not set a duration for this function. I want to play animations for a certain time. I tried some fps solutions but these are not smooth.
How can i fill this water in x seconds?
const water = document.querySelector('.water')
let scale = 0
const fillGlass = () => {
scale += 0.01
water.style.transform = `scaleY(${scale})`
if (scale <= 1) {
requestAnimationFrame(fillGlass)
}
}
requestAnimationFrame(fillGlass)
.glass {
margin: 100px;
width: 150px;
height: 250px;
border: 3px solid #000;
border-top: 0;
border-bottom-width: 12px
}
.water {
height: 100%;
background-color: #BBDEFB;
transform: scaleY(0);
transform-origin: bottom center;
}
<div class="glass">
<div class="water"></div>
</div>
Simply, you can control it with animation-duration
. If you want to add dynamic value, I have just added a parameter to pass value to CSS
.glass {
margin: 100px;
width: 150px;
height: 250px;
border: 3px solid #000;
border-top: 0;
border-bottom-width: 12px
}
.water {
height: 100%;
background-color: #BBDEFB;
transform-origin: bottom center;
animation-name: animation;
animation-duration: var(--value);
}
@keyframes animation {
from { transform:scaleY(0) }
to { transform:scaleY(1) }
}
<div class="glass">
<div class="water" style='--value:20s'></div>
</div>
you can change --value
in HTML, it will affect on CSS
const water = document.querySelector('.water')
let scale = 0
let time = 2000 // 20 second * 100
const myInterval = setInterval(()=> {
scale += 1/time
water.style.transform = `scaleY(${scale})`
if (scale >= 1) {
clearInterval(myInterval);
}
}, 10);
.glass {
margin: 100px;
width: 150px;
height: 250px;
border: 3px solid #000;
border-top: 0;
border-bottom-width: 12px
}
.water {
height: 100%;
background-color: #BBDEFB;
transform: scaleY(0);
transform-origin: bottom center;
}
<div class="glass">
<div class="water"></div>
</div>
const start = document.querySelector('.start')
const stop = document.querySelector('.stop')
const fill = document.querySelector('.fill')
const empty = document.querySelector('.empty')
const water = document.querySelector('.water')
let scale = 0
let time = 2000 // 20 second * 100
let myInterval;
start.addEventListener('click', () => {
myInterval = setInterval(() => {
scale += 1 / time
water.style.transform = `scaleY(${scale})`
if (scale >= 1) {
clearInterval(myInterval);
}
}, 10);
})
stop.addEventListener('click', () => {
clearInterval(myInterval);
})
fill.addEventListener('click', () => {
scale = 1
water.style.transform = `scaleY(${scale})`
})
empty.addEventListener('click', () => {
scale = 0
water.style.transform = `scaleY(${scale})`
})
.glass {
margin: 100px;
width: 150px;
height: 250px;
border: 3px solid #000;
border-top: 0;
border-bottom-width: 12px
}
.water {
height: 100%;
background-color: #BBDEFB;
transform: scaleY(0);
transform-origin: bottom center;
}
<button type="button" class="start">Start</button>
<button type="button" class="stop">Stop</button>
<button type="button" class="fill">Instant Fill</button>
<button type="button" class="empty">Instant Empty</button>
<div class="glass">
<div class="water"></div>
</div>