动画在表演前等待

时间:2016-04-18 22:01:01

标签: javascript css animation

我正在尝试使用css为元素高度设置动画。我这样做的方式是,我为元素添加了一个触摸事件。该函数将className添加到应该隐藏的元素,即获得高度为0。

问题是,当单击元素时,假定高度为0的div暂停一秒钟,然后获得所需的高度。似乎动画持续时间越长,它在动画之前等待的时间就越长。

以下是相关代码:

transition: max-height 2s ease-in-out;

JSFiddle

var heading = document.getElementById('heading'),
  body = document.getElementById('body');

heading.addEventListener('click', hide);
body.addEventListener('transitionend', hideCallback);

function hide() {
  body.className = 'hide';
}

function hideCallback(e) {
  console.log(e.propertyName);
}
#wrapper {
  margin: auto;
  background-color: blue;
  width: 470px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17);
  max-height: 400px;
  max-width: 600px;
  padding: 0;
}
#buttonContainer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  align-content: center;
  flex-direction: column;
  margin: auto;
  width: 100px;
  height: 100px;
  color: white;
}
#buttonIcon {
  width: 36px;
  height: 36px;
  line-height: 36px;
  font-size: 35px;
  font-weight: bold;
  display: inline-block;
}
#buttonLabel {
  font-size: 20px;
}
#content {
  width: 100%;
  height: 100%;
  text-align: left;
  transform: translateY(0px);
}
#heading {
  color: white;
  text-align: right;
  margin: 10px;
  font-size: 17px;
}
#body {
  color: #000;
  color: rgba(0, 0, 0, 0.87);
  background-color: #FFF;
  width: 100%;
  max-height: 500px;
  padding: 10px 0;
  box-sizing: border-box;
}
#body.hide {
  transition: max-height 2s ease-in-out;
  max-height: 0;
}
#innerBody {
  height: 200px;
  background-color: orange;
}
<div id="wrapper">
  <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span>
  </div>
  <div id="content">
    <div id="heading">Press Me</div>
    <div id="body">
      <div id="innerBody"></div>
    </div>
  </div>
</div>

3 个答案:

答案 0 :(得分:2)

您的初始max-height设置为500px,但实际高度要低得多。在过渡中,500px逐渐减小到0.首先,它没有视觉效果,直到最大高度变得小于实际高度。这产生了'#34;延迟&#34;你看到了。

您应该将实际的height属性转换为0(但只有在初始高度设置时才有效,在您的情况下为200px)。或者你可以考虑转换一个transform: scaleY(0),它有更便宜的额外好处,并提供更平滑的动画。 (http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

答案 1 :(得分:2)

您正在制作动画max-height而不是height。动画max-height是一种技巧,用于动画高度未知的元素的高度。你陈述了一个非常大的max-height,只要未知高度小于最大高度,它就可以了。唯一的缺点是,由于你的动画大于你的实际高度,它会有延迟。在这种情况下,你的max-height是500px,高度(包括填充)只有220px,这意味着超过时间(~1.1秒)只是将最大高度减少到220px,当它得到时在那里,视觉开始动画。

如果像这个例子一样,你知道元素的实际高度(220 =填充10 + innerBody高度200),你可以设置确切高度的动画。

如果您事先不知道高度,请尝试降低max-height估算并使用快速启动的缓动,例如ease-out或使用javascript设置开始和结束高度。

已知height: 220px(以全屏观看):

var heading = document.getElementById('heading'),
  body = document.getElementById('body');

heading.addEventListener('click', hide);
body.addEventListener('transitionend', hideCallback);

function hide() {
  body.className = 'hide';
}

function hideCallback(e) {
  console.log(e.propertyName);
}
#wrapper {
  margin: auto;
  background-color: blue;
  width: 470px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17);
  max-height: 400px;
  max-width: 600px;
  padding: 0;
}
#buttonContainer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  align-content: center;
  flex-direction: column;
  margin: auto;
  width: 100px;
  height: 100px;
  color: white;
}
#buttonIcon {
  width: 36px;
  height: 36px;
  line-height: 36px;
  font-size: 35px;
  font-weight: bold;
  display: inline-block;
}
#buttonLabel {
  font-size: 20px;
}
#content {
  width: 100%;
  height: 100%;
  text-align: left;
  transform: translateY(0px);
}
#heading {
  color: white;
  text-align: right;
  margin: 10px;
  font-size: 17px;
}
#body {
  color: #000;
  color: rgba(0, 0, 0, 0.87);
  background-color: #FFF;
  width: 100%;
  height: 220px;
  padding: 10px 0;
  box-sizing: border-box;
}
#body.hide {
  transition: height 2s ease-in-out;
  height: 0;
}
#innerBody {
  height: 200px;
  background-color: orange;
}
<div id="wrapper">
  <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span>
  </div>
  <div id="content">
    <div id="heading">Press Me</div>
    <div id="body">
      <div id="innerBody"></div>
    </div>
  </div>
</div>

javascript的未知高度 - 设置动画开始前的实际高度,等待下一帧,并将其更改为0(以全屏观看):

var heading = document.getElementById('heading'),
  body = document.getElementById('body');

heading.addEventListener('click', hide);
body.addEventListener('transitionend', hideCallback);

function hide() {
  body.style.height = body.scrollHeight + 'px'; /** sample actual height, and set it on element **/
  requestAnimationFrame(function() { // wait for next frame
    body.style.height = 0; // change height to 0
  });
}

function hideCallback(e) {
  console.log(e.propertyName);
}
#wrapper {
  margin: auto;
  background-color: blue;
  width: 470px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.17);
  max-height: 400px;
  max-width: 600px;
  padding: 0;
}
#buttonContainer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  align-content: center;
  flex-direction: column;
  margin: auto;
  width: 100px;
  height: 100px;
  color: white;
}
#buttonIcon {
  width: 36px;
  height: 36px;
  line-height: 36px;
  font-size: 35px;
  font-weight: bold;
  display: inline-block;
}
#buttonLabel {
  font-size: 20px;
}
#content {
  width: 100%;
  height: 100%;
  text-align: left;
  transform: translateY(0px);
}
#heading {
  color: white;
  text-align: right;
  margin: 10px;
  font-size: 17px;
}
#body {
  color: #000;
  color: rgba(0, 0, 0, 0.87);
  background-color: #FFF;
  width: 100%;
  padding: 10px 0;
  box-sizing: border-box;
  transition: height 2s ease-in-out;
}

#innerBody {
  height: 200px;
  background-color: orange;
}
<div id="wrapper">
  <div id="buttonContainer"><span id="buttonIcon">My</span><span id="buttonLabel">self</span>
  </div>
  <div id="content">
    <div id="heading">Press Me</div>
    <div id="body">
      <div id="innerBody"></div>
    </div>
  </div>
</div>

答案 2 :(得分:0)

尝试其他一些CSS transition-timing-function,例如linearease-out

根据w3schools

  

ease-in-out指定缓慢开始和结束的过渡效果(相当于cubic-bezier(0.42,0,0.58,1))