Skip to content

Instantly share code, notes, and snippets.

@igorbrigadir
Last active January 3, 2025 18:48
Show Gist options
  • Save igorbrigadir/a4b35983d659a68439cd7920868de57f to your computer and use it in GitHub Desktop.
Save igorbrigadir/a4b35983d659a68439cd7920868de57f to your computer and use it in GitHub Desktop.
Progressive Story Demo
::StoryTitle Progressive Story Demo
::StoryData
{
"ifid": "F6BE4A85-73E2-4126-8B5A-C1F1F81A434F",
"format": "SugarCube",
"format-version": "2.36.1",
"start": "Start"
}
::UserStylesheet[stylesheet]
#ui-bar {
display: none;
}
#story {
margin: 0;
padding: 0;
max-width: 100%;
}
#passages {
max-width: 100%;
margin: 0;
padding: 0;
}
.passage {
margin: 0;
padding: 0;
}
#progress-bar {
position: fixed;
top: 0;
left: 0;
width: 0%;
height: 3px;
background-color: #808080;
transition: width 0.1s ease;
z-index: 1000;
}
#story-container {
margin: 0;
padding: 0;
width: 100%;
}
.sentence-space {
height: 500px;
width: 100%;
}
.sentence-display {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.2em;
line-height: 1.5;
opacity: 0;
transition: opacity 0.5s ease;
text-align: center;
width: 80%;
max-width: 800px;
pointer-events: none;
}
::Start
<div id="progress-bar"></div>
<div id="story-container"></div>
<<script>>
$(document).ready(function() {
const storyText = `Scroll Down...
Hello.
This is a progressive story.
One Sentence at a time.
Some are slightly further than others.
This is made for Twine, a non linear story making app, using SugarCube
but this is a very linear story.
To make one like this,
Grab the source code:
https://bit.ly/progressive-story-demo
In Twinery twinery.org go to Library -> Import
and then Build -> Publish To File.
This will generate a single html page you can host.
The quickest way is on neocities.org
Replace index.html with the one generated by twinery.
That's it!`;
const sentences = storyText.split('\n');
const container = $('#story-container');
// Create display and space elements
const displayContainer = $('<div id="display-container"></div>');
sentences.forEach(sentence => {
displayContainer.append($('<div class="sentence-display"></div>').text(sentence));
container.append($('<div class="sentence-space"></div>'));
});
container.prepend(displayContainer);
const displaySentences = $('.sentence-display');
const spacerSentences = $('.sentence-space');
const totalSentences = spacerSentences.length;
const pixelsPerSentence = 500;
const transitionPixels = 100;
// Add extra scroll space to ensure last sentences are visible
container.append($('<div></div>').css('height', $(window).height()));
$(window).on('scroll', function() {
const scrollPixels = window.scrollY;
const maxScroll = $(document).height() - $(window).height();
const scrollPercentage = Math.min((scrollPixels / maxScroll) * 100, 100);
// Update progress bar
$('#progress-bar').css('width', scrollPercentage + '%');
displaySentences.each(function(index) {
const sentenceStart = index * pixelsPerSentence;
const sentenceEnd = sentenceStart + pixelsPerSentence;
const fadeOutStart = sentenceEnd - transitionPixels;
const fadeInEnd = sentenceStart + transitionPixels;
if (scrollPixels >= sentenceStart && scrollPixels <= sentenceEnd) {
let opacity = 1;
if (scrollPixels < fadeInEnd) {
opacity = (scrollPixels - sentenceStart) / transitionPixels;
}
else if (scrollPixels > fadeOutStart) {
opacity = 1 - ((scrollPixels - fadeOutStart) / transitionPixels);
}
$(this).css('opacity', Math.max(0, Math.min(1, opacity)));
} else {
$(this).css('opacity', 0);
}
});
});
$(window).trigger('scroll');
});
<</script>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment