简体   繁体   English

带有 ken-burns-out 图像的 Slick Slider 跳跃错误

[英]Slick Slider with ken-burns-out image jumps bug

After the slide animation (scale(1.3) to scale(1)) finishes and moving back to the slide I get this annoying jump.在幻灯片动画(缩放(1.3)到缩放(1))完成并移回幻灯片后,我得到了这个恼人的跳跃。

I want that each active slide will be already in scale(1.3) without the jump.我希望每个活动幻灯片都已经按比例缩放(1.3)而无需跳转。

 $('.home-slider').slick({ slidesToScroll: 1, slidesToShow: 1, //arrows: true, autoplay: true, autoplaySpeed: 7000, dots: false })
 body, html { height: 100%; background: #333; font-family: 'Roboto', sans-serif; } .slideshow { position: relative; z-index: 1; height: 100%; max-width: 700px; margin: 50px auto; } .slideshow .item { height: 100%; position: relative; z-index: 1; } .slideshow .item img { width: 100%; } .slideshow .item.slick-active img { -webkit-animation: ken-burns-out 8s 1 ease-in-out forwards; animation: ken-burns-out 8s 1 ease-in-out forwards; } /*//The animation: from 1.3 scale to 1*/ @-webkit-keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3) } to { -webkit-transform: scale(1); transform: scale(1) } } @keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3) } to { -webkit-transform: scale(1); transform: scale(1) } }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" rel="stylesheet"/> <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script> <div class="slideshow"> <div class="home-slider"> <div class="item"> <img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" /> </div> <div class="item"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" /> </div> </div> </div>

The problem happens because all of the images gets the same z-index.出现问题是因为所有图像都获得相同的 z-index。

My code doesn't work when you navigate from first slide to last slide (slide right), but it's something to start with.当您从第一张幻灯片导航到最后一张幻灯片(向右滑动)时,我的代码不起作用,但这是一个开始。

first of all, delete the z-index from this selector: .slideshow .item .首先,从这个选择器中删除 z-index: .slideshow .item

Then, add transform to every image in order every image to start with this scale (maybe add class name to each image and then change the selector):然后,为每个图像添加变换,以便每个图像都以这个比例开始(可能为每个图像添加类名,然后更改选择器):

img {
  transform: scale(1.3);
}

Add a function to get slick by index (there are cloned slicks elements so I use the selector that gets un-cloned slicks):添加一个函数以通过索引获取平滑(有克隆的 slicks 元素,因此我使用获取未克隆的 slick 的选择器):

function getSlickByIndex(index) {
  return $('.item:not(.slick-cloned)[data-slick-index="' + index + '"]');
}

Then, add init event (the logic makes the first slide to get the bigger zIndex=1 of all of his siblings that have zIndex=0), and beforeChange (the logic makes the next slick to get the bigger index and the others to get the smaller index):然后,添加init事件(逻辑使第一张幻灯片获得 zIndex=0 的所有兄弟姐妹中更大的 zIndex=1)和beforeChange (逻辑使下一张beforeChange获得更大的索引,其他人获得较小的索引):

$('.home-slider').on('init', function(event, slick){
  getSlickByIndex(0).css('zIndex', '1');
}).on('beforeChange', function(event, slick, currentSlide, nextSlide){
  getSlickByIndex(currentSlide).css('zIndex', '0');
  getSlickByIndex(nextSlide).css('zIndex', '1');
});

Demo演示

 img { transform: scale(1.3); } body, html { height: 100%; background: #333; font-family: 'Roboto', sans-serif; } .slideshow { position: relative; z-index: 1; height: 100%; max-width: 700px; margin: 50px auto; } .slideshow .item { height: 100%; position: relative; z-index: 1; } .slideshow .item img { width: 100%; } .slideshow .item.slick-active img { -webkit-animation: ken-burns-out 8s 1 ease-in-out forwards; animation: ken-burns-out 8s 1 ease-in-out forwards; } /*//The animation: from 1.3 scale to 1*/ @-webkit-keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3) } to { -webkit-transform: scale(1); transform: scale(1) } } @keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3) } to { -webkit-transform: scale(1); transform: scale(1) } }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script> <div class="slideshow"> <div class="home-slider"> <div class="item"> <img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" /> </div> <div class="item"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" /> </div> <div class="item"> <img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" /> </div> <div class="item"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" /> </div> </div> </div> <script> function getSlickByIndex(index) { return $('.item:not(.slick-cloned)[data-slick-index="' + index + '"]'); } $('.home-slider').on('init', function(event, slick){ getSlickByIndex(0).css('zIndex', '5555'); }).on('beforeChange', function(event, slick, currentSlide, nextSlide){ getSlickByIndex(currentSlide).css('zIndex', '0'); getSlickByIndex(nextSlide).css('zIndex', '5555'); }); $('.home-slider').slick({ slidesToScroll: 1, slidesToShow: 1, //arrows: true, autoplay: true, autoplaySpeed: 7000, dots: false }); </script>

This is a working fiddle: https://codepen.io/alonsh/pen/JQmZjj这是一个工作小提琴: https : //codepen.io/alonsh/pen/JQmZjj

Your images are starting with a scale of 1, then when they become active the animation starts them off at 1.3 which is what causes the jump.您的图像以 1 的比例开始,然后当它们处于活动状态时,动画以1.3开始它们,这就是导致跳跃的原因。 What you need to do is start all the images off at a scale(1.3) by adding this to the .item img css definition.您需要做的是通过将其添加到.item img css 定义中以scale(1.3)开始所有图像。 Doing only that causes the images to overflow onto one another.仅这样做会导致图像相互溢出。 To combat that make sure the contents of each .item don't overflow by adding overflow: hidden which results in:为了解决这个问题,通过添加overflow: hidden来确保每个.item的内容不会溢出,这会导致:

EDIT编辑

Which results in code which still doesn't quite work correctly.这导致代码仍然不能正常工作。 We still need everything from the previous answer but we end up with the opposite issue where the images jump to the fully zoomed size when they're switched off.我们仍然需要上一个答案中的所有内容,但是我们最终遇到了相反的问题,即当它们关闭时图像会跳转到完全缩放的尺寸。

This became a bit of a rabbit hole, but there is an animation-play-state property in css which we can use to pause the animation at the state it is in when an item becomes inactive, so I made the animation play on every .item element, which means that when it's scrolled away and the active class is lost, it will pause the animation where it is.这有点像一个兔子洞,但是 css 中有一个animation-play-state属性,我们可以使用它在项目变为非活动状态时暂停动画,所以我让动画在每个.item元素,这意味着当它滚动离开并且活动类丢失时,它将在它所在的位置暂停动画。

This almost gets us to the desired result, but then when an image is brought back into view, it resumes from where it has left off.这几乎让我们得到了想要的结果,但是当图像重新出现时,它会从停止的地方恢复。 It turns out there isn't a pretty way to get a css animation to restart, so what I'm doing is I've bound to the slide change event for slick and when a slide has changed (which I believe guarantees only the active slide is visible) I reset the .item animation.事实证明,没有一个很好的方法可以让 css 动画重新启动,所以我正在做的是我已经绑定到幻灯片的幻灯片更改事件以及幻灯片更改时(我相信这只能保证活动幻灯片可见)我重置了.item动画。 In order to do this in a way which doesn't interrupt the active slide I've added a class .animated which I can remove, then add back later in a setTimeout .为了以不中断活动幻灯片的方式执行此操作,我添加了一个.animated类,我可以将其删除,然后稍后在setTimeout添加回来。 The delay is needed in order for the animation to restart.需要延迟才能重新启动动画。

You'd hope that was the end, but you'd be wrong.你希望这就是结局,但你错了。 THEN Slick considers a started swipe, which then lands back on the same image to be a slide change ("change") so I added a current slide variable to keep track of which slide we are on and only reset the .animated class if the slide did actually change. THEN Slick 考虑开始滑动,然后返回到同一图像上作为幻灯片更改(“更改”),因此我添加了一个当前幻灯片变量来跟踪我们在哪个幻灯片上,并且仅在出现.animated时才重置.animated类幻灯片确实发生了变化。 Important Note: in a real project I would wrap this currentSlide in some sort of class/object to track the state of an individual slideshow, because as it stands you couldn't have more than one slideshow on a single page without them interfering.重要提示:在实际项目中,我会将这个currentSlide包装在某种类/对象中以跟踪单个幻灯片的状态,因为就目前而言,在一个页面上不能有多个幻灯片而不受它们的干扰。 But I wasn't going to write all of that for a simple example.但我不会为了一个简单的例子写所有这些。

After all of this, we end up with slightly different CSS and a bit more JS to get a working result:毕竟,我们最终得到了稍微不同的 CSS 和更多的 JS 以获得工作结果:

 $('.home-slider').slick({ slidesToScroll: 1, slidesToShow: 1, //arrows: true, autoplay: true, autoplaySpeed: 7000, dots: false }); var currentSlide = 0; $('.home-slider').on('afterChange', function(event, slick, newSlide){ var items = $('.home-slider .item'); if(currentSlide != newSlide){ currentSlide = newSlide; items.removeClass('animated'); setTimeout(function(){ items.addClass('animated'); }); } });
 body, html { height: 100%; background: #333; font-family: 'Roboto', sans-serif; } .slideshow { position: relative; z-index: 1; height: 100%; max-width: 700px; margin: 50px auto; } .slideshow .item { height: 100%; position: relative; overflow: hidden; } .slideshow .item img { width: 100%; -webkit-transform: scale(1.3); transform: scale(1.3); } .slideshow .item.animated img { -webkit-animation: ken-burns-out 8s 1 ease-in-out forwards; animation: ken-burns-out 8s 1 ease-in-out forwards; animation-play-state: paused; } .slideshow .item.slick-active img { animation-play-state: running; } /*//The animation: from 1.3 scale to 1*/ @-webkit-keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3); } to { -webkit-transform: scale(1); transform: scale(1) } } @keyframes ken-burns-out { 0% { -webkit-transform: scale(1.3); transform: scale(1.3) } to { -webkit-transform: scale(1); transform: scale(1) } }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" rel="stylesheet"/> <link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script> <div class="slideshow"> <div class="home-slider"> <div class="item animated"> <img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" /> </div> <div class="item animated"> <img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" /> </div> </div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM