网页图片跑马灯滚动效果的需求:均速无限滚动,无缝衔接滚动,鼠标悬浮暂停滚动,鼠标移动恢复滚动,可以向左或向右滚动。实现原理,利用gsap参数x和repeat。
效果如下:
HTML代码:
<div class="gallery"> <ul id="marquee"> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> <li> <a href=""> <img class="img" src="../images/gallery_01.jpg" alt=""/> </a> </li> </ul> </div>
CSS代码:
.gallery .list {display:flex;} .gallery .list:nth-child(2n){justify-content:flex-end;}/*反方向,不需要则删除*/ .gallery ul {width: max-content; display:flex;} .gallery li {width: 2.8rem; padding: 0.16rem 0.1rem;} .gallery a {padding-bottom: 38.46153846%; position:relative; overflow:hidden; display:block;} .gallery img {display:block; width:100%; height:100%; object-fit:cover; position:absolute; left:0; top:0;} @media only screen and (max-width: 750px) { .gallery li {width: 2.15rem; padding: 0.1rem 0.075rem;} }
js代码如下:
function initMarquee(selector, duration, direction) { const marqueeTrack = document.querySelector(selector); const singleWidth = marqueeTrack.scrollWidth / 3; //因为复制了两份,但只要一份的宽度 const xValue = direction == 'left' ? `-=${singleWidth * 2}` : `+=${singleWidth * 2}`; const tl = gsap.to(marqueeTrack, { x: xValue, duration: duration, ease: 'none', repeat: -1, }); marqueeTrack.addEventListener('mouseenter', () => { tl.pause(); }); marqueeTrack.addEventListener('mouseleave', () => { tl.play(); }); } $(function(){ const _gallery = $('.gallery'); const _paver = Math.ceil(_gallery.find('li').length / 3); const _pwidth = _gallery.find('li').innerWidth(); _gallery.find('li').unwrap('ul').each(function(e){ _gallery.find('li').slice(e*_paver, e*_paver+_paver).wrapAll('<div class="list"><ul id="marquee'+e+'"></ul></div>'); }); _gallery.find('ul').each(function(e){ const _self = $(this); const _total = _self.find('li').length * _pwidth; const _marq = $(this).attr('id'); if(_total > _gallery.width()){ const _copy = _self.html(); _self.prepend(_copy).prepend(_copy);//复制两份实现无缝滚动,越多越影响性能 const _dure = e % 2 == 0 ? 25 : 30; initMarquee('#'+_marq, _dure, 'left'); } }); });
改良:
判断数量是否足够超过一行的排版,如果不超过,就显示一行滚动;超过一行少于三行,则两行滚动;超过两行,则三行滚动。
const $gallery = $('.gallery'); const $total = $gallery.find('li').length; if($total > 4){ const $rows = Math.floor($total/4); if($rows > 1){ const $event = $rows == 2 ? $rows : 3; const $paver = Math.ceil($total / $event); const $itemWidth = $gallery.find('li').innerWidth(); $gallery.find('li').unwrap('ul').each(function(e){ $gallery.find('li').slice(e*$paver, e*$paver+$paver).wrapAll('<div class="list"><ul id="marquee'+e+'"></ul></div>'); }); $gallery.find('ul').each(function(e){ const _self = $(this); const _total = _self.find('li').length * $itemWidth; const _marq = $(this).attr('id'); if(_total > $gallery.width()){ const _copy = _self.html(); _self.prepend(_copy).prepend(_copy); const _dure = e % 2 == 0 ? 25 : 30; initMarquee('#'+_marq, _dure, 'left'); } }); }else{ $gallery.find('ul').wrapAll('<div class="list"></div>'); initMarquee('#marquee', 30, 'left'); } }
PS:代码不通用,要实际应用修改,经测试在Chrome和Firefox浏览器上可运行,其它浏览器未测试。