Created
January 7, 2009 16:56
-
-
Save tsukkee/44332 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name ldr smooth scroll | |
// @namespace http://relaxedcolumn.blog8.fc2.com/ | |
// @description smoothing scroll for livedoor reader (ldr) and fastladder | |
// @include http://reader.livedoor.com/reader/ | |
// @include http://reader.livedoor.com/public/* | |
// @include http://fastladder.com/reader/ | |
// ==/UserScript== | |
// | |
(function() { | |
// shorthand | |
var _gm = !!this.unsafeWindow; | |
var _w = this.unsafeWindow || window; | |
var $ = _w.$; | |
var container = $("right_container"); | |
// config | |
var config = { | |
type: "always", | |
threshold: 300, | |
duration: 300, | |
easing: "easeInOutCubic" | |
}; | |
// load config | |
if(_gm) for(var val in config) config[val] = GM_getValue(val, config[val]); | |
// easing | |
var easingFunctions = { | |
linear: function(t, b, c, d) { | |
return c * t / d + b; | |
}, | |
easeInOutCubic: function(t, b, c, d) { | |
if((t/=d/2) < 1) return c /2*t*t*t + b; | |
else return c/2*((t-=2)*t*t + 2) + b; | |
}, | |
easeInOutSine: function(t, b, c, d) { | |
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; | |
}, | |
easeInBounce: function(t, b, c, d) { | |
return c - easingFunctions.easeOutBounce(d-t, 0, c, d) + b; | |
}, | |
easeOutBounce: function(t, b, c, d) { | |
if((t/=d) <(1/2.75)) { | |
return c*(7.5625*t*t) + b; | |
} else if(t <(2/2.75)) { | |
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; | |
} else if(t <(2.5/2.75)) { | |
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; | |
} else { | |
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; | |
} | |
}, | |
easeInOutBounce: function(t, b, c, d) { | |
if(t < d/2) return easingFunctions.easeInBounce(t*2, 0, c, d) * .5 + b; | |
else return easingFunctions.easeOutBounce(t*2-d, 0, c, d) * .5 + c*.5 + b; | |
} | |
}; | |
// smooth scroll | |
var timer = null; | |
var smooth_scroll_to = function(elem, px) { | |
if(timer != null) return; | |
var startTime = Date.now(); | |
var begin = elem._scrollTop; | |
var change = px - elem.scrollTop; | |
timer = setInterval(function() { | |
var time = Date.now() - startTime; | |
elem._scrollTop = easingFunctions[config.easing](time, begin, change, config.duration); | |
if(time >= config.duration) { | |
elem._scrollTop = px; | |
stop_scroll(); | |
} | |
}, 5); | |
}; | |
var stop_scroll = function() { | |
if(timer != null) { | |
clearInterval(timer); | |
timer = null; | |
} | |
}; | |
// override scrollTop | |
var force_nonsmooth = false; | |
var current_to = 0; | |
var override_scrollTop = function(elem) { | |
elem = elem.wrappedJSObject || elem; | |
elem.__defineGetter__("_scrollTop", elem.__lookupGetter__("scrollTop")); | |
elem.__defineSetter__("_scrollTop", elem.__lookupSetter__("scrollTop")); | |
elem.__defineGetter__("scrollTop", function() { return elem._scrollTop; }); | |
elem.__defineSetter__("scrollTop", function(px) { | |
// don't cancel if distination is same as current scroll | |
if(px == current_to) return; | |
stop_scroll(); | |
current_to = px; | |
var diff = Math.abs(px - elem._scrollTop); | |
if(!force_nonsmooth && ( | |
config.type == "always" || | |
config.type == "auto" && diff > config.threshold | |
)) | |
smooth_scroll_to(elem, px); | |
else | |
elem._scrollTop = px; | |
}); | |
}; | |
override_scrollTop(container); | |
// privent scroll when go to next feed | |
// override scrollTop of each items for fastladder_fixed_item_height.js | |
var register_hook = _w.register_hook; | |
register_hook("BEFORE_PRINTFEED", function() { force_nonsmooth = true; }); | |
register_hook("BEFORE_SUBS_LOAD", function() { force_nonsmooth = true; }); | |
register_hook("AFTER_PRINTFEED", function() { | |
force_nonsmooth = false; | |
Array.slice(container.getElementsByClassName("item")).map(override_scrollTop); | |
}); | |
register_hook("AFTER_SUBS_LOAD", function() { | |
force_nonsmooth = false; | |
Array.slice(container.getElementsByClassName("item")).map(override_scrollTop); | |
}); | |
window.addEventListener('load', function() { | |
// Keybind | |
var Keybind = _w.Keybind; | |
// toggle smooth type | |
var next_type = { | |
none: "always", | |
always: "auto", | |
auto: "none" | |
}; | |
Keybind.add("S", function() { | |
config.type = next_type[config.type]; | |
_w.message('set smooth: "' + config.type + '"'); | |
if(_gm) window.setTimeout(function() { GM_setValue("type", config.type); }, 0); | |
}); | |
// scroll to top | |
Keybind.add("t", function() { container.scrollTop = 0; }); | |
// scroll to bottom | |
Keybind.add("b", function() { | |
var divs = container.getElementsByClassName("item"); | |
var last_item = divs[divs.length - 1]; | |
var target = last_item.offsetTop + last_item.offsetHeight | |
- container.offsetHeight + 40; | |
container.scrollTop = target; | |
}); | |
}, false); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment