Javascript/CSS - animation duration in pixel per second

巧了我就是萌 提交于 2021-01-27 07:52:43

问题


How can i set the duration of an transition/animation to pixel per second?

You see the two different wrappers, with a different total height depending on it's colored content. The total speed is the same, given from the css transition attribute, thats okay if you want several animations with the same duration. For a smoother look i want to set this transition/animation effect to pixel per second so it takes as long as many pixels there. More content = more pixel = longer animation.

How can i achieve this with vanilla javascript or even css?

var wrapper1 = document.getElementById('wrapper1');
var wrapper2 = document.getElementById('wrapper2');
var header1 = document.getElementById('header1');
var header2 = document.getElementById('header2');
var wrapper1CmputedHeight = wrapper1.scrollHeight;
var wrapper2CmputedHeight = wrapper2.scrollHeight;

header1.addEventListener('click', function() {
  if (wrapper1.style.height === '60px') {
    wrapper1.style.height = wrapper1CmputedHeight + 'px';
  } else {
    wrapper1.style.height = '60px';
  }
})

header2.addEventListener('click', function() {
  if (wrapper2.style.height === '60px') {
    wrapper2.style.height = wrapper2CmputedHeight + 'px';
  } else {
    wrapper2.style.height = '60px';
  }
})
#wrapper1,
#wrapper2 {
  background: #fff;
  border: 1px solid grey;
  overflow: hidden;
  transition: height .2s linear
}

#wrapper1 {
  margin-bottom: 40px
}

#header1,
#header2 {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer
}

#content1 {
  height: 20px;
  background: blue
}

#content2 {
  height: 600px;
  background: green
}
<div id="wrapper1" style="height: 60px">
  <div id="header1">
    <span>header</span>
  </div>
  <div id="content1"></div>
</div>

<div id="wrapper2" style="height: 60px">
  <div id="header2">
    <span>header</span>
  </div>
  <div id="content2"></div>
</div>

回答1:


The only way to do this with css transitions, is to dynamically calculate the duration of the transition using a little javascript. So, in your code, I would remove the duration for the transition rule in your css, i,e.

#wrapper1,
#wrapper2 {
  background: #fff;
  overflow: hidden;
  transition: height linear
}

and I would instead set the duration in the click handler as follows:

header1.addEventListener('click', function () {
    if(wrapper1.style.height === '60px') {
    wrapper1.style.height = wrapper1CmputedHeight + 'px';
    wrapper1.style.transitionDuration=(wrapper1CmputedHeight/100)+"s";
  } else {
    wrapper1.style.height = '60px';
  }
})

So in this case, I've used a speed of 100px per second (this is the /100 part in the above code).




回答2:


I found this example here but it seems to do the trick for you (after some tweaking). In this case it implements a quartic interpolation, however you could adjust this algorithm to linear / other if so desired.

//
// Animate
//
var btn1 = document.querySelector('.animate');
btn1.addEventListener('click', function() {
  reset();
  animate();
  btn1.disabled = true;
});

//
// http://easings.net/#easeInOutQuart
//  t: current time
//  b: beginning value
//  c: change in value
//  d: duration
//
function easeInOutQuart(t, b, c, d) {
  if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
  return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}

function reset() {
  document.querySelector('.square').style.width = Math.floor((Math.random() * 500) + 1) + "px";
}

function animate() {

  var rect = document.querySelector('.square');
  var from = 0;
  var to = window.getComputedStyle(rect, null).getPropertyValue("width").split('px')[0];
  var duration = to * 10;

  var start = new Date().getTime();
  var timer = setInterval(function() {
    var time = new Date().getTime() - start;
    var width = easeInOutQuart(time, from, to - from, duration);
    rect.style.width = width + "px";
    if (time >= duration) {
      clearInterval(timer);
      btn1.disabled = false;
    }
  }, 1000 / 60);
  rect.style.width = from;
}

reset();
.square {
  position: relative;
  display: block;
  width: 30px;
  height: 30px;
  background-color: #f00;
}
<div class="square"></div>

<button class="animate">Animate</button>


来源:https://stackoverflow.com/questions/47706393/javascript-css-animation-duration-in-pixel-per-second

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!