- // ==UserScript==
- // @name Smoothscroll
- // @include http*
- // @author Creec Winceptor
- // @description Smooth scrolling on pages using javascript and jquery
- // @namespace https://greasyfork.org/users/3167
- // @run-at document-idle
- // @grant none
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_registerMenuCommand
- // @version 1.3
- // ==/UserScript==
-
- if (window.top != window.self) //don't run on frames or iframes
- return;
-
-
-
-
-
- //DEFAULT SETTINGS HERE
- //DO NOT CHANGE ANYTHING HERE ANYMORE, USE SCRIPT COMMANDS -> CONFIGURE SMOOTHSCROLL
-
-
-
-
-
-
- //Smoothness factor value (how strong the smoothing effect is)
- //values: 1-(infinite)
- var smoothness = 30;
-
- //Scroll sensitivity
- //values: anything? (default 1.00)
- var sensitivity = 1;
-
- //Acceleration sensitivity
- //values: anything? (default 1.50)
- var acceleration = 1;
-
- //Refreshrate setting
- //values: 30-144 (default = 60/72/120/144 = same as your monitor hz)
- var baserefreshrate = 60;
-
-
- //Alternative scrolling multiplier
- //values: true/false (try to set this to true if scrolling is too slow/doesn't work)
- var alternative_sensitivity_multiplier = false;
-
-
- //CODE STARTS HERE
-
- var minimal_jquery_version = 200;
-
- //max retries
- var jquery_retry_max = 5;
- var jquery_retry_count = 0;
-
-
- var DEBUG = false;
-
- var WEBKIT = false;
-
- //this.$ = this.jQuery = jQuery.noConflict(true);
-
- console.log("Loading smoothscroll...");
-
- if (smoothness>100)
- {
- smoothness = 100;
- }
-
- if (baserefreshrate <= 30 || baserefreshrate>144)
- {
- baserefreshrate = 144;
- }
- refreshrate = baserefreshrate;
-
- var animationduration = Math.round(1000/refreshrate);
- //var relativeratio = Math.round(51-smoothness/2)/100;
- var relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100;
- //var relativeratio = relativeratio;
-
-
-
- var lastLoop = new Date;
- //var lastrefreshrate = 0;
- function gameLoop() {
- var thisLoop = new Date;
- var refreshrate0 = 1000 / (thisLoop - lastLoop + 1);
- lastLoop = thisLoop;
-
- refreshrate = refreshrate + (refreshrate0-refreshrate)*0.1;
- refreshrate = Math.round(refreshrate);
-
- if (DEBUG)
- {
- console.log(refreshrate);
- }
- //console.log(refreshrate);
-
- animationduration = Math.round(1000/(refreshrate));
- //var relativeratio = Math.round(51-smoothness/2)/100;
- relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100;
- }
- gameLoop();
-
-
- function InitSmoothscroll()
- {
-
- LoadConfig();
-
- InitConfigmenu();
-
- var startposition = false;
- var targetposition = 0;
- var position = 0;
-
- var scrollfocus = ss$('body');
- var mousemoved = true;
-
- function hasScrollBarVisible(element)
- {
- //return (document.documentElement.scrollHeight !== document.documentElement.clientHeight);
-
- // Get the computed style of the body element
- var cStyle = element.currentStyle||window.getComputedStyle(element, "");
-
- // Check the overflow and overflowY properties for "auto" and "visible" values
- var scrollbar1 = cStyle.overflow == "scroll" || cStyle.overflowY == "scroll";
-
- var scrollbar2 = cStyle.overflow == "auto" || cStyle.overflowY == "auto";
-
- var scrollbar = scrollbar1 || scrollbar2;
-
- return scrollbar;
- }
-
-
- function hasscrollbars(scrollfocus)
- {
- var hasvisiblescrollbars = hasScrollBarVisible(scrollfocus);
- var parentelement = ss$(scrollfocus).parent();
- if ( ss$(parentelement))
- {
- if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea") || ss$(parentelement).is("article") || ss$(parentelement).is("article"))
- {
- return true;
- }
- else
- {
- if (ss$(parentelement).hasClass( "yt-scrollbar" ) || ss$(scrollfocus).hasClass( "yt-scrollbar" ))
- {
- return true;
- }
- return hasvisiblescrollbars;
- }
- }
- else
- {
- return hasvisiblescrollbars;
- }
- return false;
- }
-
- function UpdatePosition(element)
- {
- gameLoop();
-
- var positiondelta = scrollpositiondelta(element);
-
- var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio);
-
- if (positiondelta<0)
- {
- smoothdelta = smoothdelta*(-1);
- }
-
- if (Math.abs( (positiondelta-smoothdelta)) <= 1 )
- {
- ss$(element).stop();
- ss$(element).animate({
- scrollTop: '+=' + Math.round(positiondelta)
- }, animationduration, "linear", function() {
- scrollpositiondelta(element, 0);
- if (DEBUG)
- {
- ss$(element).css( "border", "1px solid red" );
- }
- });
- }
- else
- {
- ss$(element).stop();
- ss$(element).animate({
- scrollTop: '+=' + Math.round(smoothdelta)
- }, animationduration, "linear", function() {
- scrollpositiondelta(element, positiondelta-smoothdelta);
- UpdatePosition(element);
- if (DEBUG)
- {
- ss$(element).css( "border", "1px solid red" );
- }
- });
- }
- }
-
-
- function MouseScroll (e) {
- gameLoop();
-
- var mul = 1;
- if (!WEBKIT || alternative_sensitivity_multiplier)
- mul = 40;
- var x = e.deltaX*mul;
- var y = e.deltaY*mul;
-
- if (mousemoved)
- {
- scrollfocus = UpdateFocus(x,y);
- mousemoved = false;
- }
- //
-
- var positiondelta = 0;
- var lastscrolltop = 0;
-
- var parentelement = ss$(scrollfocus).parent();
-
- var rolled = y;
-
- var lastscrolltop = ss$(scrollfocus).scrollTop();
-
- if (!canscroll(scrollfocus, rolled))
- {
- if (!ss$(scrollfocus).is("html"))
- {
- scrollfocus = UpdateFocus(x,y);
- return false;
- }
- else
- {
-
- //console.log("true");
- return false;
- }
- }
- else
- {
- e.preventDefault();
- }
- positiondelta = scrollpositiondelta(scrollfocus);
-
- var direction = rolled/Math.abs(rolled);
-
- var positiondeltadelta = Math.round(rolled*sensitivity + Math.sqrt(Math.abs(positiondelta-rolled*sensitivity))*acceleration*rolled*0.09/sensitivity);
-
- positiondelta = positiondelta + positiondeltadelta;
-
- scrollpositiondelta(scrollfocus, positiondelta)
-
- UpdatePosition(ss$(scrollfocus));
-
- return true;
- }
-
- function canscroll(element, dir)
- {
- //console.log(dir);
- if (dir>0)
- {
- dir = 1;
- }
- if (dir<0)
- {
- dir = -1;
- }
- var checkradius = 3; //pixels to try scrolling
-
- var canscroll0 = false;
- var scrollable = ss$(element);
- var lastscrolltop = ss$(scrollable).scrollTop();
- ss$(scrollable).scrollTop(lastscrolltop+dir*checkradius);
- if (ss$(scrollable).scrollTop()!=lastscrolltop)
- {
- canscroll0 = true;
- }
- ss$(scrollable).scrollTop(lastscrolltop);
- //console.log("canscroll0: " + ss$(element).prev().prop('nodeName') + " : " + canscroll0);
- return canscroll0;
- }
-
-
- function scrollpositiondelta(element, newdelta)
- {
- var target = ss$(element);
- var delta = 0;
- if (newdelta!=undefined)
- {
- //console.log(dir);
- var dir = 0;
- if (newdelta>0)
- {
- dir = 1;
- }
- if (newdelta<0)
- {
- dir = -1;
- }
- //ss$(target)[0].setAttribute("positiondelta", newdelta );
- ss$( target ).data( "positiondelta", newdelta );
- delta = newdelta;
- }
- else
- {
- //var olddelta = ss$(target)[0].getAttribute("positiondelta");
- var olddelta = ss$( target ).data( "positiondelta" );
- if (olddelta!=undefined)
- {
- delta = olddelta;
- }
- }
- return delta;
- }
-
- function UpdateFocus(x,y) {
- if (scrollfocus)
- {
- //ss$(scrollfocus)[0].setAttribute( "positiondelta",0 );
- ss$(scrollfocus).stop();
- }
- var dir = y;
- var nodelist = document.querySelectorAll( ":hover" );
- //ss$(nodelist).stop();
- //console.log(nodelist);
- if (WEBKIT)
- {
- scrollfocus = ss$('body');
- }
- else
- {
- scrollfocus = ss$('html');
- }
-
- for (var i = nodelist.length-1; i >= 0 ; i--) {
- //var parent = nodelist[i-1];
- var newfocus = nodelist[i];
- if (DEBUG)
- {
- ss$(newfocus).css( "border", "1px solid blue" );
- //var debugtimer = setTimeout(function(){ ss$(newfocus).css( "border", "0px solid white" ); }, 1000);
- }
- //if (ss$(newfocus).hasScrollBar3() && hasScrollBarVisible(newfocus) && canscroll(newfocus, dir) && hasscrollbars(newfocus))
- if (canscroll(newfocus, dir) && hasscrollbars(newfocus))
- {
- scrollfocus = ss$(newfocus);
- return newfocus;
- }
- }
-
- return scrollfocus;
- }
-
- ss$('html').bind({
-
- mousemove: function(e) {
- mousemoved = true;
- },
-
- mousedown: function(e) {
- if (DEBUG)
- {
- console.log(scrollfocus);
- }
- if (scrollfocus)
- {
- scrollpositiondelta(scrollfocus, 0);
- //ss$(scrollfocus).stop();
- }
- scrollfocus = UpdateFocus(0,0);
- //console.log("click");
- }
- });
-
-
-
- document.documentElement.addEventListener("wheel", function(e){
- MouseScroll(e);
- //console.log("scrolling");
- });
-
-
- //WEBKIT = 'webkitRequestAnimationFrame' in window;
- WEBKIT = document.compatMode == 'CSS1Compat' || document.compatMode == "BackCompat";
-
- //console.log("window: " + window);
- console.log("Smoothscroll initiated! Webkit: " + WEBKIT);
- }
-
- var JQUERY = false;
- var OWNJQUERY = false;
- var OLDJQUERY = false;
-
- var old$;
- var oldjQuery;
-
- var ss$;
-
- function jQueryVersion(temp$)
- {
- if (typeof temp$ == 'undefined' || typeof temp$.fn == 'undefined' || typeof temp$.fn.jquery == 'undefined')
- {
- return 0;
- }
-
- var versiontable = temp$.fn.jquery.split('.');
- var version = 0;
- for (var i = versiontable.length-1; i >= 0; i--) {
- var power = versiontable.length-i;
- version += Math.pow(10,power-1)*versiontable[i];
- }
- return version;
- }
-
-
- function LoadConfig()
- {
- smoothness = GM_getValue( 'smoothness', smoothness );
- sensitivity = GM_getValue( 'sensitivity', sensitivity );
- acceleration = GM_getValue( 'acceleration', acceleration );
- baserefreshrate = GM_getValue( 'baserefreshrate', baserefreshrate );
- //alternative_sesitivity_multiplier = GM_getValue( 'alternative_sesitivity_multiplier', alternative_sesitivity_multiplier );
- console.log("Config for smoothscroll loaded!")
- }
-
- function SaveConfig()
- {
- GM_setValue( 'smoothness', document.getElementById('ss-smoothness').value)
- GM_setValue( 'sensitivity', document.getElementById('ss-sensitivity').value)
- GM_setValue( 'acceleration', document.getElementById('ss-acceleration').value)
- GM_setValue( 'baserefreshrate', document.getElementById('ss-baserefreshrate').value)
- //console.log(document.getElementById('ss-alternative_sesitivity_multiplier').checked)
- console.log("Config for smoothscroll saved!")
- }
-
- function InitConfigmenu()
- {
- console.log("Initiating smoothscroll config...");
- var configbar = document.createElement('div');
- configbar.setAttribute("id","ss-configbar");
-
- configbar.innerHTML = '<div style="display:block; width: 100%; height: auto; border: 0px solid #aaaaaa; background-color: grey;">Config page for smoothscroll (refresh page for changes to apply!) Made by: Creec Winceptor</div><div id="ss-config" style="margin:3px; display:block; width: auto; height: auto; border: 0px solid #554433;"><table style="width:auto;"><tr><td>Smoothness</td><td><input type="number" id="ss-smoothness" min="0" max="100" value="' + smoothness + '"></td><td> Smoothness factor value (how strong the smoothing effect is)</td></tr><tr><td>Sensitivity</td><td><input type="number" id="ss-sensitivity" min="0" max="100" value="' + sensitivity + '"></td><td> Scroll sensitivity (duh)</td></tr><tr><td>Acceleration</td><td><input type="number" id="ss-acceleration" min="0" max="100" value="' + acceleration + '"></td><td> Acceleration of continuous scroll action (saves your finger)</td></tr><tr><td>Refreshrate</td><td><input type="number" id="ss-baserefreshrate" min="1" max="100" value="' + baserefreshrate + '"></td><td>Refreshrate of scrollanimation (60Hz default)</td></tr></table></div><div style="width: 100%; height: auto; text-align: center; background-color: grey;"><input id="ss-save" type="button" value="Save config" style="width: 44%; height: auto; border: 0px solid #aaaaaa; margin: 3px"/><input id="ss-close" type="button" value="Close config" style="width: 44%; height: auto; border: 0px solid #aaaaaa; margin: 3px"/><div>';
-
-
- var configparent = document.getElementsByTagName("body")[0];
- configbar.style.width = '100%';
- configbar.style.display = 'none';
- configbar.style.position = 'absolute';
- configbar.style.zIndex = '9999';
- configbar.style.backgroundColor = 'white';
-
- configparent.insertBefore(configbar, configparent.childNodes[0]);
-
- ss$("#ss-close").click(function() {
- //ss$("#ss-config").animate({
- // height: '0'
- //}, 100);
- ss$("#ss-configbar").hide("slow");
- });
- ss$("#ss-save").click(function() {
- SaveConfig();
- });
-
- //ss$("#ss-configbar").hide();
- }
-
- function ConfigSmoothscroll()
- {
- if (typeof ss$ == 'undefined'){
- alert("Smoothscroll is not running properly on this page!");
- return;
- }
- //ss$("#ss-config").animate({
- //height: '100px'
- //}, 100);
- ss$("#ss-configbar").show("slow");
- ss$("html, body").animate({ scrollTop: 0 }, "slow");
- console.log("opening config...");
- }
-
- function LoadjQuery(loading)
- {
- if (loading)
- {
- console.log("Waiting for jQuery...");
- if (typeof $ == 'undefined' || typeof jQuery == 'undefined' || jQueryVersion($)<minimal_jquery_version)
- {
- if (jquery_retry_count<jquery_retry_max)
- {
- jquery_retry_count++;
- setTimeout(function() {
- LoadjQuery(true);
- }, 100);
- }
- else
- {
- console.log("Failed to load smoothscroll!");
- if (typeof old$ != 'undefined') {
- $ = old$;
- }
- if (typeof oldjQuery != 'undefined') {
- jQuery = oldjQuery;
- }
- }
- }
- else
- {
- ss$ = $;
- ssjQuery = jQuery;
- console.log("jQuery loaded!");
-
- if (typeof old$ != 'undefined') {
- $ = old$;
- }
- if (typeof oldjQuery != 'undefined') {
- jQuery = oldjQuery;
- }
- console.log("Page jQuery version: " + jQueryVersion(old$));
- console.log("Script jQuery version: " + jQueryVersion(ss$));
-
- InitSmoothscroll();
- }
- }
- else
- {
- console.log("Loading own jQuery...");
- jquery_retry_count = 0;
-
- var filename = "https://code.jquery.com/jquery-2.2.3.js";
- var fileref = document.createElement('script');
- fileref.setAttribute("type","text/javascript");
- fileref.setAttribute("src", filename);
-
- if (typeof fileref!="undefined")
- {
- var scriptparent = document.getElementsByTagName("head")[0];
-
- if (typeof scriptparent=="undefined")
- {
- var scriptparent = document.createElement('head');
- document.getElementsByTagName("html")[0].appendChild(scriptparent);
- }
- scriptparent.appendChild(fileref);
- }
-
- LoadjQuery(true);
- }
- }
-
-
- function Init()
- {
-
- if (typeof ss$ == 'undefined' )
- {
- var sitejquery = !(typeof $ == 'undefined' || typeof jQuery == 'undefined');
- if (sitejquery && jQueryVersion($)>=minimal_jquery_version)
- {
- ss$ = $;
- ssjQuery = jQuery;
- console.log("Reusing page jQuery...");
- console.log("Page jQuery version: " + jQueryVersion($));
- InitSmoothscroll();
- }
- else
- {
- if (typeof $ != 'undefined' && typeof old$ == 'undefined')
- {
- old$ = $;
- }
- if (typeof jQuery != 'undefined' && typeof oldjQuery == 'undefined')
- {
- oldjQuery = jQuery;
- }
-
- LoadjQuery(false);
- }
- }
- }
-
- if (typeof ss$ == 'undefined'){
- console.log("Initiating smoothscroll...");
- Init();
- //InitSmoothscroll();
- GM_registerMenuCommand("Configurate smoothscroll", ConfigSmoothscroll);
- }
- else
- {
- console.log("Smoothscroll already loaded!");
- }