Javascript动画不会以预期的方式运行

时间:2015-02-22 17:26:56

标签: javascript

我想创建一个简单的动画,当'mouseover'事件发生时,矩形的长度平滑变为其值的一半,当'mouseout'事件发生时再次加倍。 如果鼠标移动缓慢,则以下代码有效,但如果鼠标快速移动则不能。如果鼠标快速移动,矩形就会卡住。请建议如何克服这一点。

<body>
    <svg id="svg" width="600" height="100">
        <rect id="myrect" width="600" height="100" fill="green">
     </svg>
     <script>
        svg = document.getElementById("svg");
        var w = 600;
        var step = 10;
        
        svg.addEventListener("mouseover", function(){ 
            function anim ()    {
                w -= step;
                if( w >= 300)    {
                    myrect = document.getElementById("myrect");
                    myrect.setAttribute("width", w);
                    requestAnimationFrame(anim);            
                }
            }
            anim();
        });
        
        svg.addEventListener("mouseout", function(){ 
            function anim ()    {
                w += step;
                if( w <= 600)    {
                    myrect = document.getElementById("myrect");
                    myrect.setAttribute("width", w);
                    requestAnimationFrame(anim);            
                }
            }
            anim();
        });
    </script>
</body>

2 个答案:

答案 0 :(得分:2)

今天,请不要将JavaScript用于此类动画。 CSS转换就是这样做的 - 它们表现出更好的性能,因为大多数浏览器可以在图形卡而不是CPU上更快地计算它们。

有关详细信息,请参阅W3C School on CSS Transitions

因此,您的示例的改进版本和更短版本看起来像

&#13;
&#13;
#myrect {
  transition: transform 0.5s ease;
}
#myrect:hover {
  transform: scale(0.5, 1.0);
}
&#13;
<svg id="svg" width="600" height="100">
  <rect id="myrect" width="600" height="100" fill="green" />
</svg>
&#13;
&#13;
&#13;

注意:您似乎无法设置动画宽度&#39;通过简单的CSS完成SVG的属性,就像之前做过的那样。为了便于处理,您可以使用translate-property并将其缩放到宽度的50%。

(好吧,根据SVG Standard - Section Attributes&#39; width&#39;可以使用更强大的SVG动画逻辑进行动画处理,但CSS看起来更安静,这些知识也可以应用于HTML元素: - ))

答案 1 :(得分:0)

以下代码的简短说明:

动画过程统一在单个函数中,可以在两个方向上工作,具体取决于direction参数值。鼠标事件只会改变动画方向。变量animActive阻止requestAnimationFrame的双重调用,并使方向更改顺利。

<body>
    <svg id="svg" width="600" height="100">
        <rect id="myrect" width="600" height="100" fill="green">
     </svg>
     <script>
        svg = document.getElementById("svg");
        var w = 600;
        var step = 10;
        var direction;
        var animActive = false;
        
        svg.addEventListener("mouseover", function(){ 
            direction = true;
            if (!animActive)
              requestAnimationFrame(anim);
        });
        
        svg.addEventListener("mouseout", function(){ 
            direction = false;
            if (!animActive)
              requestAnimationFrame(anim);
        });
       
       function anim(){
         if (direction){
            if( w > 300){
                animActive = true;
                w -= step;
                myrect = document.getElementById("myrect");
                myrect.setAttribute("width", w);
                requestAnimationFrame(anim);
            }
            else
                animActive = false;
         }
         else{
            if( w < 600){
                animActive = true;
                w += step;
                myrect = document.getElementById("myrect");
                myrect.setAttribute("width", w);
                requestAnimationFrame(anim);            
            }
           else
               animActive = false;
         }
       }
    </script>
</body>