Skip to content

Commit cb0b7df

Browse files
feat: added smooth scrolling using arrow keys in PDF mode
Now when you press the down/up arrow in PDF mode you'll go to the next/previous slide respectively.
1 parent 0126b61 commit cb0b7df

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

lib/core/browser/page-logic.browser.ts

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable max-lines */
2+
13
import type { DeepReadonly } from '#lib/types';
24
import { Logger } from '#lib/logger';
35

@@ -156,28 +158,67 @@ export const toggleFullScreen = function toggleFullScreen(): void {
156158
}
157159
};
158160

161+
/** Gets the size of one `--unit` in pixels. */
162+
export const getOneUnitSizeInPixels = function getOneUnitSizeInPixels(): number {
163+
const element = document.createElement('div');
164+
element.style.position = 'absolute';
165+
element.style.visibility = 'hidden';
166+
element.style.height = 'var(--unit)';
167+
document.body.appendChild(element);
168+
const pixels = element.getBoundingClientRect().height;
169+
document.body.removeChild(element);
170+
return pixels;
171+
};
172+
173+
interface scrollUsingUnitArgs {
174+
readonly amount: number;
175+
/** Wether to move down that many slides instead of units. */
176+
readonly slides?: boolean;
177+
}
178+
179+
/** Scrolls the window down by `amount * --unit` in pixels. */
180+
export const scrollUsingUnit = function scrollUsingUnit({
181+
amount,
182+
slides = false,
183+
}: scrollUsingUnitArgs): void {
184+
let modifier = 1;
185+
if (slides) {
186+
const marginBetweenSlides = 1;
187+
const value = getComputedStyle(document.body).getPropertyValue('--height').trim();
188+
modifier = Number.parseFloat(value) + marginBetweenSlides;
189+
}
190+
191+
const pixels = getOneUnitSizeInPixels() * amount * modifier;
192+
Logger.debug(`Scrolling by ${pixels} pixels`);
193+
if (!Number.isNaN(pixels)) document.body.scrollBy({ behavior: 'smooth', left: 0, top: pixels });
194+
};
195+
159196
/** Handles key presses on the document, and moves slides accordingly. */
160197
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
161198
export const handleKeyPresses = function handleKeyPresses(event: KeyboardEvent): void {
162-
if (isPDF()) return;
163-
164199
switch (event.key) {
165200
case 'Enter':
166201
case ' ':
167202
case 'd':
168203
case 'l':
169204
case 'ArrowRight':
170-
goToNextSlide();
205+
if (!isPDF()) goToNextSlide();
171206
break;
172207
case 'a':
173208
case 'h':
174209
case 'ArrowLeft':
175-
goToPreviousSlide();
210+
if (!isPDF()) goToPreviousSlide();
176211
break;
177212
case 'f':
178213
case 'F11':
179214
toggleFullScreen();
180215
break;
216+
case 'ArrowDown':
217+
if (isPDF()) scrollUsingUnit({ amount: 1, slides: true });
218+
break;
219+
case 'ArrowUp':
220+
if (isPDF()) scrollUsingUnit({ amount: -1, slides: true });
221+
break;
181222
default:
182223
}
183224
};
@@ -268,6 +309,8 @@ export const setupScriptCode = /*JavaScript*/ `
268309
${handleUrlHashChange.toString()}
269310
${handleMousePresses.toString()}
270311
${toggleFullScreen.toString()}
312+
${getOneUnitSizeInPixels.toString()}
313+
${scrollUsingUnit.toString()}
271314
${handleKeyPresses.toString()}
272315
${handleScrollEvents.toString()}
273316
${handleTouchEvents.toString()}

0 commit comments

Comments
 (0)