【问题标题】:Improve performance of jQuery drag animation提高 jQuery 拖动动画的性能
【发布时间】:2011-12-24 22:36:57
【问题描述】:

我最近开始了一个新项目,这是一本 CSS3/jQuery 翻书(点击翻页,或点击并拖动右侧页面)。

查看live hereplay with the fiddle

问题:

如何提高页面拖拽速度?

在 Chrome 和 Safari 中似乎还可以,但在 Firefox 中速度较慢/“steppy”,在 Opera 中非常糟糕(在 Mac OS X Snow Leopard 上的最新版本中测试)

顺便说一句..我仍在清理代码/我尝试删除旋转,但它似乎没有改变任何东西。

我也有一些测试人员抱怨 Chrome/mac 上的性能(对我来说似乎“还可以”)..

感谢任何帮助/批评/提示。

这是移动页面的代码(完整代码请参见小提琴)

function startMove() {
    $('#flipwrap.movable').on('mousemove', function(e) {
        e.preventDefault();
        thisX = parseFloat((e.pageX - offsetX - 190), 10);
        thisY = parseFloat((e.pageY - offsetY - 270), 10);
        positionX = parseFloat((((thisX - 55) * -1) + 310), 10);
        positionY = parseFloat(((thisY + 100) / 10), 10);
        rotateZ = parseFloat((((positionX - 350) * positionY) / 900).toFixed(2) * -1, 10);

        if ($('.page.flipit').hasClass('movable')) {
            $('.page.flipit').stop(true, true);
            $('.page.removeit').stop(true, true);
            $('.page.flipit').removeClass('css-animation').css({
                width: 116 - thisX / 2.1,
                height: 345 - thisX / 8,
                top: -13 + thisX / 16,
                left: thisX + 155
            });
            $('.page.flipit').css('-webkit-transform', 'rotate(' + rotateZ + 'deg)  ').css('-o-transform', 'rotate(' + rotateZ + 'deg)  ').css('-moz-transform', 'rotate(' + rotateZ + 'deg)  ');
            console.log('    pX = ' + positionX + ' pY = ' + positionY + ' rZ = ' + rotateZ + ' tX = ' + thisX + ' tY = ' + thisY);
            $('.page.removeit').css({
                width: 40 + thisX / 1.6
            });
        }
    });
}

【问题讨论】:

  • 不得不说它在 Chrome 中对我来说也相当笨重(最新版本,Win7)。不过,除此之外它看起来还不错。
  • 也许你可以把它和原来的 jsfiddle.net/pixelass/PXZwf/3 比较一下,它使用 translate 来定位..(在这个例子中,mouseup 上的动画......等完全关闭)......这只是关于动画拖动时卷曲/拖动部分的平滑度

标签: jquery animation css drag


【解决方案1】:

每次移动鼠标、缓存选择器时,Mousemove 都会被调用数十次/数百次,即

$('#flipwrap.movable').on('mousemove', function(e) {}
  var pageFlipIt = $('.page.flipit');
  $('#flipwrap.movable').on('mousemove', function(e) {
     pageFlipIt.doStuff();
  })
})

但最大的问题是动画盒阴影和边框半径是相当密集的处理器。我尝试在你的 jsfiddle 中删除所有这些,它在 Opera 中就像黄油一样顺利,但当然它会带走你的书实现的所有魅力。

我建议删除所有这些,然后逐步添加它们,看看在哪里可以找到视觉效果和速度之间的权衡。

【讨论】:

  • 谢谢您的帮助。我删除了盒子阴影动画,但它仍然很糟糕。边界不是真正的动画,它们只是跟随动画......我尝试使用翻译和缩放,这使得一切都比黄油更光滑。但我不能使用 scaleX .. 可悲的是。我会尝试变量缓存。无法删除边框半径,因为那样它将只是另一本糟糕的翻书(有很多糟糕的 jquery css 翻书......而且我不想使用 html5 画布......哦,圣诞快乐顺便说一句
  • 盒子阴影似乎是杀手...没有盒子阴影但有半径。然而没有 CSS 动画.. jsfiddle.net/pixelass/PXZwf/9 但是是的.. 没有阴影,这看起来真的很糟糕
【解决方案2】:

正如@Duopixel 所说,首先缓存选择器,然后将它们链接起来。我会努力简化数学——那里有很多步骤。但是,是的,mousemove 会触发很多事件,并且每个事件都有很多数学运算。所以会很难。

这是我的快速bash,希望它有一些用处

function startMove() {
    var $memoized_page_flipit = $('.page.flipit')
      , $memoized_page_removeit = $('.page.removeit ')
      , $memoized_page_stop = $memoized_page_flipit.add( $memoized_page_removeit )
      , offsetThisX =  offsetX + 190    //saves an addition at every loop..
      , offsetThisY =  offsetX + 270
      , offsetPosX =  offsetThisX + 55 + 310    //saves two additions at every loop..
      , offsetPosY =  ( offsetThisY + 100 ) / 10; //saves one addtion every loop
      , moving = false

    $('#flipwrap.movable').on('mousemove', function(e) {
        e.preventDefault();

        //tries not to have too many handlers hogging resources
        if( moving ){
            return;
        }
        moving = true;

        thisX = e.pageX - offsetThisX;  //floats and ints are all Numbers
        thisY = e.pageY - offsetThisY;
        positionX = offsetPosX - e.pageX;   //swapping order to save the * -1
        positionY = e.pageY / 10 - offsetPosY

        //make a string only once
        rotateZ = 'rotate(' + parseFloat((((positionX - 350) * positionY) / 900).toFixed(2) * -1, 10) + 'deg)';

        if ( $memoized_page_flipit.hasClass('movable')) {
            $memoized_page_stop.stop(true, true);
            $memoized_page_flipit
                .removeClass('css-animation')
                .css({
                    width: 116 - thisX / 2.1,
                    height:  345 - ( thisX  >> 3 ),     //bitwise shift division
                    top:  -13 + ( thisX >> 4 ) ,
                    left: thisX + 155
                    , '-webkit-transform' : rotateZ
                    , '-o-transform' : rotateZ
                    , '-moz-transform' : rotateZ
                });
            $memoized_page_removeit.css({
                width: 40 + thisX / 1.6
            });
        }
        moving = false;
    });
}

【讨论】:

  • 这看起来很有趣。迫不及待想回家试一试......谢谢一堆
  • 所以.. 我试过你的答案。 jsfiddle.net/pixelass/PXZwf/7 ...我还删除了 box-shadow 和 border-radius 的 CSS 动画,但在 Opera/Firefox 中看起来仍然很糟糕。我也很乐意从其他人那里得到一些反馈.. 差异???等等……
  • 是的,我也试过了,但没有发现太大的不同......正如我所说,这些是最佳实践,但有这么多数学和这么多事件,这真的很难。
  • 我在@Duopixel 的回答上发表了评论...删除框阴影使它更平滑.. 仍然在玩.. 我对此非常有信心.. 无论如何..到目前为止,谢谢您的帮助。顺便说一句,一旦完成,这将是一个开源 jQuery 插件。
猜你喜欢
  • 2012-12-03
  • 1970-01-01
  • 2016-01-30
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多