The smoothscroll plugin for chrome(link) is a cute plugin that intercepts mousewheel events and animates the scrolling of the page so it scrolls in a nice fluid motion rather than the epileptic fashion of the default scrolling in chrome. After examining the source of the extension I decided to add it in to this blog, since blogger is so liberal about the use of javascript on the website.
Unfortunately according to this:
Firefox users will not be able to experience the endless joy of scrolling smoothly; however it is compatible with most version of IE and chrome and safari.
To get this working, just paste this in the blogger template somewhere in a pair of script tags in the header section:
// Frame Variables
var frame = false;
var noscrollframe = false;
var yoff = 0;
// Scroll Variables
// tweakables
var framerate = 60; // hz
var animtime = 400; // faster than picasa
var scrollsz = 180; // pixels
// less tweakables
var PulseScale = 10; // ratio of 'tail' to 'acceleration'
var PulseNormalize = 1;
ComputePulseScale();
var scrolls;
// Keyboard Settings
var keyboardsupport = true;
var arrscroll = 40; //in px
var arrframes = 6;
var pgscroll = 800; //in px
var pgframes = 20;
// Arrays of timeouts
var up = [], down = [];
// Other Variables
var sTop = 1337;
var delta = 0;
var initdone = false;
var d = 10;
function onloadf() {
if (!scrolls)
scrolls = setupScrolls();
if (top != self) { // Checks if this script is running in a frame
frame=true;
//if (document.documentElement.scrollHeight < (document.documentElement.clientHeight+10))
if (document.body.scrollHeight <= (document.body.clientHeight+10))
noscrollframe=true;
}
// Fix acid3 test -> make some people happy
if (document.URL != "http://acid3.acidtests.org/") {
var underlay = document.createElement('div');
underlay.setAttribute("style","z-index: -1; position:absolute; top:0px; left: 0px; width: 100%; height: "+document.body.scrollHeight+"px;");
document.body.appendChild(underlay);
/* This fixes a bug where the areas left and right
to the content does not trigger the onmousewheel event
on some pages */
}
initdone=true;
}
function wheel(event){
if (initdone==false) onloadf();
var scroll=true;
var prevent = false;
var src = window.event.srcElement;
var scrollup = true;
var scrolldown = true;
var lastdelta = delta;
delta = 0;
if (event.wheelDelta)
delta = event.wheelDelta/120;
do {
if (document.body.scrollHeight == src.scrollHeight) {
scroll=true;
break;
}
else {
if ((src.clientHeight+10) < src.scrollHeight) {
overflow = document.defaultView.getComputedStyle(src,"").getPropertyValue("overflow");
if (overflow=="scroll" || overflow=="auto") {
prevent = true;
if (src.scrollTop == sTop) {
if (src.scrollTop == 0) {
scrollup = true;
scrolldown = false;
}
else {
scrolldown = true;
scrollup = false;
}
} else {
scroll = false;
}
sTop = src.scrollTop;
scrollelm(delta,src,1); //Fixes a bug
var a = delta<0 ? up : down;
while(a.length) {
try {
clearTimeout(a.pop(a[i]));
} catch(e) {}
}
for (var i=0; i < 10; i++) {
d = 10;
(delta>0 ? up: down).push(setTimeout(function () {
scrollelm(delta,src,d)
}, i * 1000 / framerate + 1));
}
break;
}
}
}
} while(src = src.parentElement)
if (frame==true) {
if (noscrollframe==true) {
scroll=false;
}
else {
if ((yoff==window.pageYOffset) && (lastdelta<0)) {
//The last scroll downwards did nothing
scrollup=true;
scrolldown=false;
}
if ((yoff==window.pageYOffset) && (lastdelta>0)) {
//The last scroll upwards did nothing
scrollup=false;
scrolldown=true;
}
yoff = window.pageYOffset;
}
}
if (scroll==true) {
if (((scrolldown==true) && (delta < 0)) || ((scrollup==true) && (delta > 0))) {
handle(delta);
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
}
}
if (prevent == true) {
// Prevention for scrollable html elements
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
}
//Debug
//console.log("scrollup "+scrollup);
//console.log("scrolldown "+scrolldown);
//console.log("scroll "+scroll);
//console.log("frame "+frame);
//console.log("prevent "+prevent);
//console.log("noscrframe "+noscrollframe);
//console.log(document.documentElement.scrollHeight);
//console.log(document.documentElement.clientHeight+10);
}
// viscous fluid with a pulse for part and decay for the rest
function Pulse_(x)
{
var val;
// test
x = x * PulseScale;
if (x < 1) {val = x - (1 - Math.exp(-x));}
else {
// the previous animation ended here:
var start = Math.exp(-1);
// simple viscous drag
x -= 1;
var expx = 1 - Math.exp(-x);
val = start + (expx * (1.0 - start));
}
return val * PulseNormalize;
}
function ComputePulseScale()
{
PulseNormalize = 1 / Pulse_(1);
}
// viscous fluid with a pulse for part and decay for the rest
function Pulse(x)
{
if (x >= 1) return 1;
if (x <= 0) return 0;
if (PulseNormalize == 1) {
ComputePulseScale();
}
return Pulse_(x);
}
function setupScrolls() {
scrolls = new Array();
var last = 0;
var frm = parseInt(framerate * animtime / 1000);
for (var i = 0; i < frm; i++) {
// scroll is [0, 1]
var scroll = (i + 1) / frm;
// transform [0, 1] -> [0, 1]:
scroll = Pulse(scroll);
// scale and quantize to int so our pixel difference works:
var iscroll = parseInt(scrollsz * scroll + 0.99);
scrolls.push(iscroll - last);
last = iscroll;
}
return scrolls;
}
function handle(delta) {
var a = delta<0 ? up : down;
while(a.length) {
try {
clearTimeout(a.pop(a[i]));
} catch(e) {}
}
for (var i=0; i < scrolls.length; i++)
(delta>0 ? up : down).push(setTimeout('window.scrollBy( 0 ,' + -delta * scrolls[i] + ');', i * 1000 / framerate + 1));
}
function scrollelm(delta,src,d) {
if (delta > 0) {
src.scrollTop -= d;
} else {
src.scrollTop += d;
}
}
function keypress()
{
if(window.event) {
if (!(event.target instanceof HTMLInputElement) &&
!(event.target instanceof HTMLTextAreaElement) &&
(event.target.contentEditable == "false") &&
!(event.ctrlKey || event.altKey || event.shiftKey)) {
if(event.keyCode==38) {
arrscrollwindow(event.altKey ? 2 : 1);
event.preventDefault();
}
if(event.keyCode==40) {
arrscrollwindow(event.altKey ? -2 : -1);
event.preventDefault();
}
}
if(event.keyCode==33 && !event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey) {
pgscrollwindow(1);
event.preventDefault();
}
if(event.keyCode==34 && !event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey) {
pgscrollwindow(-1);
event.preventDefault();
}
}
}
function arrscrollwindow(delta) {
var a = delta<0 ? up : down;
while(a.length) {
try {
clearTimeout(a.pop(a[i]));
} catch(e) {}
}
for (var i=0; i < arrframes; i++)
(delta>0 ? up : down).push(setTimeout ('window.scrollBy( 0 ,' + -delta * (arrscroll/arrframes) + ');', i * 25));
}
function pgscrollwindow(delta) {
var a = delta<0 ? up : down;
while(a.length) {
try {
clearTimeout(a.pop(a[i]));
} catch(e) {}
}
for (var i=0; i < pgframes; i++)
(delta>0 ? up : down).push(setTimeout ('window.scrollBy( 0 ,' + -delta * (window.innerHeight/pgframes) + ');', i * 25));
}
window.onmousewheel = wheel;
window.onload = onloadf;
Basically I just deleted the parts in the plugin source that was communicating with the plugin internals, which makes this any plain old javascript.
Original source by: patrickb1991, https://chrome.google.com/extensions/detail/cccpiddacjljmfbbgeimpelpndgpoknn
0 comments:
Post a Comment