diff --git a/components/slider/index.html b/components/slider/index.html index df3199b..d1fa6ae 100644 --- a/components/slider/index.html +++ b/components/slider/index.html @@ -24,10 +24,11 @@
-
-
+
+
+ \ No newline at end of file diff --git a/components/slider/js/slider.js b/components/slider/js/slider.js index e69de29..f7ea70e 100644 --- a/components/slider/js/slider.js +++ b/components/slider/js/slider.js @@ -0,0 +1,118 @@ +const fetchedElements = document.getElementsByClassName('slider-element'); +const sliderElements = []; +let okToMove = true; +let currentSlideIndex = 0; +const sliderContainer = document.getElementsByClassName('slider-container')[0]; +function sliderGoToIndex(index) { + if (okToMove) { + if (index < sliderElements.length && index >= 0) { + okToMove = false; + // Determine next and previous elements + let previousElement = 0; + let nextElement = 0; + if (index < sliderElements.length - 1) { + nextElement = index + 1; + } + else { + nextElement = 0; + } + if (index === 0) { + previousElement = sliderElements.length - 1; + } + else { + previousElement = index - 1; + } + // Determine move direction: + // true = next, false = previous + let moveDirection = true; + if ((index < currentSlideIndex || (index === sliderElements.length - 1 && currentSlideIndex === 0)) && !(index === 0 && currentSlideIndex === sliderElements.length - 1)) { + moveDirection = false; + } + /* + Add correct classes to all elements + */ + // New current element + sliderElements[index].classList.add('current'); + sliderElements[index].classList.remove('next'); + sliderElements[index].classList.remove('past'); + // New next element + if (moveDirection) { + sliderElements[nextElement].classList.add('future'); + } + else { + sliderElements[nextElement].classList.add('next'); + } + sliderElements[nextElement].classList.remove('current'); + sliderElements[nextElement].classList.remove('past'); + // new past element + sliderElements[previousElement].classList.add('past'); + sliderElements[previousElement].classList.remove('current'); + sliderElements[previousElement].classList.remove('next'); + // Glitch fixes + setTimeout(() => { + if (moveDirection) { + sliderElements[nextElement].classList.add('next'); + sliderElements[nextElement].classList.remove('future'); + } + currentSlideIndex = index; + setTimeout(() => { + okToMove = true; + }, 750); + }, 1000); + } + else if (index < 0) { + sliderGoToIndex(sliderElements.length - 1); + } + else { + sliderGoToIndex(0); + } + } +} +function sliderControl(action) { + if (action === 'next') { + sliderGoToIndex(currentSlideIndex + 1); + } + else if (action === 'previous') { + sliderGoToIndex(currentSlideIndex - 1); + } + sliderAutoAdvance(); +} +let sliderAutoAdvanceInterval = 0; +let sliderInterval = 0; +function activateSlider(interval) { + sliderAutoAdvanceInterval = interval; + sliderContainer.addEventListener('mouseenter', () => { + stopSliderAutoAdvance(); + }); + sliderContainer.addEventListener('mouseleave', () => { + sliderAutoAdvance(); + }); + document.addEventListener('blur', () => { + stopSliderAutoAdvance(); + }); + window.addEventListener('focus', () => { + sliderAutoAdvance(); + }); + sliderAutoAdvance(); +} +const sliderAutoAdvance = () => { + if (sliderAutoAdvanceInterval > 0) { + stopSliderAutoAdvance(); + sliderInterval = setInterval(() => { + sliderGoToIndex(currentSlideIndex + 1); + }, sliderAutoAdvanceInterval); + } +}; +const stopSliderAutoAdvance = () => { + try { + clearInterval(sliderInterval); + } + catch (e) { } + ; +}; +for (let el in fetchedElements) { + if (fetchedElements[el].className) { + sliderElements.push(fetchedElements[el]); + } +} +sliderGoToIndex(0); diff --git a/components/slider/slider.css b/components/slider/slider.css index a9b5c4e..6f78bda 100644 --- a/components/slider/slider.css +++ b/components/slider/slider.css @@ -15,14 +15,26 @@ top: calc( 50% - 1.5rem ); cursor: pointer; user-select: none; + padding: 0.5rem 1rem; + background-color: white; + text-align: center; + text-indent: 0; + line-height: 1; + transform: scale( 1 ); + transition: all 0.5s; + z-index: 10; +} + +.slider-controls:hover { + transform: scale( 1.1 ); } .slider-control-left { - left: 10px; + left: 0; } .slider-control-right { - right: 10px; + right: 0; } .slider-element { @@ -32,4 +44,29 @@ top: 0; background-size: cover; background-position: center; + transition: left 1s; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.slider-element.past { + z-index: 3; + left: 0; +} + +.slider-element.current { + z-index: 4; + left: 0; +} + +.slider-element.future { + z-index: -1; + left: 110%; +} + +.slider-element.next { + z-index: 5; + left: 150%; } \ No newline at end of file diff --git a/components/slider/ts/slider.ts b/components/slider/ts/slider.ts index e69de29..e2981e4 100644 --- a/components/slider/ts/slider.ts +++ b/components/slider/ts/slider.ts @@ -0,0 +1,130 @@ +const fetchedElements = document.getElementsByClassName( 'slider-element' ); +const sliderElements: HTMLDivElement[] = []; +let okToMove = true; +let currentSlideIndex = 0; +const sliderContainer: HTMLDivElement = ( document.getElementsByClassName( 'slider-container' )[ 0 ] as HTMLDivElement ); + +function sliderGoToIndex ( index: number ) { + if ( okToMove ) { + if ( index < sliderElements.length && index >= 0 ) { + okToMove = false; + // Determine next and previous elements + let previousElement = 0; + let nextElement = 0; + if ( index < sliderElements.length - 1 ) { + nextElement = index + 1; + } else { + nextElement = 0; + } + + if ( index === 0 ) { + previousElement = sliderElements.length - 1; + } else { + previousElement = index - 1; + } + + // Determine move direction: + // true = next, false = previous + let moveDirection = true; + if ( ( index < currentSlideIndex || ( index === sliderElements.length - 1 && currentSlideIndex === 0 ) ) && !( index === 0 && currentSlideIndex === sliderElements.length - 1 ) ) { + moveDirection = false; + } + + /* + Add correct classes to all elements + */ + + // New current element + sliderElements[ index ].classList.add( 'current' ); + sliderElements[ index ].classList.remove( 'next' ); + sliderElements[ index ].classList.remove( 'past' ); + + // New next element + if ( moveDirection ) { + sliderElements[ nextElement ].classList.add( 'future' ); + } else { + sliderElements[ nextElement ].classList.add( 'next' ); + } + sliderElements[ nextElement ].classList.remove( 'current' ); + sliderElements[ nextElement ].classList.remove( 'past' ); + + // new past element + sliderElements[ previousElement ].classList.add( 'past' ); + sliderElements[ previousElement ].classList.remove( 'current' ); + sliderElements[ previousElement ].classList.remove( 'next' ); + + // Glitch fixes + setTimeout( () => { + if ( moveDirection ) { + sliderElements[ nextElement ].classList.add( 'next' ); + sliderElements[ nextElement ].classList.remove( 'future' ); + } + currentSlideIndex = index; + setTimeout( () => { + okToMove = true; + }, 750 ); + }, 1000 ); + } else if ( index < 0 ) { + sliderGoToIndex( sliderElements.length - 1 ); + } else { + sliderGoToIndex( 0 ); + } + } +} + + +type SliderAction = 'next' | 'previous'; +function sliderControl ( action: SliderAction ) { + if ( action === 'next' ) { + sliderGoToIndex( currentSlideIndex + 1 ); + } else if ( action === 'previous' ) { + sliderGoToIndex( currentSlideIndex - 1 ); + } + + sliderAutoAdvance(); +} + +let sliderAutoAdvanceInterval = 0; +let sliderInterval = 0; +function activateSlider ( interval: number ) { + sliderAutoAdvanceInterval = interval; + sliderContainer.addEventListener( 'mouseenter', () => { + stopSliderAutoAdvance() + } ); + + sliderContainer.addEventListener( 'mouseleave', () => { + sliderAutoAdvance(); + } ); + + document.addEventListener( 'blur', () => { + stopSliderAutoAdvance() + } ); + + window.addEventListener( 'focus', () => { + sliderAutoAdvance(); + } ); + + sliderAutoAdvance(); +} + +const sliderAutoAdvance = () => { + if ( sliderAutoAdvanceInterval > 0 ) { + stopSliderAutoAdvance(); + sliderInterval = setInterval( () => { + sliderGoToIndex( currentSlideIndex + 1 ); + }, sliderAutoAdvanceInterval ); + } +} + +const stopSliderAutoAdvance = () => { + try { + clearInterval( sliderInterval ); + } catch ( e ) {}; +} + +for ( let el in fetchedElements ) { + if ( fetchedElements[ el ].className ) { + sliderElements.push( ( fetchedElements[ el ] as HTMLDivElement ) ); + } +} +sliderGoToIndex( 0 ); \ No newline at end of file