3

我正在为一些图像编写一个小型查看器。我遇到了麻烦,我不确定原因是什么,但我猜这是 CSS 和 jQuery 的混合。

问题是:

  • 当其他人正在制作动画时,图像会稍微抽动。
  • 第一次动画后,图像移动低于其原始位置

代码可能有点乱,因为我必须更改很多东西才能让小提琴正常工作。

我的 HTML 标记:

<html>
    <body>
        <div id="photos">
            <figure class="photo">
                <img class="photo-image" src="http://bite-dose.com/wp-content/uploads/2011/03/cute-baby-animals.jpg"/>
            </figure>
            <figure class="photo">
                <img class="photo-image" src="http://cdn.arkarthick.com/wp-content/uploads/2010/04/blissfully-cute-baby-animals-baby-squirrel-6.jpg"/>
            </figure>
            <figure class="photo">
                <img class="photo-image" src="http://1.bp.blogspot.com/_4CngMC7D0HE/TDDHJ73_qJI/AAAAAAAAALY/-8Rvz41kRnc/s1600/baby_monkey_blanket.jpg"/>
            </figure>
            <figure class="photo">
                <img class="photo-image" src="http://2.bp.blogspot.com/_sIsR_xZ02MY/S_es3PlQIrI/AAAAAAAABGQ/ud3iEaMiu4w/s1600/cute_baby_animals_T3509_seal.jpg"/>
            </figure>
            <figure class="photo">
                <img class="photo-image" src="http://xaxor.com/images/baby-animals-part3-/baby-animals-part3-12.jpg"/>
            </figure>
            <figure class="photo">
                <img class="photo-image" src="http://nrbrose.edublogs.org/files/2011/05/blissfully-cute-baby-animals-baby-elephant-11-178o61g.jpg"/>
            </figure>
        </div>
        <hr/><br/><br/>
    </body>
</html>
​

我的 CSS:

#photos  {
    display : block;
    position: relative;
}

.photo {
    border    : 1px solid #808080;
    box-shadow: 0 0 10px 2px rgba( 0, 0, 0, 0.5 );
    position  : absolute;
    max-height: 250px;
    max-width : 250px;
}

.photo {
    display: block;
}

.photo:hover {
            transform: rotate( 0deg ) !important;
    -webkit-transform: rotate( 0deg ) !important;
       -moz-transform: rotate( 0deg ) !important;
        -ms-transform: rotate( 0deg ) !important;
         -o-transform: rotate( 0deg ) !important;
    z-index: 1;
}

.photo-image {
    display   : block;
    max-height: 100%;
    max-width : 100%;
}

hr {
    border: 0;
    border-top: 1px dashed red;
}
​

我的 JavaScript:

SemiEllipse = function ( a, b, cx, cy ) {
    this.radiusA = a;
    this.radiusB = b;
    this.radiusASquared = a * a;
    this.radiusBSquared = b * b;
    this.centerX = cx || 0;
    this.centerY = cy || 0;
}

SemiEllipse.prototype = {
    getPoint: function ( x ) {
        x -= this.radiusA;
        var y = this.radiusB * Math.sqrt( 1 - ( ( x * x ) / this.radiusASquared ) );

        return { x: x + this.centerX, y: y + this.centerY };
    },

    getAngle: function ( x ) {
        var angle = Math.PI/2 - Math.atan2( this.radiusB, x );
        return angle;
    }
}

$( '#photos' ).each(function () {
    var $photogroup = $( this );
    var $photos     = $photogroup.find( '.photo' );
    var count       = $photos.length;
    var limitHeight = $photos.css( 'max-height' );
    var maxHeight   = 0;

    for ( var i = 0; i < count; ++i ) {
        var $photo = $photos.eq( i );
        var h = $photo.height();

        if ( h > maxHeight ) {
            maxHeight = h;
        }
        if ( maxHeight > limitHeight ) {
            maxHeight = limitHeight;
            break;
        }
    }

    $photogroup.height( 400 );

    var bounds = {
        w   : $photogroup.width(),
        h   : $photogroup.height(),
        padW: $photogroup.innerWidth() - $photogroup.width(), 
        padH: $photogroup.innerHeight() - $photogroup.height(), 
    }
    var halfW = bounds.w / 2;
    var scale = halfW / ( count - 1 );
    var sc = new SemiEllipse( halfW / 2, 100 );

    // PHOTO POSITIONING
    for ( var i = 0; i < count; ++i ) {
        var $photo = $photos.eq( i );
        var p     = sc.getPoint( i * scale );
        var theta = sc.getAngle( p.x ) / 10;

        $photo.css({
            'left'  : p.x + sc.radiusA,
            'bottom': p.y,
            'transform': 'rotate( ' + theta + 'rad )',
            '-webkit-transform': 'rotate( ' + theta + 'rad )',
            '-mox-transform': 'rotate( ' + theta + 'rad )',
            '-ms-transform': 'rotate( ' + theta + 'rad )',
            '-o-transform': 'rotate( ' + theta + 'rad )',
        });
    }

    // HOVER FUNCTIONS
    $photos.each(function () {
        $this = $( this );
        var y = parseFloat( $this.css('bottom') );

        $this.data('mouseOverBottom', y + 10)
        .data('mouseOutBottom',  y - 10)
        .css({
            'transition': 'all .25s ease-in-out',
            '-webkit-transition': 'all .25s ease-in-out', 
            '-moz-transition': 'all .25s ease-in-out', 
            '-o-transition': 'all .25s ease-in-out'
        });
    }).hover(function () {
        $this = $( this );
        $this.css( 'bottom', $this.data( 'mouseOverBottom' ) );
    }, function () {
        $this = $( this );
        $this.css( 'bottom', $this.data( 'mouseOutBottom' ) );
    });
});

​http://jsfiddle.net/rNnx4/16/

我不确定图像是否会降低,但我之前已经处理过抽搐。我已经知道这transform: translateZ(0)会奏效,但这似乎会扼杀我的轮换。我能想到让它工作的唯一方法是<div>在每个图像周围添加一个这样做的类,但我很固执,不想在<div>我所有的东西中添加 s。但我想如果这是唯一的方法,我会接受它。

4

1 回答 1

3

您发现了两个问题:

  • 当其他人正在制作动画时,图像会稍微抽动。

这可以通过translate3d(0,0,0)向每个转换添加 a 来解决(在 CSS 和 JS 中)。这种“黑客”迫使浏览器在其自己的层上呈现每个 div,并在适用时添加硬件加速。它可能会影响移动设备的性能/内存。

我不确定根本原因是什么;正如 Niloct 指出的那样,只有“位于顶部”的图像才会受到影响,因此当您将鼠标悬停在大象上方时,不会有任何晃动。如果您以相反的顺序分配各个 z-index(因此仓鼠在顶部),则在将鼠标悬停在仓鼠上时没有任何晃动。

我的猜测是浏览器正在渲染任何需要重新计算的东西(照片上的阴影会出现在悬停的照片上,而z-index从 0->1 过渡)在一层上,并且抖动是抗锯齿的过渡中的帧被渲染。

  • 第一次动画后,图像移动低于其原始位置

您的代码中每张照片都从bottom: 0. 上mouseOverbottom: 10。打开mouseOut, bottom: -10, 并且在选项卡的剩余生命周期内将保持为 -10。可以通过设置mouseOver = 20和来修复mouseOut = 0

这两项更改都在您的小提琴上实现:http: //jsfiddle.net/rNnx4/19/

于 2012-10-23T01:54:53.133 回答