1// File#: _2_image-comparison-slider 2// Usage: codyhouse.co/license 3(function() { 4 var ComparisonSlider = function(element) { 5 this.element = element; 6 this.modifiedImg = this.element.getElementsByClassName('js-compare-slider__img--modified')[0]; 7 this.handle = this.element.getElementsByClassName('js-compare-slider__handle')[0]; 8 this.keyboardHandle = this.element.getElementsByClassName('js-compare-slider__input-handle')[0]; 9 this.captions = this.element.getElementsByClassName('js-compare-slider__caption'); 10 // drag 11 this.dragStart = false; 12 this.animating = false; 13 this.leftPosition = 50; 14 // store container width 15 this.sliderWidth = getSliderWidth(this); 16 initComparisonSlider(this); 17 }; 18 19 function getSliderWidth(slider) { 20 return slider.element.offsetWidth; 21 }; 22 23 function initComparisonSlider(slider) { 24 // initial animation 25 if(reducedMotion) { // do not animate slider elements 26 Util.addClass(slider.element, 'compare-slider--reduced-motion compare-slider--in-viewport'); 27 } else if(intersectionObserverSupported) { // reveal slider elements when it enters the viewport 28 var observer = new IntersectionObserver(sliderObserve.bind(slider), { threshold: [0, 0.3] }); 29 observer.observe(slider.element); 30 } else { // reveal slider elements right away 31 Util.addClass(slider.element, 'compare-slider--in-viewport'); 32 } 33 // init drag functionality 34 new SwipeContent(slider.element); 35 slider.element.addEventListener('dragStart', function(event){ 36 if(!event.detail.origin.closest('.js-compare-slider__handle')) return; 37 Util.addClass(slider.element, 'compare-slider--is-dragging'); 38 if(!slider.dragStart) { 39 slider.dragStart = event.detail.x; 40 detectDragEnd(slider); 41 } 42 }); 43 // slider.element.addEventListener('dragging', function(event){ 44 slider.element.addEventListener('mousemove', function(event){ 45 sliderDragging(slider, event) 46 }); 47 slider.element.addEventListener('touchmove', function(event){ 48 sliderDragging(slider, event) 49 }); 50 51 // detect mouse leave 52 slider.element.addEventListener('mouseleave', function(event){ 53 sliderResetDragging(slider, event); 54 }); 55 slider.element.addEventListener('touchend', function(event){ 56 sliderResetDragging(slider, event); 57 }); 58 59 // on resize -> update slider width 60 window.addEventListener('resize', function(){ 61 slider.sliderWidth = getSliderWidth(slider); 62 }); 63 64 // detect change in keyboardHandle input -> allow keyboard navigation 65 slider.keyboardHandle.addEventListener('change', function(event){ 66 slider.leftPosition = Number(slider.keyboardHandle.value); 67 updateCompareSlider(slider, 0); 68 }); 69 }; 70 71 function sliderDragging(slider, event) { 72 if(!slider.dragStart) return; 73 var pageX = event.pageX || event.touches[0].pageX; 74 if(slider.animating || Math.abs(pageX - slider.dragStart) < 5) return; 75 slider.animating = true; 76 updateCompareSlider(slider, pageX - slider.dragStart); 77 slider.dragStart = pageX; 78 }; 79 80 function sliderResetDragging(slider, event) { 81 if(!slider.dragStart) return; 82 if(event.pageX < slider.element.offsetLeft) { 83 slider.leftPosition = 0; 84 updateCompareSlider(slider, 0); 85 } 86 if(event.pageX > slider.element.offsetLeft + slider.element.offsetWidth) { 87 slider.leftPosition = 100; 88 updateCompareSlider(slider, 0); 89 } 90 }; 91 92 function sliderObserve(entries, observer) { 93 if(entries[0].intersectionRatio.toFixed(1) > 0) { // reveal slider elements when in viewport 94 Util.addClass(this.element, 'compare-slider--in-viewport'); 95 observer.unobserve(this.element); 96 } 97 }; 98 99 function detectDragEnd(slider) { 100 document.addEventListener('click', function cb(event){ 101 document.removeEventListener('click', cb); 102 Util.removeClass(slider.element, 'compare-slider--is-dragging'); 103 updateCompareSlider(slider, event.detail.x - slider.dragStart); 104 slider.dragStart = false;
105 }); 106 }; 107 108 function updateCompareSlider(slider, delta) { 109 var percentage = (delta*100/slider.sliderWidth); 110 if(isNaN(percentage)) return; 111 slider.leftPosition = Number((slider.leftPosition + percentage).toFixed(2)); 112 if(slider.leftPosition < 0) slider.leftPosition = 0; 113 if(slider.leftPosition > 100) slider.leftPosition = 100; 114 // update slider elements -> modified img width + handle position + input element (keyboard accessibility) 115 slider.keyboardHandle.value = slider.leftPosition; 116 slider.handle.style.left = slider.leftPosition + '%'; 117 slider.modifiedImg.style.width = slider.leftPosition + '%'; 118 updateCompareLabels(slider); 119 slider.animating = false; 120 }; 121 122 function updateCompareLabels(slider) { // update captions visibility 123 for(var i = 0; i < slider.captions.length; i++) { 124 var delta = ( i == 0 ) 125 ? slider.captions[i].offsetLeft - slider.modifiedImg.offsetLeft - slider.modifiedImg.offsetWidth 126 : slider.modifiedImg.offsetLeft + slider.modifiedImg.offsetWidth - slider.captions[i].offsetLeft - slider.captions[i].offsetWidth; 127 Util.toggleClass(slider.captions[i], 'compare-slider__caption--is-hidden', delta < 10); 128 } 129 }; 130 131 //initialize the ComparisonSlider objects 132 var comparisonSliders = document.getElementsByClassName('js-compare-slider'), 133 intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype), 134 reducedMotion = Util.osHasReducedMotion(); 135 if( comparisonSliders.length > 0 ) { 136 for( var i = 0; i < comparisonSliders.length; i++) { 137 (function(i){ 138 new ComparisonSlider(comparisonSliders[i]); 139 })(i); 140 } 141 } 142}());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.