Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Adding a mouseover/hoverfunction that activates hidden passage links (Twine 2, Sugarcube 2)

I was wondering if it is possible to add a function in Twine 2 where a player is taken to a new passage when they move their mouse cursor over a certain text. For example, if there is a bit of text that says: "Don't look at the black cat", and the player is taken to a new passage if they move the cursor over "black cat". I am using Sugarcube 2. Any help would be greatly appreciated!

Comments

  • There are numerous ways that it could be done, the easiest would probably be to write a custom macro—or have one written.

    Something like the following: (goes in Story JavaScript)
    Macro.add('mousegoto', {
    	tags    : null,
    	handler : function () {
    		if (this.args.length === 0) {
    			return this.error('no passage specified');
    		}
    
    		var passage;
    
    		if (typeof this.args[0] === 'object') {
    			// Argument was in wiki link syntax.
    			passage = this.args[0].link;
    		}
    		else {
    			// Argument was simply the passage name.
    			passage = this.args[0];
    		}
    
    		if (!Story.has(passage)) {
    			return this.error('passage "' + passage + '" does not exist');
    		}
    
    		jQuery(this.output)
    			.wiki(this.payload[0].contents)
    			.one('mouseover.macros', function () {
    				setTimeout(function () {
    					Engine.play(passage);
    				}, Engine.minDomActionDelay);
    			});
    	}
    });
    
    Syntax:
    <<mousegoto passage_name_or_link>>content_to_mouse_over<</mousegoto>>
    
    Usage:
    → Using a "passage name"
    <<mousegoto "To Oz">>Over the rainbow!<</mousegoto>>
    
    → Using a [[passage link]]
    <<mousegoto [[To Oz]]>>Over the rainbow!<</mousegoto>>
    
  • edited February 2017
    Thank you for the help. This macro does move the player to another passage, but it does so if you move your mouse cursor over the body of the whole text instead of the words I framed between "<<mousegoto>>" and "<</mousegoto>>".
  • I'm sure @TheMadExile will have a better solution but the following modification worked for me.
    Macro.add('mousegoto', {
    	tags    : null,
    	handler : function () {
    		if (this.args.length === 0) {
    			return this.error('no passage specified');
    		}
    
    		var passage;
    
    		if (typeof this.args[0] === 'object') {
    			// Argument was in wiki link syntax.
    			passage = this.args[0].link;
    		}
    		else {
    			// Argument was simply the passage name.
    			passage = this.args[0];
    		}
    
    		if (!Story.has(passage)) {
    			return this.error('passage "' + passage + '" does not exist');
    		}
    
    		var el = jQuery('<span></span>')
    			.addClass('mousegoto')
    			.wiki(this.payload[0].contents)
    			.one('mouseover.macros', function () {
    				setTimeout(function () {
    					Engine.play(passage);
    				}, Engine.minDomActionDelay);
    			});
    		
    		jQuery(this.output).append(el);
    	}
    });
    
    ... I wrapped the <<mousegoto>> macro's output in a classed span so that you can style it if you want.
  • edited February 2017
    Ugh. You're right, of course. That's what I get for testing this without having other content in the mix. My apologies.

    @greyelf I wouldn't say better necessarily, your modification is on point. I do have some idioms that I like to follow, however, so I would have made some different choices.

    Here's my update:
    Macro.add('mousegoto', {
    	tags    : null,
    	handler : function () {
    		if (this.args.length === 0) {
    			return this.error('no passage specified');
    		}
    
    		var passage;
    
    		if (typeof this.args[0] === 'object') {
    			// Argument was in wiki link syntax.
    			passage = this.args[0].link;
    		}
    		else {
    			// Argument was simply the passage name.
    			passage = this.args[0];
    		}
    
    		if (!Story.has(passage)) {
    			return this.error('passage "' + passage + '" does not exist');
    		}
    
    		jQuery(document.createElement('span'))
    			.addClass('macro-' + this.name + ' ' + this.name)
    			.wiki(this.payload[0].contents)
    			.one('mouseover.macros', function () {
    				setTimeout(function () {
    					Engine.play(passage);
    				}, Engine.minDomActionDelay);
    			})
    			.appendTo(this.output);
    	}
    });
    
    Like greyelf's version, the wrapper contains the class mousegoto, which you may use for styling if you wish.
  • Thanks everyone! Got it working now :D Looks really cool
Sign In or Register to comment.