jQuery动画跳动

时间:2018-10-11 19:00:41

标签: jquery

我正在尝试创建动画滑块。

当屏幕分辨率大于1265px时,滑块应自动旋转(使用 Ctrl + -在笔记本电脑上模拟)

我使用jQuery.animation,但是结果太过跳跃了。

如何修复它,使动画更流畅?

var myObj = {};
var isEmptyObj = !Object.keys(myObj).length;

if(isEmptyObj) {
    // true
} else {
var wSlider = {
    slider_width : 0,
    slide_count : 0,
    state_count : 0,
    isAutoRotate : false,
    autoRotateTimeout : null,
    isRotating : false,
    autoRotatePause : false,
    isInit: false
}

$(document).ready(function  () {
    wSlider.adjustScreen();
    $(window).focus(function () {
        wSlider.startAutoRotate();
    }).blur(function () {
        wSlider.stopAutoRotate();
        wSlider.autoRotatePause = true;

    });
})

window.onresize = function() {
    wSlider.adjustScreen();
}

wSlider.autoRotate = function() {
    if (!wSlider.isAutoRotate) return;
    wSlider.isRotating = true;
    timeFrame = 20000;

    sliderTrack = $(".sliderTrack");

    [diffLeft,diffRight] = wSlider.getDiffs();

    // console.log("diffRight",diffRight)
    // console.log("wSlider.slider_width",wSlider.slider_width)
    diff = wSlider.slider_width 

    if (diffLeft != 0) {
        diff = diffRight;
        timeFrame = timeFrame*(diffRight/wSlider.slider_width);
        // console.log("after pause",timeFrame)
    }

    // console.log("timeFrame",timeFrame)
    // console.log("diff",diff)

    left = Math.round(sliderTrack.position().left) - diff;
    sliderTrack.animate({"left": left}, timeFrame,"linear", function() {});


    wSlider.autoRotateTimeout = setTimeout(function() {
        [diffLeft,diffRight] = wSlider.getDiffs();
        if (diffLeft != 0) {
            // console.log("fix diffRight",diffRight)
            left = Math.round(sliderTrack.position().left) - diffRight;
            sliderTrack.css({"left": left})
        }

        wSlider.adjustCorusel(1);
        wSlider.autoRotate();
    },timeFrame);
}

wSlider.stopAutoRotate = function() {
    $(".sliderTrack").stop();
    clearTimeout(wSlider.autoRotateTimeout);
    wSlider.isRotating = false;
}
wSlider.startAutoRotate = function(){
    clearTimeout(wSlider.autoRotateTimeout);
    if (wSlider.autoRotatePause) {
        // wSlider.autoRotateTimeout = setTimeout(wSlider.autoRotate, 1000);
        wSlider.autoRotate();
        wSlider.autoRotatePause= false;
    } else {
        wSlider.autoRotateTimeout = setTimeout(wSlider.autoRotate, 3500);
    }

}
wSlider.adjustScreen = function () {    
    wSlider.stopAutoRotate();

    if ($(window).width() <=  1265) {
        wSlider.isAutoRotate = false;
        wSlider.slider_width = $(".w-container").width()/2;

    } else {
        wSlider.isAutoRotate = true;
        wSlider.startAutoRotate();
        wSlider.slider_width = $(".w-container").width()/3;
    }
    wSlider.slider_width = Math.round(wSlider.slider_width);


    if (!wSlider.isInit) {
        wSlider.isInit = true;
        // duuplicate before/after
        slider_entries = $('.mySlides');
        slider_entries.clone().appendTo( ".sliderTrack" )
        slider_entries.clone().prependTo( ".sliderTrack" )
        wSlider.slide_count = slider_entries.length;

    }

    $(".sliderTrack").css({ 'left':0});

    slider_entries = $('.mySlides');

    slider_entries.each(function(i,o) {
        $(o).width($(".w-container").width());
        $(o).css({ 'left': wSlider.slider_width*(i-wSlider.slide_count)+'px'});
        $(o).attr("sid",i);
    })
    $(".w-container").height(slider_entries.height()*0.79);
}

wSlider.adjustCorusel = function(n) {
    slider_entries = $('.mySlides');
    if (n > 0) {
        // console.log(">")
        // move first left element to the last right
        last_postition = $(slider_entries[slider_entries.length-1]).position().left;
        last_postition = Math.round(last_postition);
        last_postition += wSlider.slider_width;
        $(slider_entries[0]).css("left",last_postition+'px');
        $(slider_entries[0] ).detach().appendTo( ".sliderTrack" ).show();
    } else {
        // console.log("<")

        // move last right element to the first left
        fisrt_postition = $(slider_entries[0]).position().left;
        fisrt_postition = Math.round(fisrt_postition);

        fisrt_postition -= wSlider.slider_width;
        $(slider_entries[slider_entries.length-1]).css("left",fisrt_postition+'px');
        $(slider_entries[slider_entries.length-1] ).detach().prependTo( ".sliderTrack" ).show();
    }
}

wSlider.sliderMove = function(n) {

    // don't run if previous run still running
    if (wSlider.state_count != 0) return;
    wSlider.state_count = 1;
    wSlider.stopAutoRotate();
    // console.log("wSlider.sliderMove",n)


    sliderTrack = $(".sliderTrack");
    stLeft = Math.round(sliderTrack.position().left);

    [diffLeft,diffRight] = wSlider.getDiffs();

    if (diffLeft  == 0){
        // normal case - auto rotate is off
        stLeft -= wSlider.slider_width * n;
        wSlider.adjustCorusel(n);

    } else {
        // rotating in progress 
        if (n > 0) {
            stLeft -= diffRight;
            wSlider.adjustCorusel(n);
        } else {
            // no need to wSlider.adjustCorusel since we simply undoing the last rotation
            stLeft += diffLeft;
        }

    }




    // console.log('stLeft: '+stLeft);

    sliderTrack.animate({"left": stLeft}, 250,"swing", function() {
        wSlider.state_count = 0;
        if (wSlider.isAutoRotate) {
            wSlider.startAutoRotate();
        }
    });


}

// returns [diffLeft,diffRight] 
// diffLeft - the pixel value of the left most visible slider that is invisible 
// diffRight - the pixel value of the left most visible slider that is visible
wSlider.getDiffs = function() {
    sliderTrack = $(".sliderTrack");
    stLeft = Math.round(sliderTrack.position().left);

    diff = Math.abs(stLeft) % wSlider.slider_width;
    if (Math.abs(Math.abs(diff) - wSlider.slider_width) < 1) diff = 0;

    diffLeft = diff;
    diffRight = wSlider.slider_width - diff;

    if (stLeft > 0 && diff != 0) {
        // swap
        [diffLeft,diffRight] = [diffRight,diffLeft];
    }
    return [diffLeft,diffRight];
}

wSlider.focusSlide = function(o) {
    // don't run if previous run still running
    if (wSlider.state_count != 0) return;
    wSlider.state_count = 1;
    if (wSlider.isRotating) {
        wSlider.autoRotatePause = true;
    }
    wSlider.stopAutoRotate();
    // console.log("wSlider.focusSlide")



    $(".ctrl-buttons").hide();
    o = $(o);
    $(".growImg",o).removeClass("growImg").addClass("growImg-tmp");

    oLeft = Math.round(o.position().left);
    // console.log("left",oLeft);

    sliderTrack = $(".sliderTrack");
    stLeft = Math.round(sliderTrack.position().left);

    slider_entries = $('.mySlides');

    cWidth = $(".w-container").width();
    slider_entries.each(function  (i,sibling) {
        sibling = $(sibling);
        sLeft = Math.round(sibling.position().left);
        relativeLeft = sLeft + stLeft;
        if (relativeLeft < -wSlider.slider_width ||
            relativeLeft >= cWidth) 
            {
                return;
            }

        sibling.data('origLeft',sLeft);
        if (sLeft <= oLeft) {
            if (relativeLeft <= 0 && sLeft != oLeft) {
                [diffLeft,diffRight] = wSlider.getDiffs();
                sibling.animate({"left": -diffRight - stLeft}, 250,"swing", function() {});
            } else {
                sibling.animate({"left": 0 - stLeft}, 250,"swing", function() {});
            }
        } else {
            sibling.animate({"left": cWidth - stLeft}, 250,"swing", function() {});
        }

    })

    // redraw text
    content = $(".content",o);
    content.hide();
    $(".displayLeft",content).removeClass("displayLeft").addClass("displayRight");
    content.fadeIn(1000);

}
wSlider.unfocusSlide = function(o) {
    event.stopPropagation();
    if (wSlider.state_count != 1) return;
    wSlider.state_count = 0;
    o = $(o).parent();

    slider_entries = $('.mySlides');

    slider_entries.each(function  (i,sibling) {
        sibling = $(sibling);
        l = sibling.data('origLeft');
        sibling.data('origLeft',null);
        if (l != null) {
            sibling.animate({"left": l}, 250,"swing", function() {});
        }

    })

    $(".growImg-tmp",o).removeClass("growImg-tmp").addClass("growImg");
    $(".ctrl-buttons").show();

    // redraw text
    content = $(".content",o);
    content.hide();
    $(".displayRight",content).removeClass("displayRight").addClass("displayLeft");
    content.fadeIn(1000);
    wSlider.startAutoRotate();
}
button:focus {
    outline:none  !important;
}
.sliderTrack {
    position: absolute;  
}
.mySlides {
    z-index: 1;
    position: absolute;
    overflow: hidden;
    -webkit-transition: all 0.1s ease-in-out;
    border-left: 1px solid;

}
.w-container {
  /*display: flex; */
  /* or inline-flex */
  overflow: hidden;
  position: relative;
  /*-webkit-transition: all 0.1s ease-in-out;*/

}
.grow {     
    background: black;
 }
 .growImg {
    transition-property: opacity, transform, -webkit-transform;
    transition-duration: 0.75s, 0.75s, 0.75s;
    transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1), cubic-bezier(0.19, 1, 0.22, 1), cubic-bezier(0.19, 1, 0.22, 1);
    transition-delay: 0s, 0s, 0s;
    opacity: 0.8;
    z-index: 0;

 }
.growImg:hover, .content:hover + .growImg {
       opacity: 1;
       transform: scale(1.1);

}
.close-slide {
    position: absolute;
    right: 50px;
    top: 40px;
    font-size: 200%;
    color:white;
    z-index: 1;
}
.w-white {
    color: #fff!important;
    /* background-color: #000!important; */
    font-size: 400%;
}
.w-button {
    border: none;
    display: inline-block;
        margin: 8px 40px;
    vertical-align: middle;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    background-color: inherit;
    text-align: center;
    cursor: pointer;
    white-space: nowrap;
    opacity: 0.8;
    z-index: 10;

}
.content {
    position: absolute;
    top: 0;
    color: white;
    width: 100%;
    z-index: 1;

}
.displayLeft {
    margin-left: 3em;
    font-size: 400%;
    margin-top: 6em;
}
.displayRight {
    margin-left: 1em;
    font-size: 600%;
    margin-top: 3em;
    width: 50%;
    float: right;
}
p {
    text-transform: uppercase;
    font-family: Brutal_Bold;
}
.displayLeft p {

    float: left;
    margin-right: 0.3em;
}
.displayLeft .explore {
    display: none;
}
.displayRight .explore {
    display: block;
}
.explore {
    text-decoration: none !important;
    color: white;
    font-size: 50%;
    background-color: transparent;
    border: 1px solid white;

}
.explore:hover {
    color: black;
    background-color: white;
}
.ctrl-buttons {
}

1 个答案:

答案 0 :(得分:1)

这里的问题归结于硬件和软件。

在执行动画时,某些浏览器很难。这是因为默认情况下未启用硬件加速。因此最好的办法是强制硬件加速触发。

为此,在要进行动画处理的元素上使用translate3d。对于您来说,我相信它是您的sliderTrack元素和您的grow元素。

将其添加到您的grow元素中后,我发现单击幻灯片时立即获得了巨大的进步。

因此只需添加:

.sliderTrack, .grow{
   -webkit-transform: translate3d(0, 0, 0);
   -moz-transform: translate3d(0, 0, 0);
   -ms-transform: translate3d(0, 0, 0);
   transform: translate3d(0, 0, 0);
}

我还将注意到,就我而言,在1080上,您的滑块轨道在没有加速的情况下工作正常。您会注意到该设备到设备。设备和浏览器的功能将极大地影响您的动画。使用translate3d将为他们提供最好的机会,但是如果硬件或软件不能满足任务要求,将无法如您所愿地顺利进行。