0 votes
by (220 points)
Hello, I was wondering if it's possible to trigger an instance of Typed.js with something like a window.onclick, after something already exists in your passage. The idea is that you have something written out already when the page loads > it waits for you to click anywhere on screen > click > Typed.js begins. The ideal scenario for me is to have Typed.js > click > Typed.js.

The problem is it seems is with the way Typed.js is built, it runs with the passage load and can never be stopped or paused until all instances of Typed.js complete. At which point everything after just renders as normal text output without the type effect.

1 Answer

0 votes
by (159k points)

It is unclear from your question whether you are using the Typed.js library directly or SugarCube's Typed.js integration module add-on, so I will assume that you are using the SugarCube add-on. It should be noted that using the add-on doesn't stop you from access the Typed.js library's functionallity directly within your project.

eg. The following example demostrates how you can still use the Typed.js library directly within a Passage, it makes use of SugarCube's :passagedisplay event to allow the targeting of the typed ID'ed element by the Typed() function.

Lorem ipsum, dolor sit amet consectetur adipisicing elit.
<span id="typed"></span>
<<script>>
	$(document).one(':passagedisplay', function (ev) {
		var typed = new Typed("#typed", {
			strings: ["The quick brown fox jumped over the lazy dog."],
			typeSpeed: 40
		});
	});
<</script>>


To achieve the "screen > click > Typed.js" use-case you will need to attach a click event listener to the page, which can be an issue because it is likely that it was a click event that cause the current Passage to be shown and that that click event is still active during the :passagedisplay event.

One way to get around this potential issue is to attach our click event listener to an element that is being (re)created during the Passage Transition process and one such element is the ,passage CSS classed one that the engine wraps the contents of the current passage in. One downside of using this element this is that by default it's height dimention is the minimum required to display the visible content of the passage, which can make the area the end-user needs to click in quite small.

Lorem ipsum, dolor sit amet consectetur adipisicing elit.
<span id="typed"></span>
<<script>>
	$(document).one(':passagedisplay', function (ev) {
		$(".passage").one('click', function() {
			var typed = new Typed('#typed', {
				strings: ["The quick brown fox jumped over the lazy dog."],
				typeSpeed: 40
			});
		});
	});
<</script>>


Using the strings option to add the new Typed content to the existing page can be messy if that new content is large, one way to get arround this is to use the stringsElement option instead however this option does have some quirks you need to watch out for.

Lorem ipsum, dolor sit amet consectetur adipisicing elit.
<span id="typed"></span>
<div id="typed-strings" style="display: none;">
	<p>The quick brown fox jumped over the lazy dog.</p>\
</div>
<<script>>
	$(document).one(':passagedisplay', function (ev) {
		$(".passage").one('click', function() {
			var typed = new Typed('#typed', {
				stringsElement: '#typed-strings',
				typeSpeed: 40
			});
		});
	});
<</script>>

some of the quirks:
a. The text to be Typed seems to need to be wrapped in text related elements like span, p, b, etc...
b. Any br elements found at the end of a line seems to cause that line to be cleared once it has finish being Typed. Because SugarCube automatically replaces all line-feeds found in the Passage content with br elements, you may need to use a feature like Line Continuation to suppress them like the above example does.

To achieve the "Typed.js > click > Typed.js" use-case you need to change the previous examples to listen for the :typedcomplete event instead of the :passagedisplay one.
 

<div class="typed-speed40">
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
</div>

<span id="typed-2"></span>
<div id="typed-2-strings" style="display: none;">
	<p>The quick brown fox jumped over the lazy dog.</p>\
</div>

<<script>>
	$(document).one(':typedcomplete', function (ev) {
		$(".passage").one('click', function() {
			var typed = new Typed('#typed-2', {
				stringsElement: '#typed-2-strings',
				typeSpeed: 40
			});
		});
	});
<</script>>

 

by (220 points)
This is perfect! Thank you so much Greyelf! Now to be able to click to go to another passage only after the second typed instance finishes. I gave it a couple shots but couldn't figure it out, I'll keep trying. If you have any ideas yourself, let me know!
by (159k points)

You already have most of the building blocks needed to achived a "Typed > Click > Typed > Click > Passage Transition" use-case, but there are still a couple of issues you need to resolve.

In your new use-case each instance of Typed text will need it's own click event handler, and each of these handlers will need to be attached to the .passage element after the displaying of associated instance of Typed text has been completed.

The SugarCube Typed addon includes a :typedcomplete event (that you already know how to listen for using the jQuery one() function) however you can't use that to solve this issue because the same event is send for each instance of Typed text so you can't tell which instance has just completed.

You can get around the above issue by combined the Typed.js Library's  own onComplete option with the usage of jQuery's event.trigger() function to send your own custom versions of the :typedcomplete event.

The second issue you need to solve is how to cause a Passage Transition using JavaScript, and you can use SugarCube's Engine.play() function to do that.

The following example combines all of the above to achieve your new use-case.

<span id="typed-1"></span>
<div id="typed-1-strings" style="display: none;">
	<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>\
</div>

<span id="typed-2"></span>
<div id="typed-2-strings" style="display: none;">
	<p>The quick brown fox jumped over the lazy dog.</p>\
</div>

<<script>>
	$(document).one(':passagedisplay', function (ev) {
		var typed = new Typed('#typed-1', {
			stringsElement: '#typed-1-strings',
			typeSpeed: 40,
			onComplete: function () {
				jQuery.event.trigger(":typedcomplete.typed-1");
			}
		});
	});

	$(document).one(':typedcomplete.typed-1', function (ev) {
		$(".passage").one('click', function() {
			var typed = new Typed('#typed-2', {
				stringsElement: '#typed-2-strings',
				typeSpeed: 40,
				onComplete: function () {
					jQuery.event.trigger(":typedcomplete.typed-2");
				}
			});
		});
	});

	$(document).one(':typedcomplete.typed-2', function (ev) {
		$(".passage").one('click', function() {
			Engine.play("Name of Next Passage");
		});
	});
<</script>>

 

...