github.com/xiaq/elvish@v0.12.0/website/assets/home-demos.js (about) 1 (function() { 2 var current = 0, 3 expanded = true; 4 expander = document.getElementById('demo-expander'), 5 demoWindow = document.getElementById("demo-window"), 6 demoContainer = document.getElementById("demo-container"), 7 demoSwitcher = document.getElementById("demo-switcher"), 8 demoWrappers = document.getElementsByClassName("demo-wrapper"), 9 nDemos = demoWrappers.length, 10 switcherLinks = []; 11 12 var scrollTo = function(to, instant) { 13 if (expanded) { 14 return; 15 } 16 if (current != null) { 17 switcherLinks[current].className = ""; 18 } 19 var translate = -demoWrappers[0].offsetWidth * to; 20 demoContainer.className = instant ? "" : "animated-transition"; 21 demoContainer.style.transform = "translateX(" + translate + "px)"; 22 switcherLinks[to].className = "current"; 23 current = to; 24 }; 25 var scrollToNext = function() { 26 scrollTo(current < nDemos - 1 ? current + 1 : current); 27 }; 28 var scrollToPrev = function() { 29 scrollTo(current > 0 ? current - 1 : current); 30 }; 31 function scrollToCurrent() { 32 scrollTo(current); 33 } 34 35 function expand() { 36 expanded = true; 37 expander.className = "current"; 38 switcherLinks[current].className = ""; 39 demoContainer.className = "expanded"; 40 demoContainer.style.transform = ""; 41 } 42 function collapse() { 43 switcherLinks[current].className = "current"; 44 expander.className = ""; 45 demoContainer.className = ""; 46 } 47 expander.onclick = expand; 48 49 /* Build demo switcher. */ 50 for (var i = 0; i < nDemos; i++) { 51 var li = document.createElement("li"), 52 link = document.createElement("a"); 53 link.textContent = i + 1; 54 link.onclick = (function(to) { return function() { 55 if (expanded) { 56 expanded = false; 57 collapse(); 58 } 59 scrollTo(to); 60 }; })(i); 61 if (i == 0) { 62 link.className = "current"; 63 } 64 switcherLinks.push(link); 65 li.appendChild(link); 66 demoSwitcher.appendChild(li); 67 } 68 69 /* Switcher built. Hide the warning text, show the expand button, unexpand 70 * and hide scrollbar. */ 71 document.getElementById('demo-js-warning').className = "no-display"; 72 document.getElementById('demo-expander-li').className = ""; 73 demoContainer.className = ""; 74 demoWindow.className = "overflow-hidden"; 75 expanded = false; 76 77 /* Resizing breaks sliding, fix it. */ 78 window.addEventListener('resize', function() { scrollTo(current, true); }); 79 80 /* Scrolling primitives. */ 81 var scrollXTrigger = 5, scrollYTrigger = 5; 82 var scrollX = false, scrollY = false; 83 var offsetX = 0, offsetY = 0, baseOffset = 0; 84 function handleScroll(ev) { 85 if (!scrollX && !scrollY) { 86 if (Math.abs(offsetX) > scrollXTrigger) { 87 baseOffset = offsetX; 88 scrollX = true; 89 } else if (Math.abs(offsetY) > scrollYTrigger) { 90 baseOffset = offsetY; 91 scrollY = true; 92 } 93 } 94 if (!scrollX) { 95 return; 96 } 97 // No overscrolling. 98 var calculatedOffset = offsetX - baseOffset; 99 if ((current == 0 && calculatedOffset > 0) || 100 (current == nDemos-1 && calculatedOffset < 0)) { 101 calculatedOffset = 0; 102 } 103 var translate = calculatedOffset - demoWrappers[0].offsetWidth * current; 104 demoContainer.style.transform = "translateX(" + translate + "px)"; 105 ev.preventDefault(); 106 } 107 function settleScroll() { 108 if (scrollX) { 109 var threshold = Math.min(60, demoWindow.offsetWidth / 4); 110 if (offsetX < -threshold) { 111 scrollToNext(); 112 } else if (offsetX > threshold) { 113 scrollToPrev(); 114 } else { 115 scrollToCurrent(); 116 } 117 } 118 offsetX = offsetY = baseOffset = 0; 119 scrollX = scrollY = false; 120 } 121 122 /* Support scrolling by touch. */ 123 var initX, initY; 124 demoWindow.addEventListener('touchstart', function(ev) { 125 if (expanded) { 126 return; 127 } 128 initX = ev.touches[0].clientX; 129 initY = ev.touches[0].clientY; 130 demoContainer.className = ""; 131 }); 132 demoWindow.addEventListener('touchmove', function(ev) { 133 if (expanded) { 134 return; 135 } 136 if (ev.touches.length == 1) { 137 var lastX = ev.touches[0].clientX; 138 var lastY = ev.touches[0].clientY; 139 offsetX = lastX - initX; 140 offsetY = lastY - initY; 141 handleScroll(ev); 142 // document.getElementById('demo-debug').innerText = '(' + offsetX + ', ' + offsetY + '), ' + scrollX + ', ' + scrollY; 143 } 144 }); 145 demoWindow.addEventListener('touchcancel', function() { 146 if (expanded) { 147 return; 148 } 149 scrollTo(current); 150 }); 151 demoWindow.addEventListener('touchend', function() { 152 if (expanded) { 153 return; 154 } 155 settleScroll(); 156 }); 157 158 // Keyboard bindings. 159 window.addEventListener('keypress', function(ev) { 160 var char = String.fromCodePoint(ev.keyCode || ev.charCode); 161 if (char == 'h') { 162 scrollToPrev(); 163 } else if (char == 'l') { 164 scrollToNext(); 165 } else if (char == 'o') { 166 expanded = !expanded; 167 if (expanded) { 168 expand(); 169 } else { 170 collapse(); 171 scrollToCurrent(); 172 } 173 } else { 174 var i = parseInt(char); 175 if (1 <= i && i <= nDemos) { 176 if (expanded) { 177 expanded = false; 178 collapse(); 179 } 180 scrollTo(i-1); 181 } 182 } 183 }); 184 })();