github.com/elves/elvish@v0.15.0/website/home.js (about)

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