Animate scrolling the page - without jQuery. Code adapted from DualViewer's stepper.js
517254
function scrollToIndex(index) {
    var duration = 400;
    var start = window.pageYOffset;
    var end = index * window.innerHeight;
    var amount = end - start;
    var startTime = +new Date();

    var easing = function easing(k) {
      return -0.5 * (Math.cos(Math.PI * k) - 1);
    };

    var step = function step(value /* , percent */) {
      window.scrollTo(0, value);
    };

    var complete = function complete() {
      isScrolling = false;
    };

    var looper = function looper() {
      var now = +new Date();
      var remainingTime = startTime + duration - now;
      var percent = 1 - (remainingTime / duration || 0);

      // Abort if already past 100%.
      if (percent >= 1) {
        // Make sure it always finishes with 1.
        step(end, 1);
        complete();
        return;
      }

      // Apply easing.
      percent = easing(percent);

      // Tick.
      step(start + amount * percent, percent);

      // Request animation frame.
      requestAnimationFrame(looper);
    };

    isScrolling = true;
    requestAnimationFrame(looper);
  }
342174
function scroll (event) {
    if (!ctrl.shouldPaginate) return;
    event.preventDefault();
    if (event.deltaY) {
      ctrl.offsetLeft = fixOffset(ctrl.offsetLeft + event.deltaY);
    } else if (event.deltaX) {
      ctrl.offsetLeft = fixOffset(ctrl.offsetLeft + event.deltaX);
    }
  }
1148878
function _animate({ node, properties, duration = 200, easing, callback }) {
  let cssProperties = []
    , fakeEvent  = { target: node, currentTarget: node }
    , cssValues  = {}
    , transforms = ''
    , fired;

  if (!transitionProps.end)
    duration = 0

  Object.keys(properties).forEach(key => {
    if (isTransform(key))
      transforms += `${key}(${properties[key]}) `
    else {
      cssValues[key] = properties[key]
      cssProperties.push(hyphenate(key))
    }
  })

  if (transforms) {
    cssValues[transitionProps.transform] = transforms
    cssProperties.push(transitionProps.transform)
  }

  if (duration > 0) {
    cssValues[transitionProps.property] = cssProperties.join(', ')
    cssValues[transitionProps.duration] = `${duration / 1000  }s`
    cssValues[transitionProps.delay]    = `${0  }s`
    cssValues[transitionProps.timing]   = easing || 'linear'

    on(node, transitionProps.end, done)

    setTimeout(() => {
      if (!fired) done(fakeEvent)
    }, duration + 500)
  }

  // eslint-disable-next-line no-unused-expressions
  node.clientLeft // trigger page reflow

  css(node, cssValues)

  if (duration <= 0)
    setTimeout(done.bind(null, fakeEvent), 0)

  return {
    cancel() {
      if (fired) return
      fired = true
      off(node, transitionProps.end, done)
      css(node, reset)
    }
  }

  function done(event) {
    if (event.target !== event.currentTarget) return

    fired = true
    off(event.target, transitionProps.end, done)
    css(node, reset)
    callback && callback.call(this)
  }
}
766830
private float scrollBy(@NonNull MotionEvent event, float dx) {
        if (isSkipViewPager || isViewPagerDisabled) {
            return dx;
        }

        final State state = getState();
        getStateController().getMovementArea(state, tmpRectF);

        float pagerDx = splitPagerScroll(dx, state, tmpRectF);
        pagerDx = skipPagerMovement(pagerDx, state, tmpRectF);
        float viewDx = dx - pagerDx;

        // Applying pager scroll
        boolean shouldFixViewX = isViewPagerInterceptedScroll && viewPagerX == 0;
        int actualX = performViewPagerScroll(event, pagerDx);
        viewPagerX += actualX;
        if (shouldFixViewX) { // Adding back scroll not handled by ViewPager
            viewDx += Math.round(pagerDx) - actualX;
        }

        // Returning altered scroll left for image
        return viewDx;
    }
2
function() {
        var options = this.options;

        if (options.hideOthers) {
            this.secondary.each(function() {
                var sidebar = $(this);

                if (sidebar.hasClass('is-expanded')) {
                    sidebar.toolkit('offCanvas', 'hide');
                }
            });
        }

        this.fireEvent('showing');

        this.container.addClass('move-' + this.opposite);

        this.element
            .reveal()
            .addClass('is-expanded')
            .aria('expanded', true);

        if (options.stopScroll) {
            $('body').addClass('no-scroll');
        }

        this.fireEvent('shown');
    }
375323
function animate() {
    var diff = this.speed;

    //
    // If we're getting close to the endpoint stop at 0.
    //
    if (this.delta < diff) {
      clearInterval(this.animated);
      diff = this.delta;
    }

    //
    // Keep track of how much is scrolled.
    //
    this.delta = this.delta - diff;
    this.y = this.y + diff * this.direction;

    //
    // Animate the scroll position.
    //
    window.scrollTo(0, this.y);
  }
718000
function InfiniteScrollView (options) {
  options || (options = {});
  BaseView.call(this, options);
  InfiniteScrollSetup.call(this, options);
}
498815
function StepperView(vm, stepper) {
	function add(num) {
		stepper.value += num;
		vm.redraw();
	}

	function set(e) {
		stepper.value = +e.target.value;
	}

	// template renderer (called on each redraw)
	return function() {
		return el("#stepper", [
			el("button", {onclick: [add, -1]}, "-"),
			el("input[type=number]", {value: stepper.value, oninput: set}),
			el("button", {onclick: [add, +1]}, "+"),
		]);
	};
}
1157060
function _handleScroll() {
        // Save current scroll
        // Supports IE 9 and up.
        const nx = hasScrollContainer ? viewEl.scrollLeft : window.pageXOffset;
        const ny = hasScrollContainer ? viewEl.scrollTop : window.pageYOffset;
        scroll.setScroll(nx, ny);

        // Only called if the last animation request has been
        // completed and there are parallax elements to update
        if (!ticking && elements.length > 0) {
            ticking = true;
            window.requestAnimationFrame(_updateAllElements);
        }
    }
139574
function() {
		this.scrollToCurrent();
		window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
		document.body.addEventListener('click', this.delegateAnchors.bind(this));
	  }
1350115
function($option, scroll, animate) {
			var height_menu, height_item, y;
			var scroll_top, scroll_bottom;
			var self = this;
	
			if (self.$activeOption) self.$activeOption.removeClass('active');
			self.$activeOption = null;
	
			$option = $($option);
			if (!$option.length) return;
	
			self.$activeOption = $option.addClass('active');
	
			if (scroll || !isset(scroll)) {
	
				height_menu   = self.$dropdown_content.height();
				height_item   = self.$activeOption.outerHeight(true);
				scroll        = self.$dropdown_content.scrollTop() || 0;
				y             = self.$activeOption.offset().top - self.$dropdown_content.offset().top + scroll;
				scroll_top    = y;
				scroll_bottom = y - height_menu + height_item;
	
				if (y + height_item > height_menu + scroll) {
					self.$dropdown_content.stop().animate({scrollTop: scroll_bottom}, animate ? self.settings.scrollDuration : 0);
				} else if (y < scroll) {
					self.$dropdown_content.stop().animate({scrollTop: scroll_top}, animate ? self.settings.scrollDuration : 0);
				}
	
			}
		}
919889
function (scrollBy, animation) {
            var pages = this.pages,
              pageCount = pages.length,
              currentPage = this.currentPage + scrollBy,
              clipHeight = this.clipHeight,
              navOptions = this.options.navigation,
              activeColor = navOptions.activeColor,
              inactiveColor = navOptions.inactiveColor,
              pager = this.pager,
              padding = this.padding,
              scrollOffset;

            // When resizing while looking at the last page
            if (currentPage > pageCount) {
                currentPage = pageCount;
            }

            if (currentPage > 0) {

                if (animation !== UNDEFINED) {
                    setAnimation(animation, this.chart);
                }

                this.nav.attr({
                    translateX: padding,
                    translateY: clipHeight + this.padding + 7 + this.titleHeight,
                    visibility: VISIBLE
                });
                this.up.attr({
                      fill: currentPage === 1 ? inactiveColor : activeColor
                  })
                  .css({
                      cursor: currentPage === 1 ? 'default' : 'pointer'
                  });
                pager.attr({
                    text: currentPage + '/' + pageCount
                });
                this.down.attr({
                      x: 18 + this.pager.getBBox().width, // adjust to text width
                      fill: currentPage === pageCount ? inactiveColor : activeColor
                  })
                  .css({
                      cursor: currentPage === pageCount ? 'default' : 'pointer'
                  });

                scrollOffset = -pages[currentPage - 1] + this.initialItemY;

                this.scrollGroup.animate({
                    translateY: scrollOffset
                });

                this.currentPage = currentPage;
                this.positionCheckboxes(scrollOffset);
            }

        }
105185
function() {

        var data = window.kelmu.data[id];

        clearAnnotations();

        // Enable undo and redo in the first step if there are substeps
        if (data.stepNumber === 0 && data.subStepNumber > 0 && data.undoStack.length > 1) {
          element.find(window.kelmu.data[id].settings.undo).prop('disabled', false);
          element.find(window.kelmu.data[id].settings.begin).prop('disabled', false);
        }

        if (data.stepNumber === 0 && data.subStepNumber === 0) {
          element.find(window.kelmu.data[id].settings.undo).prop('disabled', true);
          element.find(window.kelmu.data[id].settings.begin).prop('disabled', true);
        }

        if (data.stepNumber === 0 && data.undoStack.length > 1 && data.undoPointer !== data.undoStack.length - 1) {
          element.find(window.kelmu.data[id].settings.redo).prop('disabled', false);
        }

        if (data.stepNumber === 0 && data.undoStack.length === 1) {
          element.find(window.kelmu.data[id].settings.redo).prop('disabled', true);
        }

        if (data.definitions['step' + data.stepNumber]) {

          if (data.stepNumber === data.lastStep && data.subStepNumber < data.definitions['step' + data.stepNumber].length - 1) {
            // Allow showing substeps in the final step
            element.find(window.kelmu.data[id].settings.step).prop('disabled', false);

            // Notify the animator that there will be still substeps to be shown
            window.kelmu.sendMessage(id, 'postponeEnd');
          } else if (data.stepNumber === data.lastStep && data.subStepNumber === data.definitions['step' + data.stepNumber].length - 1) {
            element.find(window.kelmu.data[id].settings.step).prop('disabled', true);
            // Notify the animator that the last substep is now shown
            window.kelmu.sendMessage(id, 'lastSubstepShown');
          }

          var svg = null;
          var arrowCounter = 0;

          // Iterate all the annotations assigned to this step/substep
          $.each(data.definitions['step' + data.stepNumber][data.subStepNumber], function(index) {

            // Ignore annotations that should not be shown with the current sound setting
            var soundEnabled = window.kelmu.data[id].settings.soundEnabled === true;
            if (!data.editorMode && soundEnabled && this.soundOption === 'off') {
              return;
            } else if (!data.editorMode && !soundEnabled && this.soundOption === 'on') {
              return;
            }

            if (this.text) {

              var annotation = $('<div></div>').addClass('kelmu-annotation');
              annotation.attr('data-annotation', index);

              if (this.html) {
                $('<div></div>').addClass('kelmu-annotation-content').html(this.text).appendTo(annotation);
              } else {
                $('<div></div>').addClass('kelmu-annotation-content').text(this.text).appendTo(annotation);
              }

              annotation.css('position', 'absolute');
              annotation.css('top', this.top + 'px');
              annotation.css('left', this.left + 'px');
              annotation.css('width', this.width + 'px');
              annotation.css('height', this.height + 'px');
              annotation.css('color', this.color);
              annotation.css('background-color', this.background);
              annotation.css('font-family', this.font);
              annotation.css('font-size', this.size + 'px');
              annotation.css('border-radius', '4px');
              annotation.css('padding', '10px');
              annotation.css('z-index', '50001');

              if (!data.editorMode) {
                // Text annotations should not accidentally capture any mouse events
                annotation.css('pointer-events', 'none');
              }

              if (this.rotate !== 0) {
                annotation.css('transform', 'rotate(' + this.rotate + 'deg)');
                annotation.css('moz-transform', 'rotate(' + this.rotate + 'deg)');
                annotation.css('webkit-transform', 'rotate(' + this.rotate + 'deg)');
                annotation.css('ms-transform', 'rotate(' + this.rotate + 'deg)');

                annotation.css('transform-origin', 'left top');
                annotation.css('moz-transform-origin', 'left top');
                annotation.css('webkit-transform-origin', 'left top');
                annotation.css('ms-transform-origin', 'left top');
              }

              if (this.background !== 'transparent' && this.shadow) {
                //TODO: editor
                annotation.css('box-shadow', '3px 3px 5px #888888');
              }

              annotationsDiv.append(annotation);

            } else if (this.button) {

              var button = $('<a></a>').addClass('kelmu-button');
              button.attr('data-annotation', index);
              button.text(this.buttonText).appendTo(annotationsDiv);

              button.css('position', 'absolute');
              button.css('top', this.top + 'px');
              button.css('left', this.left + 'px');
              button.css('font-family', this.font);
              button.css('font-size', this.size + 'px');
              button.css('white-space', 'nowrap');
              button.css('cursor', 'pointer');
              button.css('z-index', '50002');

              if (this.rotate !== 0) {
                button.css('transform', 'rotate(' + this.rotate + 'deg)');
                button.css('moz-transform', 'rotate(' + this.rotate + 'deg)');
                button.css('webkit-transform', 'rotate(' + this.rotate + 'deg)');
                button.css('ms-transform', 'rotate(' + this.rotate + 'deg)');

                button.css('transform-origin', 'left top');
                button.css('moz-transform-origin', 'left top');
                button.css('webkit-transform-origin', 'left top');
                button.css('ms-transform-origin', 'left top');
              }

              var self = this;
              button.click(function(event) {
                if (!data.editorMode || event.ctrlKey) {
                  if (self.button === 'show') {
                    handleShow(event, self);
                  } else if (self.button === 'skip') {
                    handleSkip(event, self);
                  } else {
                    $.each(window.kelmu.callbacks[id], function() {
                      this(self.button, self.parameter);
                    });
                  }
                }
              });

              annotationsDiv.append(button);

            } else if (this.arrow || this.line) {

              if (svg === null) {
                var areaWidth = container.width();
                var areaHeight = container.height();
                svg = $('<svg class="annotation-svg-container" pointer-events="none" style="z-index: 51000; position: absolute; top: 0; left: 0;" width="' + areaWidth + '" height="' + areaHeight + '"><defs></defs></svg>');
                svg.prependTo(container);
              }

              if (this.arrow) {
                var arrowMarker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
                arrowMarker.setAttribute('id', id + '-arrow-marker-' + arrowCounter);
                arrowMarker.setAttribute('viewBox', '0 0 10 10');
                arrowMarker.setAttribute('refX', '10');
                arrowMarker.setAttribute('refY', '5');
                arrowMarker.setAttribute('markerUnits', 'strokeWidth');
                arrowMarker.setAttribute('markerWidth', this.size);
                arrowMarker.setAttribute('markerHeight', this.size);
                arrowMarker.setAttribute('orient', 'auto');

                var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
                path.setAttribute('fill', this.arrow);
                path.setAttribute('stroke', this.arrow);

                svg.children('defs').append(arrowMarker);
                $(arrowMarker).append(path);
              }

              var arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
              var d = 'M ' + this.x1 + ' ' + this.y1 + ' L ' + this.x2 + ' ' + this.y2;
              arrow.setAttribute('id', 'arrow-' + arrowCounter);
              arrow.setAttribute('d', d);
              arrow.setAttribute('fill', 'none');
              arrow.setAttribute('stroke', this.arrow || this.line);
              arrow.setAttribute('stroke-width', this.width);
              if (this.arrow) {
                arrow.setAttribute('marker-end', 'url(#' + id + '-arrow-marker-' + (arrowCounter) + ')');
              }
              arrowCounter += 1;
              svg.append(arrow);
            } else if (this.action) {

              if (this.when === 'enter' && !data.editorMode) {
                var actionData = this;
                $.each(window.kelmu.callbacks[id], function() {
                  this(actionData.action, actionData.parameter);
                });
              }

            } else if (this.sound && !data.editorMode && window.kelmu.data[id].settings.soundEnabled) {
              var sound = $('<audio></audio>').attr('src', this.sound).addClass('kelmu-annotation-sound');
              container.append(sound);
              try {
                sound[0].play();
              } catch (err) {

              }
            }
          });

        }

      }
928193
function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  }
259116
function (el) {
            $el = $(el);
            $el.on('scroll', handleScroll);
            $el.on('touchstart', handleTouchstart);
            $el.on('touchmove', handleTouchmove);
            $el.on('touchend', handleTouchend);
        }
389888
function step(context) {
    var time = now();
    var value;
    var currentX;
    var currentY;
    var elapsed = (time - context.startTime) / SCROLL_TIME;

    // avoid elapsed times higher than one
    elapsed = elapsed > 1 ? 1 : elapsed;

    // apply easing to elapsed time
    value = ease(elapsed);

    currentX = context.startX + (context.x - context.startX) * value;
    currentY = context.startY + (context.y - context.startY) * value;

    context.method.call(context.scrollable, currentX, currentY);

    // scroll more if we have not reached our destination
    if (currentX !== context.x || currentY !== context.y) {
      w.requestAnimationFrame(step.bind(w, context));
    }
  }
1294884
public final void smoothScrollBy(int dx, int dy) {
        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
        if (duration > ANIMATED_SCROLL_GAP) {
            mScroller.startScroll(getScrollX(), getScrollY(), dx, dy);
            awakenScrollBars(mScroller.getDuration());
            invalidate();
        } else {
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
            scrollBy(dx, dy);
        }
        mLastScroll = AnimationUtils.currentAnimationTimeMillis();
    }