-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAuto Scroll Mouse [fork].user.js
216 lines (190 loc) · 6.36 KB
/
Auto Scroll Mouse [fork].user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// ==UserScript==
// @name Auto Scroll Mouse [fork]
// @namespace http://www.marcbelmont.com
// @description No mousewheel? No problem! This script will scroll the page if you place your mouse near the top or bottom of the window and wiggle it.
// @version 2.1.10
// @license ISC
// @include http://*/*
// @include https://*/*
// @grant GM_addStyle
// @run-at document-start
// ==/UserScript==
// Originally "Auto Scroll!" by Marc Belmont on userscripts.org
// Tweaked by joeytwiddle
// TODO: Do not scroll after/during a mousedown (so it won't interfere when dragging/selecting)
// BUG: Does not trigger when mouse is over an iframe (window does not receive the mousemove event)
// We could solve this by listening for mousemove events on the region divs instead of on the document.
// But that could be more disruptive, as it prevents events from reaching the window like they normally would.
//////////////////////
// Constants //
//////////////////////
// Which key should be held to enable scrolling. Possible values are 0 | 1
// Enable more than one to require a combination be held.
var ONLY_WHEN_HOLDING_SHIFT = 0;
var ONLY_WHEN_HOLDING_CTRL = 0;
var ONLY_WHEN_HOLDING_ALT = 0;
var NOSCROLL_PERCENT = 80; // Area in the middle of the page where there won't be scrolling
var SCROLLSTEP = 5; // Scrolling speed
var ONLYLEFTRIGHT = 1; // Scrolling will happen only when you move left or right in the top or bottom areas. Possible values are 0 | 1
var ONLYLEFTRIGHT_MOUSESPEED = 1.5; // Acceleration
var ONLYLEFTRIGHT_DONTSCROLL = 100; // if no event for too long, no scrolling
var DELAY_TIME = 5; // This tries to reduce the number of scroll operations, to reduce load on the browser
var SHOW_ACTIVE_REGION = 1;
//////////////////////
// Some Code //
//////////////////////
var _mX = 0;
var _mXOld = 0;
var _mYOld = 0;
var _mY = 0;
var _go = 0;
var _mNow = new Date();
var _mThen = new Date();
// 2. scroll the window
function ScrollWindow() {
// don't scroll if we're in the middle of the page
var end = ((_mY - window.pageYOffset) - window.innerHeight/2);
if (Math.abs(end) < window.innerHeight*NOSCROLL_PERCENT/200) {
regionUI.hideRegions();
return;
}
/* var down = (_mY - window.pageYOffset) / window.innerHeight;
if (Math.abs(down - 0.5)*2 < NOSCROLL_PERCENT/100) {
return;
} */
// if ONLYLEFTRIGHT is on, scroll only when you move left or right,
//if (ONLYLEFTRIGHT && (Math.abs(_mY - _mYOld) > 2)) {
// return;
//}
// if you want scrolling, mouse have to go start moving slowly
if (Math.abs(_mY - _mYOld) < 7 && Math.abs(_mX - _mXOld) < 7)
_go = 1;
// scroll the page
var way = end > 0 ? 1 : -1;
var val = SCROLLSTEP;
if (ONLYLEFTRIGHT) {
if (_go) {
val = Math.pow(Math.abs(_mX - _mXOld), ONLYLEFTRIGHT_MOUSESPEED);
} else {
val = 0;
}
}
if (val != 0) {
window.scrollTo(window.pageXOffset, window.pageYOffset + val*way);
}
if (ONLYLEFTRIGHT && SHOW_ACTIVE_REGION /*&& val != 0*/) {
if (end > 0) {
regionUI.showBottomRegion();
} else {
regionUI.showTopRegion();
}
}
}
function maybe(scrollWindow) {
var timer;
return function(){
if (!timer) {
timer = setTimeout(function(){
timer = null;
scrollWindow();
_mXOld = _mX;
_mYOld = _mY;
_mThen = _mNow;
}, DELAY_TIME);
}
};
}
var maybeScrollWindow = maybe(ScrollWindow);
// 1. Catch mouse movement
document.addEventListener('mousemove', mousemove, true);
function mousemove(e)
{
// get mouse pos and the date
if (!e)
e = window.event || window.Event;
if('undefined'!=typeof e.pageX) {
_mX = e.pageX;
_mY = e.pageY;
} else {
_mX = e.clientX + document.body.scrollLeft;
_mY = e.clientY + document.body.scrollTop;
}
_mNow = Date.now();
// Hack to avoid unwanted scrolling when the mouse enters a window
// if no event for too long, no scrolling
if (_mNow - _mThen > ONLYLEFTRIGHT_DONTSCROLL)
_go = 0;
if (ONLY_WHEN_HOLDING_SHIFT && !e.shiftKey) return;
if (ONLY_WHEN_HOLDING_CTRL && !e.ctrlKey) return;
if (ONLY_WHEN_HOLDING_ALT && !e.altKey) return;
// Scroll the window
maybeScrollWindow();
}
var regionUI = (function() {
var FADE_IN_DURATION = 300;
var topRegion = null;
var bottomRegion = null;
function ensureRegionsExist() {
if (!bottomRegion) {
topRegion = document.createElement('div');
topRegion.className = 'ASM_region';
topRegion.style.top = 0;
topRegion.style.width = '100%';
topRegion.style.height = (100 - NOSCROLL_PERCENT) / 2 + '%';
document.body.appendChild(topRegion);
bottomRegion = document.createElement('div');
bottomRegion.className = 'ASM_region';
bottomRegion.style.bottom = 0;
bottomRegion.style.width = '100%';
bottomRegion.style.height = (100 - NOSCROLL_PERCENT) / 2 + '%';
document.body.appendChild(bottomRegion);
GM_addStyle(`
.ASM_region {
position: fixed;
z-index: 99999999;
background: #09c4;
pointer-events: none;
transition: opacity 0.3s 0s;
opacity: 0;
}
.ASM_region.ASM_show {
display: block;
transition: opacity ${FADE_IN_DURATION}ms;
opacity: 1;
}
`);
}
}
function showRegion(regionElement) {
regionElement.classList.add('ASM_show');
//regionElement.offsetWidth;
// We need to wait long enough for the new state to fade in before we remove the class.
//setTimeout(() => {
// regionElement.classList.remove('ASM_show');
//}, FADE_IN_DURATION);
}
function showTopRegion() {
ensureRegionsExist();
showRegion(topRegion);
}
function showBottomRegion() {
ensureRegionsExist();
showRegion(bottomRegion);
}
function hideRegions() {
topRegion.classList.remove('ASM_show');
bottomRegion.classList.remove('ASM_show');
}
return {
ensureRegionsExist: ensureRegionsExist,
showTopRegion: showTopRegion,
showBottomRegion: showBottomRegion,
hideRegions: hideRegions,
};
}());
if (SHOW_ACTIVE_REGION) {
// It's good to create them at the start, otherwise the first animation won't fade in (because the region will be given the 'ASM_show' class on the same tick that it was created).
document.addEventListener('DOMContentLoaded', function() {
regionUI.ensureRegionsExist();
});
}