Jquery动画跳动

标签 jquery

我正在尝试创建一个动画 slider 。

当屏幕分辨率超过 1265px 时, slider 应自动旋转(在笔记本电脑上使用 Ctrl+- 进行模拟)

我使用 jQuery.animation 但结果太跳跃。

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

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 {
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class=" w-container">
        <div class="sliderTrack">
            <div class="mySlides grow" onclick="wSlider.focusSlide(this)">
                <div class="content">
                    <div class="displayLeft h1 word-amount-2">
                        <p>
                            <span>Unreal</span>
                        </p>
                        <p>
                            <span>Engine</span>
                        </p>
                        <button href="https://www.unrealengine.com" class="explore">
                            Explore</a>
                    </div>
                </div>
                <img class="growImg"
                    src="https://cdn2.unrealengine.com/Epic+Games+Node%2Fue-alt-1920x1080-e653a4a4dae65307fd2420076abe44bb71b22f06.jpg"
                    style="width: 100%">

                <div class="close-slide" onclick="wSlider.unfocusSlide(this)">X</div>

            </div>
            <div class="mySlides grow" onclick="wSlider.focusSlide(this)">
                <div class="content">
                    <div class="displayLeft h1 word-amount-1">
                        <p>
                            <span>Fortnite</span>
                        </p>
                        <button class="explore">
                            Explore</a>
                    </div>
                </div>
                <img class="growImg"
                    src="https://cdn2.unrealengine.com/Epic+Games+Node%2Ffn-1920x1080-05e434e24b3170bc6cc6003c102270ee4cde3a75.jpg"
                    style="width: 100%">
                <div class="close-slide" onclick="wSlider.unfocusSlide(this)">X</div>

            </div>
            <div class="mySlides grow" onclick="wSlider.focusSlide(this)">

                <div class="content" style="">
                    <div class="displayLeft h1 word-amount-2">
                        <p>
                            <span>Robo</span>
                        </p>
                        <p>
                            <span>Recall</span>
                        </p>
                        <button class="explore">
                            Explore</a>
                    </div>
                </div>
                <img class="growImg"
                    src="https://cdn2.unrealengine.com/Epic+Games+Node%2Frr-1920x1080-5a3f8bce26f45d078c2738cf5140ad18be39041c.jpg"
                    style="width: 100%">

                <div class="close-slide" onclick="wSlider.unfocusSlide(this)">X</div>
            </div>

        </div>
    </div>

    <div class="ctrl-buttons">
        <button class="w-button w-white w3-display-left"
            onclick="wSlider.sliderMove(-1)">&#10094;</button>
        <button class="w-button w-white w3-display-right"
            onclick="wSlider.sliderMove(1)">&#10095;</button>
    </div>

最佳答案

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

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

为此,请在受动画影响的元素上使用 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 上,您的 slider 轨道在没有加速的情况下工作正常。您会注意到此设备。设备和浏览器的功能将极大地影响您的动画。使用 translate3d 将为他们提供最好的机会,但如果硬件或软件不能胜任任务,它就不会像您希望的那样顺利执行。

关于Jquery动画跳动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52767168/

相关文章:

jquery - Asp.net MVC with Entity,使用jquery将数据传递到List中。不起作用

php - Jquery将不同的id值传递给包含变量的通用函数

javascript - rails : Foundation 5 Reveal Modal to Submit Button

jquery - 如何在 django 中序列化字典以在 Jquery 中呈现 [问题级别 - 初学者]

jQuery 'has attribute' 选择器在 IE7 中失败(对于 'autofocus' )

JavaScript 数学计算不正确

javascript - 我希望主图像在相册照片页面上的上一张和下一张图像的缩略图之前加载

javascript - 尝试右对齐 Javascript 中的弹出元素

javascript - 使用相对位置和绝对位置时,我的图像消失了

javascript - 如何使用 jQuery 将新元素添加到生成的元素中?