jQuery(function () { var root = document.querySelector('#nowshowing'); var slider; var viewport; var pager; var prevButton; var nextButton; var originalSlides; var originalCount; var cloneSetCount = 2; var startIndex; var currentIndex; var isAnimating = false; var resizeTimer = 0; var suppressClick = false; var dragState = { active: false, pointerId: null, startX: 0, startY: 0, deltaX: 0, deltaY: 0 }; if (!root) { return; } slider = root.querySelector('.nowshowingSlider'); viewport = root.querySelector('.viewport'); pager = root.querySelector('.pager'); prevButton = root.querySelector('.sliderArrow.prev'); nextButton = root.querySelector('.sliderArrow.next'); originalSlides = slider ? Array.prototype.slice.call(slider.querySelectorAll('.item')) : []; originalCount = originalSlides.length; startIndex = originalCount * cloneSetCount; currentIndex = startIndex; if (!slider || !viewport || !pager || !prevButton || !nextButton || originalCount < 1) { return; } if (slider.getAttribute('data-nowshowing-initialized') === 'true') { return; } slider.setAttribute('data-nowshowing-initialized', 'true'); function buildSlides() { var fragment = document.createDocumentFragment(); var i; for (i = 0; i < cloneSetCount; i++) { originalSlides.forEach(function (slide) { var clone = slide.cloneNode(true); clone.setAttribute('data-loop-clone', 'before'); clone.setAttribute('aria-hidden', 'true'); fragment.appendChild(clone); }); } originalSlides.forEach(function (slide) { fragment.appendChild(slide); }); for (i = 0; i < cloneSetCount; i++) { originalSlides.forEach(function (slide) { var clone = slide.cloneNode(true); clone.setAttribute('data-loop-clone', 'after'); clone.setAttribute('aria-hidden', 'true'); fragment.appendChild(clone); }); } slider.innerHTML = ''; slider.appendChild(fragment); } function getSlideSpan() { var firstSlide = slider.querySelector('.item'); var slideStyle; if (!firstSlide) { return 0; } slideStyle = window.getComputedStyle(firstSlide); return firstSlide.getBoundingClientRect().width + parseFloat(slideStyle.marginRight || 0); } function normalizeIndex(index) { var normalized = (index - startIndex) % originalCount; if (normalized < 0) { normalized += originalCount; } return normalized; } function renderPager() { var pagerHtml = ''; pager.innerHTML = pagerHtml; } function updatePager() { var dots = pager.querySelectorAll('.loopDots li'); var activeIndex = normalizeIndex(currentIndex); Array.prototype.forEach.call(dots, function (dot, index) { dot.classList.toggle('is-active', index === activeIndex); }); } function applyPosition(animate) { var slideSpan = getSlideSpan(); if (!slideSpan) { return; } slider.style.transition = animate ? 'transform 550ms ease' : 'none'; slider.style.transform = 'translate3d(' + (slideSpan * currentIndex * -1) + 'px, 0, 0)'; } function jumpTo(index) { currentIndex = index; applyPosition(false); updatePager(); } function moveTo(index) { if (isAnimating || originalCount < 2) { return; } isAnimating = true; currentIndex = index; applyPosition(true); updatePager(); } function handleLoopBounds() { if (currentIndex >= originalCount * (cloneSetCount + 1)) { jumpTo(currentIndex - originalCount); } else if (currentIndex < originalCount * cloneSetCount) { jumpTo(currentIndex + originalCount); } } function resetDragState() { dragState.active = false; dragState.pointerId = null; dragState.startX = 0; dragState.startY = 0; dragState.deltaX = 0; dragState.deltaY = 0; } function startDrag(clientX, clientY, pointerId) { dragState.active = true; dragState.pointerId = pointerId; dragState.startX = clientX; dragState.startY = clientY; dragState.deltaX = 0; dragState.deltaY = 0; } function updateDrag(clientX, clientY) { if (!dragState.active) { return; } dragState.deltaX = clientX - dragState.startX; dragState.deltaY = clientY - dragState.startY; } function finishDrag() { var absX; var absY; if (!dragState.active) { return; } absX = Math.abs(dragState.deltaX); absY = Math.abs(dragState.deltaY); if (absX >= 30 && absX > absY) { suppressClick = true; if (dragState.deltaX < 0) { moveTo(currentIndex + 1); } else { moveTo(currentIndex - 1); } window.setTimeout(function () { suppressClick = false; }, 350); } resetDragState(); } function bindPointerEvents() { viewport.addEventListener('pointerdown', function (event) { if (event.pointerType === 'mouse' && event.button !== 0) { return; } startDrag(event.clientX, event.clientY, event.pointerId); }); viewport.addEventListener('pointermove', function (event) { if (!dragState.active || event.pointerId !== dragState.pointerId) { return; } updateDrag(event.clientX, event.clientY); }); window.addEventListener('pointerup', function (event) { if (!dragState.active || event.pointerId !== dragState.pointerId) { return; } updateDrag(event.clientX, event.clientY); finishDrag(); }); window.addEventListener('pointercancel', function (event) { if (!dragState.active || event.pointerId !== dragState.pointerId) { return; } resetDragState(); }); } function bindTouchFallback() { viewport.addEventListener('touchstart', function (event) { var touch = event.touches[0]; if (!touch) { return; } startDrag(touch.clientX, touch.clientY, 'touch'); }, { passive: true }); viewport.addEventListener('touchmove', function (event) { var touch = event.touches[0]; if (!touch) { return; } updateDrag(touch.clientX, touch.clientY); }, { passive: true }); viewport.addEventListener('touchend', function () { finishDrag(); }); viewport.addEventListener('touchcancel', function () { resetDragState(); }); } buildSlides(); renderPager(); jumpTo(startIndex); if (originalCount < 2) { prevButton.hidden = true; nextButton.hidden = true; } prevButton.addEventListener('click', function () { moveTo(currentIndex - 1); }); nextButton.addEventListener('click', function () { moveTo(currentIndex + 1); }); slider.addEventListener('transitionend', function (event) { if (event.propertyName !== 'transform') { return; } isAnimating = false; handleLoopBounds(); }); pager.addEventListener('click', function (event) { var button = event.target.closest('.loopDotButton'); var targetIndex; if (!button) { return; } targetIndex = parseInt(button.getAttribute('data-slide'), 10); if (isNaN(targetIndex)) { return; } moveTo(startIndex + targetIndex); }); viewport.addEventListener('click', function (event) { if (!suppressClick) { return; } event.preventDefault(); event.stopPropagation(); suppressClick = false; }, true); viewport.addEventListener('dragstart', function (event) { event.preventDefault(); }); if (window.PointerEvent) { bindPointerEvents(); } else { bindTouchFallback(); } window.addEventListener('load', function () { jumpTo(currentIndex); }); window.addEventListener('pageshow', function () { jumpTo(currentIndex); }); window.addEventListener('resize', function () { window.clearTimeout(resizeTimer); resizeTimer = window.setTimeout(function () { jumpTo(currentIndex); }, 40); }); });