"use strict"; var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var Scroller = (function () { // set options(options) { // let defaultOptions = { // } // this._options = Object.mixin(defaultOptions, options) // doesn't actually exist >:( // } function Scroller(wrapper) { var _this = this; var scrollable = arguments[1] === undefined ? wrapper.querySelector("ul") : arguments[1]; var prev = arguments[2] === undefined ? wrapper.querySelector(".prev") : arguments[2]; var next = arguments[3] === undefined ? wrapper.querySelector(".next") : arguments[3]; return (function () { // this.options = {} _this.wrapper = wrapper; _this.ele = scrollable; _this.prevEle = prev; _this.nextEle = next; _this.isMoving = false; _this.nextEle.addEventListener("click", _this.next.bind(_this)); _this.prevEle.addEventListener("click", _this.prev.bind(_this)); _this.ele.addEventListener("scroll", _this._debounceUtil(_this._toggleControlVisibility.bind(_this))); window.addEventListener("resize", _this._toggleControlVisibility.bind(_this)); _this._toggleControlVisibility(); })(); } _prototypeProperties(Scroller, null, { _debounceUtil: { value: function _debounceUtil(func) { var wait = arguments[1] === undefined ? 100 : arguments[1]; // cribbed from http://davidwalsh.name/javascript-debounce-function var timeout = undefined; return function () { var context = this; var args = arguments; var later = function () { timeout = null; func.apply(context, args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; }, writable: true, enumerable: true, configurable: true }, _toggleControlVisibility: { value: function _toggleControlVisibility() { if (this.isMoving) return; // wait a second, geez // console.log({sl: this.ele.scrollLeft, cw: this.ele.clientWidth, summed: this.ele.scrollLeft+this.ele.clientWidth, sw: this.ele.scrollWidth}); this.prevEle.classList[this.ele.scrollLeft <= 0 ? "add" : "remove"]("hidden"); this.nextEle.classList[this.ele.scrollLeft + this.ele.clientWidth >= this.ele.scrollWidth ? "add" : "remove"]("hidden"); }, writable: true, enumerable: true, configurable: true }, next: { value: function next() { this._move(1); }, writable: true, enumerable: true, configurable: true }, prev: { value: function prev() { this._move(-1); }, writable: true, enumerable: true, configurable: true }, _move: { value: function _move() { var vector = arguments[0] === undefined ? 1 : arguments[0]; if (this.isMoving) return; var _ref = [this.ele.clientWidth, this.ele.scrollLeft, this.ele.scrollWidth]; var width = _ref[0]; var offset = _ref[1]; var scrollWidth = _ref[2]; vector = vector / Math.abs(vector); var newOffset = offset + vector * width; newOffset = Math.min(newOffset, scrollWidth - width); newOffset = Math.max(newOffset, 0); this._moveItMoveIt(offset, newOffset); }, writable: true, enumerable: true, configurable: true }, _moveItMoveIt: { value: function _moveItMoveIt(oldOffset, newOffset) { var _this = this; this.isMoving = true; var startTime = Date.now(); var duration = 300; var currentOffset = oldOffset; var animStep = function () { var currentTime = Date.now(); currentOffset = _this._easeInOutCirc(currentTime - startTime, oldOffset, newOffset - oldOffset, duration); _this.ele.scrollLeft = currentOffset; if (currentTime < startTime + duration) { requestAnimationFrame(animStep); } else { _this.isMoving = false; _this.ele.scrollLeft = newOffset; _this._toggleControlVisibility(); } }; requestAnimationFrame(animStep); }, writable: true, enumerable: true, configurable: true }, _easeInOutCirc: { value: function _easeInOutCirc(currentIteration, startValue, changeInValue, totalIterations) { // from http://kirupa.googlecode.com/svn/trunk/easing.js if ((currentIteration /= totalIterations / 2) < 1) { return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue; } return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue; }, writable: true, enumerable: true, configurable: true } }); return Scroller; })(); var yep = new Scroller(document.querySelector(".scroller"));