+1 vote
by (490 points)
Hi everybody! Sorry (once again) if this is a very basic/simple question - or alternately, just too weird/hard to even consider - but I'm trying to implement this (https://www.jqueryscript.net/animation/Create-Scrolling-Movie-End-Credits-For-Webpage-Using-jQuery.html) Jquery script for a final passage/set of passages in my game - to create a kind of end credits type of situation. How would I go about converting this HTML-based script for Sugarcube 2.21?

2 Answers

+1 vote
by (44.7k points)
selected by
Best answer

SugarCube has jQuery built-in.  That said, you can use the code I wrote for my credits.  It doesn't have the problems that one did of varying speeds, especially at the beginning and end.

First, add this to your JavaScript section (preferably near the top):

if (window.hasOwnProperty("storyFormat")) {
	// Change this to the path where your HTML file is located
	// if you want to run this from inside Twine.
	setup.Path = "C:/Games/YourGame/";  // Running inside Twine application
} else { 
	setup.Path = "";  // Running in a browser
setup.ImagePath = setup.Path + "images/";

$(document).on(':passagestart', function (ev) {
	if (passage() == "Credits") {
		$.wiki('<<addclass "#passages" "credits-style">><<addclass "body" "body-credits">>');
	} else {
		$.wiki('<<removeclass "#passages" "credits-style">><<removeclass "body" "body-credits">>');

$(document).on(':passagedisplay', function (ev) {
	if (passage() == "Credits") {
		var keyframes = findKeyframesRule("credits");
		keyframes.appendRule("100% { top: " + ( ( $( ".wrapper" ).height() + 100 ) * -1 ) + "px; }");

window.findKeyframesRule = function (rule) {
	// gather all stylesheets into an array
	var i, j, ss = document.styleSheets;
	// loop through the stylesheets
	for (i = 0; i < ss.length; ++i) {
	// loop through all the rules
		for (j = 0; j < ss[i].cssRules.length; ++j) {
			// find the keyframes rule whose name matches our passed over parameter and return that rule
			if (ss[i].cssRules[j].type == window.CSSRule.KEYFRAMES_RULE && ss[i].cssRules[j].name == rule) {
				return ss[i].cssRules[j];
	// rule not found
	return null;

Change "C:/Games/YourGame/" to the path where your development version of the HTML is, and rename the image path if necessary.  That will make sure it works for you within Twine.

Then add this to your Stylesheet section (the first line should be at the top, the rest can be elsewhere):

@import url(https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300);

/*  Movie Credits style  */
.googleFont {
	font-family: 'Open Sans Condensed', sans-serif; 

.credits-style {
	padding: 0;
	box-sizing: border-box;
	max-width: 100% !important;

.body-credits {
	height: 100vh;
	background: radial-gradient(circle at top center, #333 0%, #000 100%);
	overflow: hidden;
	background-position: 0px 0px;

.wrapper {
	position: absolute;
	top: 100%;
	left: 50%;
	width: 600px;
	margin-left: -300px;
	font: 300 30px/1 'Open Sans Condensed', sans-serif;
	font-family: 'Open Sans Condensed', sans-serif;
	font-size: 30px;
	line-height: 1;
	text-align: center;
	color: #fff;
	animation: 40s credits linear infinite;

.movie {
	margin-bottom: 50px;
	font-size: 50px;

.job {
	margin-bottom: 5px;
	font-size: 18px;

.name {
	margin-bottom: 40px;
	font-size: 35px;

.name-pic {
	margin-bottom: 70px;
	font-size: 35px;

@keyframes credits {
	0% { top: 100%; }
	100% { top: -2069px; }

Now create a passage named "Credits" and put something like this in it:

[[X|Start][UIBar.unstow()]]<<run UIBar.stow()>><div class="wrapper">
	<div class="movie">My Game</div>

	<div class="job">WRITER/PROGRAMMER</div>
	<div class="name-pic">My name</div>

	<div class="job"><img style="float:left; top: -20px; position: relative;" @src="setup.ImagePath+'steve.jpg'">PROOFREADER</div>
	<div class="name-pic">Joe Smith</div>

	<div class="job">TESTER<img style="float:right; top: -20px; position: relative;" @src="setup.ImagePath+'amy.jpg'"></div>
	<div class="name-pic">Amy Jones</div>
	<img @src="setup.ImagePath+'SomeLogo.png'">
	<div class="name">HiEv</div>
	<div class="name">MonkeyNinja</div>
	<div class="name">JustDave</div>
	<div class="name">etc.</div>
	<div class="job">This video game is protected under the copyright laws of the United States and other countries throughout the world.  This is a work of fiction.  Names, characters, businesses, places, events, locales, and incidents are either the products of the author's imagination or used in a fictitious manner.  Any resemblance to actual persons, living or dead, or actual events is purely coincidental.  No animals were harmed in the making of this video game.</div>
	<div class="movie">//My Game//<div>
	<div class="job">Copyright ©2018 by My Name<div>

Then just change "[X|Start]" to "[X|whatever passage name you want to go to next]", and make whatever other changes you need to the above.  The "X" will be a link in the upper-left to let you exit the credits.

If you have images, like the "PROOFREADER" and "TESTER" lines above, you can alternate between using the "float:left" and "float:right" versions like I did above.  You'll want the images to be about 120 pixels high and probably about the same width or you'll have to modify the code a bit.  Or, if you have no images, just copy the "WRITER/PROGRAMMER" lines for each entry.

If you want stand-alone images, just follow the "SomeLogo.png" example.

That will keep looping forever, with a slight pause in between.

For what it's worth, this question isn't as simple as it sounds.  I had to work quite a bit to figure out how to make it automatically stop and restart scrolling at the right position based on the height of the text.

Hope that helps!  :-)

by (490 points)
Ohh, brilliant! I've been testing this out for a bit and I absolutely love it. One question - is there any way to make the credits scroll only once, and then switch to a new page once they're finished?
by (44.7k points)
edited by

Glad you like it.

To do what you want, just change this line in the CSS:

animation: 40s credits linear infinite;

to remove the "infinite" part.  Then add this to the "Credits" passage:

<<timed 40s>><<run UIBar.unstow()>><<goto "Next">><</timed>>

and change "Next" to the name of the passage you want it to automatically go to.

Finally, change the "40s" in both of those lines to however many seconds you want the credits to take before going to the next passage, and you should be all set.

Enjoy!  :-)

0 votes
by (23.6k points)

If you just want for your credits to slowly scroll up the screen it would probably be easier to just put them into a div of some kind and use a css animation.