Infinite
This pen allows for the user to scroll infinitely through a list.
<div id="scroll-container"> | |
<div class="wrap-container" id="wrap-scroll"> | |
<ul id="ul-scroll"> | |
<li class="active"> | |
<span class="item"> | |
Item one | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item two | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item three | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item four | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item five | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item six | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item seven | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item eight | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item nine | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item ten | |
</span> | |
</li> | |
<li> | |
<span class="item"> | |
Item eleven | |
</span> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<svg> | |
<defs> | |
<linearGradient id="gradient" x1="0" y1="0%" x2 ="0" y2="50%"> | |
<stop stop-color="black" offset="0"/> | |
<stop stop-color="white" offset="1"/> | |
</linearGradient> | |
<mask id="masking" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"> | |
<rect y="0" width="1" height="1" fill="url(#gradient)" /> | |
</mask> | |
</defs> | |
</svg> |
var scrollW = document.getElementById("wrap-scroll"); | |
var scrollUl = document.getElementById("ul-scroll"); | |
var itemsScrolled, | |
itemsMax, | |
cloned = false; | |
var listOpts = { | |
itemCount: null, | |
itemHeight: null, | |
items: [], | |
}; | |
function scrollWrap () { | |
itemsScrolled = Math.ceil( (this.scrollTop + listOpts.itemHeight / 2 ) / listOpts.itemHeight); | |
if(this.scrollTop < 1) { | |
itemsScrolled = 0; | |
} | |
listOpts.items.forEach(function (ele) { | |
ele.classList.remove("active"); | |
}) | |
if (itemsScrolled < listOpts.items.length) { | |
listOpts.items[itemsScrolled].classList.add("active"); | |
} | |
if (itemsScrolled > listOpts.items.length - 3) { | |
for ( _x = 0; _x <= itemsMax - 1; _x++ ) { | |
var node = listOpts.items[_x]; | |
if ( !cloned ) { | |
node = listOpts.items[_x].cloneNode(true); | |
} | |
scrollUl.appendChild(node); | |
} | |
initItems(cloned); | |
cloned = true; | |
itemsScrolled = 0; | |
} | |
} | |
function initItems (scrollSmooth) { | |
listOpts.items = [].slice.call(scrollUl.querySelectorAll("li")); | |
listOpts.itemHeight = listOpts.items[0].clientHeight; | |
listOpts.itemCount = listOpts.items.length; | |
if (!itemsMax) { | |
itemsMax = listOpts.itemCount; | |
} | |
if (scrollSmooth) { | |
var seamLessScrollPoint = ((itemsMax - 3) * listOpts.itemHeight); | |
scrollW.scrollTop = seamLessScrollPoint; | |
} | |
} | |
document.addEventListener("DOMContentLoaded", function(event) { | |
initItems(); | |
scrollW.onscroll = scrollWrap; | |
}); |
$max-width: 100%; | |
$max-height: 200px; | |
$item-height: 50px; | |
body{ | |
font-family: 'Avenir'; | |
font-weight: 800; | |
text-transform: uppercase; | |
} | |
#scroll-container{ | |
overflow: hidden; | |
max-width: $max-width; | |
margin: auto; | |
height: 50vh; | |
top: 25vh; | |
position: relative; | |
min-height: $max-height; | |
} | |
.wrap-container{ | |
position: relative; | |
max-height: $max-height; | |
width: 100%; | |
max-width: $max-width; | |
margin: auto; | |
/* background: #eee; */ | |
overflow: auto; | |
padding-right: 20px; // hides scrollbar | |
mask: url(#masking); | |
-webkit-mask-image: -webkit-gradient(linear, left bottom, left top, | |
color-stop(0.5, rgba(0,0,0,1)), | |
color-stop(1, rgba(0,0,0,0))); | |
ul { | |
list-style: none; | |
position: relative; | |
transition: transform .3s; | |
top: $item-height; | |
} | |
ul, ul li{ | |
margin: 0; | |
padding: 0; | |
text-align: center; | |
} | |
ul li{ | |
height: $item-height; | |
line-height: $item-height; | |
transition: transform .3s; | |
overflow: hidden; | |
&:last-of-type{ | |
padding-bottom: $item-height; | |
} | |
&.active{ | |
.item{ | |
transform: scale(1.9); | |
} | |
} | |
} | |
ul li .item{ | |
position: relative; | |
transition: transform 200ms; | |
display: inline-block; | |
} | |
} |