Here’s the code for the first method you described.
First, add this to your JavaScript section:
/* <<fadeLine>> macro - Start */
Macro.add("fadeLine", {
tags : ["nextLine", "complete"],
handler : function () {
var txt, words, show, hide, transition = 500; // Default transiton time = 0.5s
var wps = State.variables.wps / 1000; // Get words per second from $wps.
if (this.args.length >= 1) { // See if a parameter was passed to the macro.
// Use the transition time parameter passed to the macro instead of the default.
transition = Util.fromCssTime(this.args[0]);
}
show = transition; // Initial delay.
for (var i = 0, len = this.payload.length; i < len; ++i) {
// Handle each section of the macro.
txt = this.payload[i].contents.trim(); // Get a line of text.
words = (txt.match(/\s/g) || []).length + 1; // Count the words based on spaces.
hide = (words / wps) - transition; // Calculate display time.
if (hide < 0) {
hide = 0;
}
if (this.payload[i].name === "complete") {
// Display a <<complete>> section's line of text.
$(this.output).wiki('<span class="fadeline" data-transition="' + transition + '" data-show="' + show + '">' + txt + '</span>');
} else {
// Display any other section's line of text.
$(this.output).wiki('<span class="fadeline" data-transition="' + transition + '" data-show="' + show + '" data-hide="' + hide + '">' + txt + '</span>');
}
show += hide + transition; // Calculate the delay for the next line of text.
}
}
});
$(document).on(":passagerender", function (event) {
$(event.content).find(".fadeline").each(function () {
// Set up the transitions for each item with the "fadeline" class.
if ($(this).data("hide") === undefined) {
// Fade in a line of text after a delay.
$(this).delay($(this).data("show")).fadeTo($(this).data("transition"), 1);
} else {
// Fade in a line of text after a delay, then fade the text out after another delay.
$(this).delay($(this).data("show")).fadeTo($(this).data("transition"), 1).delay($(this).data("hide")).fadeTo($(this).data("transition"), 0);
}
});
});
/* <<fadeLine>> macro - End */
(See the jQuery documentation for an explanation of how the .data(), .delay(), and .fadeTo() methods work.)
Then add this to your Stylesheet section:
.fadeline {
display: block;
opacity: 0;
}
If you don’t want the text to appear on separate lines, then just remove the display: block;
line there.
Once you’ve done that, you can now put code like this within your passages:
<<fadeLine 0.25s>>
This is the first line of text.
<<nextLine>>
This is the second line of text.
<<nextLine>>
This is the third line of text.
<<nextLine>>
This is the fourth line of text.
<<nextLine>>
This is the fifth line of text.
<<complete>>
This is the last line of text.
<</fadeLine>>
The “0.25s
” part represents the transition time that a fade out or fade in takes and also the delay before the first line starts to fade in. That transition time is optional, so if you leave that out it will default to 0.5s
. The minimum time that a line of text will be shown will be twice that transition time.
The first line of text within the <<fadeLine>>
macro, as well as any lines after a <<nextLine>>
, will fade in and then fade out. The lines of text will be shown for (words / $wps) + transition
amount of time. Lines after a <<complete>>
will fade in, but won’t fade out. And you’ll need the <</fadeLine>>
at the end. Each line fades in at the same time that the previous line fades out (assuming that it fades out).
Hopefully that gives you an idea of how you can create the other macros you need and also makes what you’re trying to do a lot simpler.
Please let me know if you have any questions on how any of that works.
Enjoy!