Greasy Fork is available in English.

Smooth Scrolling

Smoothly scrolls the page when a button is held

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

  1. // ==UserScript==
  2. // @name Smooth Scrolling
  3. // @description Smoothly scrolls the page when a button is held
  4. // @version 1.1.2
  5. // @author sllypper
  6. // @homepage https://greatest.deepsurf.us/en/users/55535-sllypper
  7. // @namespace https://greatest.deepsurf.us/en/users/55535-sllypper
  8. // @match *://forums.spacebattles.com/*
  9. // @match *://forums.sufficientvelocity.com/*
  10. // @match *://forum.questionablequesting.com/*
  11. // @match *://fanfiction.net/*
  12. // @match *://archiveofourown.org/*
  13. // @match *://turb0translation.blogspot.com/*
  14. // @match *://fiction.live/*
  15. // @grant none
  16. // @todo make keybinds easily configurable
  17. // ==/UserScript==
  18.  
  19. (function() {
  20. 'use strict';
  21.  
  22. // Smooth Scrolling Settings
  23.  
  24. // how much it scrolls every time (in pixels)
  25. let scrollAmount = 16;
  26.  
  27. // how long between ticks (in ms)
  28. // 16.66667 = 60 frames per second
  29. // not used if experimental is true
  30. let scrollPeriod = 16.66667;
  31.  
  32. // how much holding Shift will multiply the scrollAmount
  33. let shiftSpeedMod = 2.0;
  34.  
  35. //
  36.  
  37. // Experimental settings
  38.  
  39. // Use the alternative experimental Scroller
  40. // it's bound to your screen framerate
  41. // is supposed to be smoother
  42. let experimental = true;
  43.  
  44. // Scroll Speed in times per second
  45. // set to 0 to match your refresh rate (smooth perfection)
  46. // values above your framerate scrolls every frame
  47. let fps = 0
  48.  
  49. // programming magic stuff
  50.  
  51. const states = {
  52. NONE: 0,
  53. UP: 1,
  54. SHIFTUP: 2,
  55. DOWN: 3,
  56. SHIFTDOWN: 4
  57. }
  58. let scrollState = states.NONE;
  59. let currScrollAction = null;
  60. let isTyping = false;
  61.  
  62. document.addEventListener('focus', function(evt) {
  63. var target = evt.target;
  64. if((target.nodeName === 'INPUT' && target.type === 'text') || target.nodeName === 'TEXTAREA') isTyping = true;
  65. // else isTyping = false;
  66. }, true);
  67.  
  68. document.addEventListener('blur', function(evt) {
  69. var target = evt.target;
  70. if((target.nodeName === 'INPUT' && target.type === 'text') || target.nodeName === 'TEXTAREA') isTyping = false;
  71. }, true);
  72.  
  73. document.addEventListener("keydown", event => {
  74. // ignore keybindings when text input is focused
  75. if (isTyping || event.isComposing || event.target.getAttribute('medium-editor') != null || event.target.getAttribute('contenteditable') != null) {
  76. //console.log('entered first if')
  77. event.stopPropagation();
  78. return;
  79. }
  80. switch (event.code) {
  81. case "KeyW":
  82. case "KeyK":
  83. case "ArrowUp": {
  84. event.preventDefault();
  85. if (scrollState !== states.UP && !event.shiftKey) {
  86. //event.preventDefault();
  87. clearScrollAction();
  88. scrollState = states.UP;
  89. scrollAction(-scrollAmount);
  90. } else if (scrollState !== states.SHIFTUP && event.shiftKey) {
  91. //event.preventDefault();
  92. clearScrollAction();
  93. scrollState = states.SHIFTUP;
  94. scrollAction(-scrollAmount*shiftSpeedMod);
  95. }
  96. break;
  97. }
  98. case "KeyS":
  99. case "KeyJ":
  100. case "ArrowDown": {
  101. event.preventDefault();
  102. if (scrollState !== states.DOWN && !event.shiftKey) {
  103. // event.preventDefault();
  104. clearScrollAction();
  105. scrollState = states.DOWN;
  106. scrollAction(scrollAmount);
  107. } else if (scrollState !== states.SHIFTDOWN && event.shiftKey) {
  108. // event.preventDefault();
  109. clearScrollAction();
  110. scrollState = states.SHIFTDOWN;
  111. scrollAction(scrollAmount*shiftSpeedMod);
  112. }
  113. break;
  114. }
  115. }
  116. });
  117.  
  118. document.addEventListener("keyup", event => {
  119. switch(event.code) {
  120. case 'KeyW':
  121. case 'KeyK':
  122. case 'KeyJ':
  123. case 'KeyS':
  124. case 'ArrowDown':
  125. case 'ArrowUp':
  126. clearScrollAction();
  127. break
  128. default:
  129. // using even.key for any Shift Key
  130. if (event.key === "Shift") {
  131. clearScrollAction();
  132. }
  133. break;
  134. }
  135. });
  136.  
  137. function scrollAction(amount) {
  138. if (experimental) {
  139. scroller.move(amount)
  140. return;
  141. }
  142.  
  143. currScrollAction = setInterval(() => {
  144. window.scrollBy(0, amount);
  145. }, scrollPeriod)
  146. }
  147.  
  148. function clearScrollAction() {
  149. clearInterval(currScrollAction);
  150. currScrollAction = null;
  151. scrollState = states.NONE;
  152. scroller.stop();
  153. }
  154.  
  155. // experimental bit
  156.  
  157. let scroller = new Scroller(fps)
  158.  
  159. function Scroller(fps) {
  160.  
  161. var delay,
  162. time,
  163. frame,
  164. tref,
  165. amount;
  166.  
  167. function loop(timestamp) {
  168. if (fps !== 0) {
  169. // Scroll with fps behavior
  170. if (time === null) {time = timestamp; timestamp = 0}
  171. var seg = Math.floor((timestamp - time) / delay);
  172. if (seg > frame) {
  173. frame = seg;
  174. window.scrollBy(0, amount);
  175. }
  176. } else {
  177. // Scroll every frame behavior
  178. window.scrollBy(0, amount);
  179. }
  180. tref = requestAnimationFrame(loop)
  181. }
  182.  
  183. this.move = function(pixels) {
  184. amount = pixels;
  185. delay = 1000 / fps;
  186. frame = -1;
  187. time = null;
  188. tref = requestAnimationFrame(loop);
  189. }
  190.  
  191. this.stop = function() {
  192. cancelAnimationFrame(tref);
  193. };
  194. }
  195.  
  196. })();