HalfScroll

  • /*
     * @title HalfScroll
     * @description スペースキーで表示域の半分の量を滑らかにスクロール
     * @include http://*
     * @license MIT License
     */
    
    (function () {
        var scrollTime = 300/*ms*/;
    
        function easing(t) {
            return t * (2 - t);
        };
    
        function calcScrollIncrement(win) {
            return win.innerHeight / 2;
        };
    
    
        var REQUEST, CANCEL, timeout;
        if (this.requestAnimationFrame) {
            REQUEST = 'requestAnimationFrame';
            CANCEL = 'cancelAnimationFrame';
        } else if (this.mozRequestAnimationFrame) {
            REQUEST = 'mozRequestAnimationFrame';
            CANCEL = 'mozCancelAnimationFrame';
        } else if (this.webkitRequestAnimationFrame) {
            REQUEST = 'webkitRequestAnimationFrame';
            CANCEL = 'webkitCancelAnimationFrame';
        } else {
            REQUEST = 'setTimeout';
            CANCEL = 'clearTimeout';
            timeout = 1000 / 60;
        }
    
        var isCSS1Compat = this.document.compatMode === 'CSS1Compat';
    
        var getPageYOffset = this.pageYOffset != null
            ? function (window) { return window.pageYOffset; }
            : isCSS1Compat
                ? function (w) { return w.document.documentElement.scrollTop; }
                : function (w) { return w.document.body.scrollTop; };
    
        var getScrollMaxY = this.scrollMaxY != null
            ? function (window) { return window.scrollMaxY; }
            : isCSS1Compat
                ? function (w) { return w.document.documentElement.scrollHeight - w.innerHeight; }
                : function (w) { return w.document.body.scrollHeight - w.innerHeight; };
    
    
        var destinationY = null;
        var requestId = null;
    
        function stopScroll(window) {
            if (requestId != null) {
                window[CANCEL](requestId);
                requestId = null;
            }
        }
    
        function startScroll(window, upward) {
            var startY = (destinationY != null ? destinationY : getPageYOffset(window)),
                scrollIncrement = calcScrollIncrement(window),
                scrollMaxY = getScrollMaxY(window),
                isAnimating = true,
                startTime;
    
            if (upward) {
                if (startY - scrollIncrement < 0) {
                    scrollIncrement = -startY;
                } else {
                    scrollIncrement *= -1;
                }
            } else {
                if (startY + scrollIncrement > scrollMaxY) {
                    scrollIncrement = scrollMaxY - startY;
                }
            }
            destinationY = startY + scrollIncrement;
    
            startTime = Date.now();
            requestId = window[REQUEST](function tick() {
                if (!isAnimating) {
                    return;
                }
                var timeRate = (Date.now() - startTime) / scrollTime;
                if (timeRate < 1) {
                    window.scrollTo(0, startY + easing(timeRate) * scrollIncrement);
                    requestId = window[REQUEST](tick, timeout);
                } else {
                    window.scrollTo(0, destinationY);
                    destinationY = null;
                    isAnimating = false;
                }
            }, timeout);
        }
    
        function handleEvent(e) {
            if (e.keyCode === 32 && !e.altKey && !e.ctrlKey && !e.metaKey) {
                var tagName = e.target.tagName;
                if (tagName === 'TEXTAREA' || tagName === 'INPUT' ||
                    e.target.isContentEditable) { return; }
    
                stopScroll(e.view);
                startScroll(e.view, e.shiftKey);
                e.preventDefault();
            }
        }
    
        this.document.addEventListener('keydown', handleEvent, false);
    }).call(this);
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2013/06/11 03:50:06 - 2013-06-11
  2. 2013/06/11 03:45:49 - 2013-06-11
  3. 2013/06/11 03:04:39 - 2013-06-11