How to use events when navigating between passages?

I’m new to the twine way of doing things, so bear with me guys. I’m on Twine 2.3.8 using SugarcubeV2 (2.31).

So when I click on an image, say in passage-A, it takes me to some passage-B (where B is the id of the img) in which I return back to passage-A.

JS:

// on DOM is ready
$(function() {
		$( '.container img' ).on( 'click', ( e ) => (
		Engine.play( e.target.id ); // renders the passage
                ))
})

Passage-B:

This is passage B.
<<link "Back" $return>><</link>>

The problem is, navigating back to passage-A I can’t fire the event again (I don’t know about the routing, or if I can use some lifecycles), so my solution was to just attach the event to the document:

// on DOM is ready
$(function() {
		$( document ).on( 'click', '.container img', ( e ) => Engine.play( e.target.id ))
})

Is there a better way to do this? I’ve looked into the documentation for the visited function :thinking: but I don’t think that’s the best way to achieve this.

Sugarcube: 2.31
Twine: 2.3.8

I work in AXMA which is structured like Twine but isn’t quite the same so I can only answer theoretically:

If I wanted a passage to fire transitionally between every viewed passage, I would store the player’s destination passage in a variable somehow via the page link the player clicks on, then use a macro/header on every destination page which then checks the previous passage (Axma stores this automatically as a variable $$from). If the $$from passage name doesn’t match the transition passage name, the macro redirects to the transition passage.

The transition passage displays, then looks at the stored destination passage and directs back there (automatically, or via a link using the stored destination variable). The header macro in the destination now recognizes the $$from matches the transition passage and displays the destination as normal.

1 Like

Okay, I’m a real Twine noob so if this answer is dumb let me know. Could you use Sugarcube’s built in clickable image macro? I found some documentation here:http://www.motoslave.net/sugarcube/2/docs/#markup-image

1 Like

The problem here is that navigating between passages, dynamically generate the HTML and the binding of the click event on document initialization is lost. So if I returned back to a previous passage I won’t be able to use the click event a second time. Using event delegation binds the event for current and “future” elements in the DOM.
@mathbrush my images are generated by a widget macro, but yes I can use that, though it will require a lot of hard coding and repetition and I’m a lazy cookie :snail:

1 Like

Is the transition just showing an optional image?

2 Likes

Sorry didn’t get exactly what you mean by an optional image, so here’s what I have.

Clicking on the image will redirect to a passage, taking care of by a click event.

1 Like

Where are you placing this code? If you put it in PassageDone, it should be added every time after navigation is complete.

https://www.motoslave.net/sugarcube/2/docs/#special-passage-passagedone

Alternatively, I think you can set the trigger up in StoryInit using JS.

https://www.motoslave.net/sugarcube/2/docs/#events-navigation-event-passagedisplay

1 Like

In the javascript Story.

:pray: Thanks this will help
https://www.motoslave.net/sugarcube/2/docs/#events-navigation-event-passagedisplay

1 Like

That’s…an extremely JavaScripty way to do things: while it should work fine, I’d just do

<<widget imglink>>[img[$args[0]][$args[1]]]<</widget>>

and then use it as

<<imglink "img.png" "passage name">>
1 Like

For no particular reason, I thought that wouldn’t work :neutral_face: And honestly I didn’t know about the passageEvents.
No flogged plz I’m still new to this :hugs:
I was foolishly using a simpleton macro with HTML tags, that’s why I wasn’t able to click it.

Now I see how it’s done, My brain was farting big times all night long I didn’t realize that we can nest “widgets” and pass data just like that…

<<widget "imgLink">>
	<<set _src = main_dir/ + $args[0].trim() + '.jpg'>>
	[img[_src][$args[0].trim()]]
<</widget>>

<<widget "container">>
	// The img part
		<<set _tmp = $args[0].trim()>>
		@@.imgStyle;<<imgLink _tmp>>@@
	// Other weird stuff goes here
		// ...
<</widget>>

and then just

<<container "Joe">>

I need to spend more time with the documentation next time :face_with_head_bandage:

No, that’s totally fine, your way works, especially if you already know some JS. And you can’t return computed values from a widget (except by putting it in a temporary variable), so they’re not a great solution for everything. But I think in your case it’s probably the most idiomatic way.

Note that if you’re using a temporary variable like you are above, you may need the <<capture>> macro to freeze the value of _src? I’d test that with multiple image links: they might end up all using the last image? I’m not sure about that without testing, but…

They don’t need to use <<capture>> there because the value is used immediately. You only need to use <<capture>> when the variable usage takes place sometime after the value of that variable has changed, such as when the player clicks something.

2 Likes