Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Scrollama problems on browser resize/zoom #107

Merged
merged 7 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions _extensions/closeread/closeread.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion _extensions/closeread/closeread.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

175 changes: 92 additions & 83 deletions _extensions/closeread/closeread.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// closeread.js //
//==============//

// import throttleDebounce from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"

Copy link
Collaborator Author

@jimjam-slam jimjam-slam Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd originally intended to use this package, but I didn't really want t bite off a bundling toolchain (although we could probably load it via a script tag in the HTML, as we do our existing dependencies). I ended up using the native browser setTimeout() instead, so this can go (although I could try loading it via script and using debounce, which would prevent .resize() being called multiple times). Not sure there's any noticeable performance impact currently, though. I'll remove this commented out code for now.

// set params
const triggerSelector = '.new-trigger'
const progressBlockSelector = '.progress-block'
Expand Down Expand Up @@ -58,101 +60,109 @@ document.addEventListener("DOMContentLoaded", () => {
// collect all sticky elements
const allStickies = Array.from(document.querySelectorAll(".sticky"));


// === Set up scrolling event listeners === //
// scrollama() is accessible because scrollama.min.js is attached via closeread.lua
// scrollama() is accessible because scrollama.min.js is attached
// via closeread.lua
const triggerScrollerConfig = {
jimjam-slam marked this conversation as resolved.
Show resolved Hide resolved
step: triggerSelector,
offset: 0.5,
progress: true,
debug: debugMode
}
const progressScrollerConfig = {
step: progressBlockSelector,
offset: 0.5,
progress: true,
debug: debugMode
}

function crTriggerStepEnter(trigger) {
focusedStickyName = trigger.element.getAttribute("data-focus-on")

// update ojs variables
ojsTriggerIndex?.define("crTriggerIndex", trigger.index)
ojsStickyName?.define("crActiveSticky", focusedStickyName)

updateStickies(allStickies, focusedStickyName, trigger)
}

function crTriggerStepProgress(trigger) {
ojsTriggerProgress?.define("crTriggerProgress", trigger.progress)
ojsDirection?.define("crDirection", trigger.direction)
}

function crProgressStepEnter(progressBlock) {
ojsProgressBlock?.define("crProgressBlock", progressBlock.progress)
}

// set up scrollers on document load, and reset them when window zoom changes
// (they seem to misbehave on zoom change: see issue #101)

// primary scroller
const triggerScroller = scrollama();
const triggerScroller = scrollama()
triggerScroller
.setup({
step: triggerSelector,
offset: 0.5,
progress: true,
debug: debugMode
})
.onStepEnter((trigger) => {

focusedStickyName = trigger.element.getAttribute("data-focus-on");

// update ojs variables
ojsTriggerIndex?.define("crTriggerIndex", trigger.index);
ojsStickyName?.define("crActiveSticky", focusedStickyName);

updateStickies(allStickies, focusedStickyName, trigger);

})
.onStepProgress((trigger) => {

// update ojs variables
ojsTriggerProgress?.define("crTriggerProgress", trigger.progress);
ojsDirection?.define("crDirection", trigger.direction);

});
.setup(triggerScrollerConfig)
.onStepEnter(crTriggerStepEnter)
.onStepProgress(crTriggerStepProgress)

// secondary scroller used for making progress blocks
const progressBlockScroller = scrollama();
progressBlockScroller
.setup({
step: progressBlockSelector,
offset: 0.5,
progress: true,
debug: debugMode
})
.onStepProgress((progressBlock) => {
// update ojs variable
ojsProgressBlock?.define("crProgressBlock", progressBlock.progress);
});
// secondary scroller used for making progress blocks
const progressBlockScroller = scrollama()
progressBlockScroller
.setup(progressScrollerConfig)
.onStepProgress(crProgressStepEnter)

window.addEventListener("resize", (event) => {
setTimeout(() => triggerScroller.resize(), 1000)
setTimeout(() => progressBlockScroller.resize(), 1000)
})

// === Hotkey Listeners === //
// Add a listener for scrolling between new triggers
let currentIndex = -1; // Start before the first element

function scrollToNewTrigger(direction) {
const triggers = document.querySelectorAll('.new-trigger');

// Add a listener for scrolling between new triggers
let currentIndex = -1; // Start before the first element
if (triggers.length === 0) return; // do nothing if there's no triggers

function scrollToNewTrigger(direction) {
const triggers = document.querySelectorAll('.new-trigger');

if (triggers.length === 0) return; // do nothing if there's no triggers

if (direction === "next") {
if (currentIndex >= triggers.length - 1) return; // exit if at end
currentIndex += 1;
}

if (direction === "previous") {
if (currentIndex === 0) return; // exit if at start
currentIndex -= 1;
}

const nextTrigger = triggers[currentIndex];
nextTrigger.scrollIntoView({ behavior: 'smooth', block: 'center' });
if (direction === "next") {
if (currentIndex >= triggers.length - 1) return; // exit if at end
currentIndex += 1;
}

document.addEventListener('keydown', (event) => {
if (event.key === 'ArrowRight') {
scrollToNewTrigger("next");
}
if (event.key === 'ArrowLeft') {
scrollToNewTrigger("previous");
}
});
if (direction === "previous") {
if (currentIndex === 0) return; // exit if at start
currentIndex -= 1;
}

const nextTrigger = triggers[currentIndex];
nextTrigger.scrollIntoView({ behavior: 'smooth', block: 'center' });
}

document.addEventListener('keydown', (event) => {
if (event.key === 'ArrowRight') {
scrollToNewTrigger("next");
}
if (event.key === 'ArrowLeft') {
scrollToNewTrigger("previous");
}
});

});

// === Other Hotkey Listeners === //

// toggle presentation mode
document.addEventListener('keydown', (event) => {
const crSections = document.querySelectorAll('.cr-section');
crSections.forEach((el) => {
if (event.key === "p") {
if (el.classList.contains("presentation-mode")) {
el.classList.remove("presentation-mode");
} else {
el.classList.add("presentation-mode");
// toggle presentation mode
document.addEventListener('keydown', (event) => {
const crSections = document.querySelectorAll('.cr-section');
crSections.forEach((el) => {
if (event.key === "p") {
if (el.classList.contains("presentation-mode")) {
el.classList.remove("presentation-mode");
} else {
el.classList.add("presentation-mode");
}
}
}
});
});
});

});


//===============//
Expand Down Expand Up @@ -393,4 +403,3 @@ function getBooleanConfig(metaFlag) {
.querySelector("meta[" + metaFlag + "]")?.getAttribute(metaFlag)
return option === "true"
}

12 changes: 5 additions & 7 deletions _extensions/closeread/closeread.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

.trigger {
padding-block: 45svh;
padding-inline: 1em;
padding-inline: 24px;

p {
margin-bottom: 0; // override bootstrap rule
Expand Down Expand Up @@ -115,7 +115,6 @@


/* mobile sizing (bootstrap: xs) is always overlay-center */
//@media (max-width: 575.98px) {
@media (max-width: 575.98px) {
.cr-section.sidebar-left,
.cr-section.sidebar-right,
Expand Down Expand Up @@ -155,6 +154,7 @@
grid-column: 1;
z-index: 1;
transition: opacity 0.5s ease-in-out;
max-width: 527.98px;

.narrative {
background-color: rgba(17, 17, 17, .85);
Expand All @@ -172,19 +172,17 @@
// ... with inline margins set for narrative content depending on side
.overlay-left {
.narrative-col {
margin-inline-start: 5%;
margin-inline-end: 65%;
justify-self: start;
}
}
.overlay-center {
.narrative-col {
margin-inline: 30%;
justify-self: center;
}
}
.overlay-right {
.narrative-col {
margin-inline-start: 65%;
margin-inline-end: 5%;
justify-self: end;
}
}

Expand Down
11 changes: 9 additions & 2 deletions docs/index-styles.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
.cr-section {
font-size: 1.4em;
background-color: rgba(39, 128, 227, 1);
}
}

.cr-section .narrative-col {
jimjam-slam marked this conversation as resolved.
Show resolved Hide resolved
font-size: 1.4em;
}

.cr-section .sticky-col {
font-size: 0.6em;
}
2 changes: 1 addition & 1 deletion docs/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Step three: flag an element to become a sticky. [@cr-doc]{highlight="14-18"}
Step four: create a trigger to make the sticky appear. [@cr-doc]{highlight="12"}
:::

:::{#cr-doc filename="myfirstcr.qmd"}
:::{#cr-doc filename="myfirstcr.qmd" .scale-to-fill}
jimjam-slam marked this conversation as resolved.
Show resolved Hide resolved
````markdown
---
title: My First Closeread
Expand Down
Loading