首页 > 解决方案 > 流畅的动画

问题描述

我的目标:实现一个流畅的侧边菜单动画,就像谷歌的一样(使用移动版左上角的按钮)。(我用非高端手机测量的动画流畅度。)

我决定测试绝对最简单的动画,因此在 jsbin 创建了一个草稿。从那以后(几天)我真的对结果感到困惑 - 最终最简单的动画表现比谷歌的差得多。(我已经在专用 url 上测试了我的,所以 jsbin 没有搞砸任何东西。)

此外还有带有类似菜单的yandex 翻译器(按钮在右上角)。当然,互联网上还有其他如此出色的动画,但它们如何比最简单的设置播放更流畅?

我会在这个问题上设置一个赏金,因为它对我来说真的很重要,但是......没有足够的声誉。


另外第二个 - 当我在动画中用 24 个孩子测试我的动画时,结果没有区别。我一直认为保持低儿童数量很重要。

【以下忽略,stackoverflow强制我粘贴】

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Sideanimations 0 children">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Sideanimations</title>
</head>
<body>
    <div class='buttonsholder'>
        <button onclick='ff1()'>by size</button>
        <button onclick='ff2()'>by position</button>
        <button onclick='ff3()'>both + rounded</button>
    </div>

  <div id='fikmic1'></div>
  <div id='fikmic2'></div>
  <div id='fikmic3'></div>


  <style>
  body{
        width:100vw;
        height:100vh;
        overflow:hidden;
    }
    .buttonsholder{
     position:absolute;
      bottom:50vh;
      right:0px;
      width:0px;
    }
    button{
        display:block;
        float:right;
      text-align:right;
      padding:0px 1vw;
      margin:.5vw 1vw;
    }

    #fikmic1{
        display:none;
        position:absolute;
      top:0vh;
      left:0vw;
        width:0vw;
        height:100vh;
        background-color:#777;
        transition:.7s;
    }
    #fikmic2{
        display:none;
        position:absolute;
      top:0vh;
      left:-80vw;
        width:80vw;
        height:100vh;
        background-color:#333;
        transition:.7s;
    }
    #fikmic3{
        display:none;
        position:absolute;
      top:50vh;
      left:0vw;
        width:0vw;
        height:0vh;
        background-color:#aaa;
      border-radius:100%;
        transition:.7s;
    }
  </style>

  <script>
      function ff1(){
        var c = document.getElementById('fikmic1');

        if(c.getAttribute('gefikt') === null){
          c.setAttribute('gefikt', '');
          c.style.display = 'block';
          setTimeout(function(){
            c.style.width = '80vw';
          }, 50);
        }
        else{
            c.removeAttribute('gefikt');
            c.style.width = '0vw';
          setTimeout(function(){
            c.style.display = 'none';
          }, 700);
        }
    }
    function ff2(){
        var c = document.getElementById('fikmic2');

        if(c.getAttribute('gefikt') === null){
          c.setAttribute('gefikt', '');
          c.style.display = 'block';
          setTimeout(function(){
            c.style.left = '0vw';
          }, 50);
        }
        else{
          c.removeAttribute('gefikt');
            c.style.left = '-80vw';
          setTimeout(function(){
            c.style.display = 'none';
          }, 700);
        }
    }
    function ff3(){
        var c = document.getElementById('fikmic3');

        if(c.getAttribute('gefikt') === null){
          c.setAttribute('gefikt', '');
          c.style.display = 'block';
          setTimeout(function(){
            c.style.top = (((window.innerHeight/100) * 50) - ((window.innerWidth/100) * 80)) + 'px';
            c.style.left = '-80vw';
            c.style.width = '160vw';
            c.style.height = '160vw';
          }, 50);
        }
        else{
          c.removeAttribute('gefikt');
            c.style.top = ((window.innerHeight/100) * 50) + 'px';
            c.style.left = '0vw';
            c.style.width = '0vw';
            c.style.height = '0vw';
          setTimeout(function(){
            c.style.display = 'none';
          }, 700);
        }
    }
  </script>


</body>
</html>

标签: javascripthtmlcss

解决方案


动画 CSStransform将比动画left,width等更有效。 “现代浏览器可以非常便宜地为四件事制作动画:位置、缩放、旋转和不透明度。”

为您的第一个侧边菜单设置动画时,将transform-origin属性设置为left,以便动画位于菜单左侧的中心。(默认原点是center,在这种情况下,这不是您想要的。)

我制作了您的 JS Bin 的修订版,并将其作为片段发布在下面。

function ff1(){
  var c = document.getElementById('fikmic1');

  if(c.getAttribute('gefikt') === null){
    c.setAttribute('gefikt', '');
    c.style.display = 'block';
    setTimeout(function(){
      c.style.transform = 'scaleX(1)';
    }, 50);
  }
  else{
    c.removeAttribute('gefikt');
    c.style.transform = 'scaleX(0)';
    setTimeout(function(){
      c.style.display = 'none';
    }, 700);
  }
}

function ff2(){
  var c = document.getElementById('fikmic2');

  if(c.getAttribute('gefikt') === null){
    c.setAttribute('gefikt', '');
    c.style.display = 'block';
    setTimeout(function(){
      c.style.transform = 'translateX(0vw)';
    }, 50);
  }
  else{
    c.removeAttribute('gefikt');
    c.style.transform = 'translateX(-80vw)';
    setTimeout(function(){
      c.style.display = 'none';
    }, 700);
  }
}

function ff3(){
  var c = document.getElementById('fikmic3');

  if(c.getAttribute('gefikt') === null){
    c.setAttribute('gefikt', '');
    c.style.display = 'block';
    setTimeout(function(){
      c.style.transform = 'scale(1)';
    }, 50);
  }
  else{
    c.removeAttribute('gefikt');
    c.style.transform = 'scale(0)';
    setTimeout(function(){
      c.style.display = 'none';
    }, 700);
  }
}
body{
  width:100vw;
  height:100vh;
  overflow:hidden;
}
.buttonsholder{
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  justify-content:center;
  height:100%;
}
button{
  width:4rem;
  text-align:right;
  padding:0 .2rem;
  margin:.4rem .8rem;
}

#fikmic1{
  display:none;
  position:absolute;
  top:0vh;
  left:0vw;
  width:80vw;
  height:100vh;
  transform:scaleX(0);
  transform-origin:left;
  background-color:#777;
  transition:.7s;
}
#fikmic2{
  display:none;
  position:absolute;
  top:0vh;
  left:0vw;
  width:80vw;
  height:100vh;
  transform:translateX(-80vw);
  background-color:#333;
  transition:.7s;
}
#fikmic3{
  display:none;
  position:absolute;
  top:calc(50vh - 80vw);
  left:-80vw;
  width:160vw;
  height:160vw;
  transform:scale(0);
  background-color:#aaa;
  border-radius:100%;
  transition:.7s;
}
<!DOCTYPE html>
<html>
  <head>
    <meta name="description" content="Sideanimations by transform">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Sideanimations</title>
  </head>
  
  <body>
    <div class='buttonsholder'>
      <button onclick='ff1()'>by size</button>
      <button onclick='ff2()'>by position</button>
      <button onclick='ff3()'>both + rounded</button>
    </div>

    <div id='fikmic1'></div>
    <div id='fikmic2'></div>
    <div id='fikmic3'></div>
  </body>
</html>


推荐阅读