简体   繁体   中英

How to set a duration for requestAnimationFrame

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

As per your need, in JS

 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>

More Functions

 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>

Defining simple animation like this is always better with pure CSS, also in this case, it gives you more control over the animation itself.

.water {
  height: 100%;
  background-color: #BBDEFB;
  transform-origin: bottom center;
  animation-name: animation;
  animation-duration: 1s;
}

@keyframes animation {
  from { transform:scaleY(0) }
  to { transform:scaleY(1) }
}

For animation and smoothness you can divide the scale value by duration you want

const water = document.querySelector('.water')
let scale = 0
let time = 5000 //in seconds 1000=1sec
let duration = 100/time;
const fillGlass = () => {
  scale += duration;
  if(scale > 1){
    scale = 1;
  }
  water.style.transform = `scaleY(${scale})`
  if (scale <= 1) {
    requestAnimationFrame(fillGlass)
  }
}

requestAnimationFrame(fillGlass)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM