HalfScroll
by
rikuba
2013-06-11 [2013/06/11 03:50:06]
スペースキーで表示域の半分の量を滑らかにスクロール
@@ -17,9 +17,7 @@
};
- var FPS60 = 1000 / 60;
-
- var REQUEST, CANCEL;
+ var REQUEST, CANCEL, timeout;
if (this.requestAnimationFrame) {
REQUEST = 'requestAnimationFrame';
CANCEL = 'cancelAnimationFrame';
@@ -32,6 +30,7 @@
} else {
REQUEST = 'setTimeout';
CANCEL = 'clearTimeout';
+ timeout = 1000 / 60;
}
var isCSS1Compat = this.document.compatMode === 'CSS1Compat';
@@ -87,13 +86,13 @@
var timeRate = (Date.now() - startTime) / scrollTime;
if (timeRate < 1) {
window.scrollTo(0, startY + easing(timeRate) * scrollIncrement);
- requestId = window[REQUEST](tick, FPS60);
+ requestId = window[REQUEST](tick, timeout);
} else {
window.scrollTo(0, destinationY);
destinationY = null;
isAnimating = false;
}
- }, FPS60);
+ }, timeout);
}
function handleEvent(e) {
/*
* @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 です。