Howdy, Stranger!

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

Disguising Buttons as Links [Snowman 1.2]

edited February 2016 in Help! with 2.0
I'm attempting to style a button in a way that resembles my story's passage links. It's attached to an alert notice that prevents the player from proceeding until the textbox is filled out, and also sets a story state variable when clicked.

I could make use of story states to save the textbox input, but with those alone, I'd lose the alert notice. And I'd prefer not to use Twine's standard button to set the story state variable, as it doesn't match the game's aesthetic. So, I'm in need of a workaround in order to use both the stylized links and the variable/alert button. (Hence the inconspicuous post title, disguising buttons as links.)

Here is an example of what I'd like to do, and the scripts I'm currently using.

r5ygxkR.png

TheMadExile was kind enough to provide both the StoryState/Alert Button and the script for Stylized Links depicted above. Please, give them credit if you use the code for your own work.

Stylized Links (StyleSheet)
/*choice button*/

#choices {
	list-style: none;
	padding: 0;
	border: 1px solid #bbb;
}
#choices li {
	margin: 0;
	padding: 0;
}
#choices li:not(:first-child) {
	border-top: 1px solid #bbb;
}
#choices li a {
	display: block;
	margin: 0;
	padding: 0.5em 0.8em;
	border: none;
	text-decoration: none;
	font-size: 75%;
}
#choices li a:hover {
	color: #fff;
	background-color: #718389;
}

Stylized Links (Passage Code)
<ul id="choices">
		<li>[[This is the link to the next passage.]]</li>
</ul>

StoryState/Alert Button (JavaScript)
function wordWrap(str, maxWidth) {
    var newLineStr = "\n"; done = false; res = '';
    do {                    
        found = false;
        // Inserts new line at first whitespace of the line
        for (i = maxWidth - 1; i >= 0; i--) {
            if (testWhite(str.charAt(i))) {
                res = res + [str.slice(0, i), newLineStr].join('');
                str = str.slice(i + 1);
                found = true;
                break;
            }
        }
        // Inserts new line at maxWidth position, the word is too long to wrap
        if (!found) {
            res += [str.slice(0, maxWidth), newLineStr].join('');
            str = str.slice(maxWidth);
        }

        if (str.length < maxWidth)
            done = true;
    } while (!done);

    return res;
}

function testWhite(x) {
    var white = new RegExp(/^\s$/);
    return white.test(x.charAt(0));
};

/*
	Sets up a text input box and continuation button.

	@param {string} selector - A jQuery-compatible selector for the wrapper element.
	@param {string} variable - The name of the variable to modify, just the variable.
	@param {string} passage  - The name of the passage to show upon completion.
*/
window.textBox = function (selector, variable, passage) {
	$(document).one("showpassage:after", function () {
		var	$input  = $(selector).find("input"),
			$button = $(selector).find("button");
		$input
			.attr({
				"type"     : "text",
				"tabindex" : 0
			})
			.on("change", function () {
				story.state[variable] = this.value;
			})
			.on("keypress", function (evt) {
				if (evt.which === 13) { // 13 is Return/Enter
					evt.preventDefault();
					$(this).change();
					$button.click();
				}
			});
		$button
			.attr("tabindex", 0)
			.on("click", function () {
				if (story.state[variable] && story.state[variable].trim() !== "") {
					story.show(passage);
				} else {
					window.alert("Please, fill out the text box.");
				}
			});
	});
};

StoryState/Alert Button (Passage Code)
What is your first name?
[
<input>
<button>Next</button>
]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>

I'd greatly appreciate any help offered with this. It's the second to last function I'll need for my Twine game.

Comments

  • You can use something like the following to make the button look like your markup link. The #nameinput button's CSS properties are based on the #choices li related ones in your example.
    #nameinput button {
    	display: block;
    	width: 100%;
    	border: 1px solid #bbb;
    	background-color: inherit;
    	line-height: inherit;
    	padding: 0.5em 0.8em;
    	text-align: left;
    }
    #nameinput button:hover {
    	color: #fff;
    	background-color: #718389;
    }
    
  • edited February 2016
    It looks precisely how I wanted it to. Thank you very much, greyelf.

    In the original code, I've found an issue with decoupling the text box from the button. They cannot be separated by any other text or code. For example, I can't use it mid sentence. I'll try to illustrate the problem below.

    It has to look like this
    -----
    
    "What do I call you?" she asked
    
    "You can call me ," I replied
    
    -----
    
    [
    <input>
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
    -----
    

    And cannot be used like this
    -----
    
    "What do I call you?" she asked
    
    "You can call me {#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>," I replied
    
    -----
    
    [
    <input>
    <button>Next</button>
    ]
    
    -----
    

    Although, it's very likely that this is only because of my poor code experience.

  • The Javascript code that TheMadExile gave you relies on both the text field (<input>) and the button (<button>) being contained within the #nameinput element which is created via the
    [ ...... ]{#nameinput}
    
    You can add other items inside the #nameinput element yourself, like so:
    [
    Here is some text<br>
    <input>
    <br>Here is some more text<br>
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
  • edited February 2016
    It works for the text field, but it looks like any text within the JavaScript code ignores the game's Stylesheet. Along with any default Snowman features. (e.g. five consecutive dash marks (-) no longer creates a line)

    ˅
    ˄

    xGkWvoM.png
    [
    -----<br>
    <br>"What do I call you?" she asked<br>
    <br>"You can call me <input>," I replied<br>
    
    <br>-----<br>
    
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
    -----
    
  • edited February 2016
    If you look at Snowman 2's documentation you will see that using [ ... ]{#element-id} to wrap passage content within a div element with an id attribute has nothing to do with TheMadExile's Javascript, it is a Snowman 2 feature.

    The following example shows that using Sub-heading Markdown within one of Snowman 2's generated div elements does not work:
    Sub-header outside generated div
    -----
    
    [
    Sub-header inside generated div
    -----
    ]{#the-divs-id}
    
    ... this may be a bug in which case you may want to create an issue on the Snowman 2 project website.

    You can use HTML to create Heading and Sub-heading:
    <h1>This is the equivalent of a Markdown Heading</h1> 
    
    <h2>This is the equivalent of a Markdown Sub-heading:</h2>
    
  • The line of hyphens thing is a markup issue. In Markdown (the base markup language used by Snowman), a line of equal signs or hyphens directly underneath any text creates a heading/sub-heading. For example, the following markup:
    Some Heading
    =========
    
    Becomes:
    <h1>Some Heading</h1>
    
    And, the following markup:
    Some Sub-Heading
    ----------------
    
    Becomes:
    <h2>Some Heading</h2>
    

    To create a horizontal rule with a line of hyphens (of which you need three or more) you must leave a blank line between the line of hyphens and any text. For example, the following markup:
    Text that will not be taken as a heading.
    
    ----
    
    More text that will not be taken as a heading.
    
    Becomes:
    Text that will not be taken as a heading.
    
    <hr>
    
    More text that will not be taken as a heading.
    
    Alternatively, you may also simply use the <hr> tag directly.


    Beyond the basic confusion about lines of hyphens, there does seem to be an issue if you try to nest a line of hyphens (to create an <hr>) within other markup. It's probably related to the nested sub-heading issue noted by greyelf (since they both use lines of hyphens). Might be a issue worth reporting on Snowman's issue tracker.

    An easy way around the issue is to use the <hr> tag directly. For example, instead of the following:
    [
    -----<br>
    <br>"What do I call you?" she asked<br>
    <br>"You can call me <input>," I replied<br>
    
    <br>-----<br>
    
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
    Use <hr> tags:
    [
    <hr><br>
    <br>"What do I call you?" she asked<br>
    <br>"You can call me <input>," I replied<br>
    
    <br><hr><br>
    
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
  • Alright, that's one problem resolved. I got it to resemble the other passage's <hr> or (-) formatting. However, it still ignores the stylesheet. Might I be able to use HTML to enable custom font (Garamond) and fix the paragraph dissimilarities? I've created a quick visual example for both formats below.


    Here is how the original text/paragraph formatting looks

    2HevrkT.png?1
    -----
    
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mi felis, feugiat a augue ac, posuere volutpat nibh. Cras vel iaculis nulla, sed semper turpis. Aenean et lorem accumsan, finibus libero at, feugiat magna. Morbi posuere elit commodo, placerat velit at, fermentum nulla. Sed in enim viverra, iaculis nunc ut, accumsan orci. Integer vel orci leo. Vivamus arcu magna, pretium eu faucibus a, imperdiet eget ante. Suspendisse quis leo in leo gravida volutpat. Mauris lacus lorem, pretium eget libero ut, lobortis tristique quam.
    
    Integer lobortis diam sed malesuada scelerisque. Nam pretium sollicitudin ex et varius. Proin consequat nunc at mi suscipit, vitae pretium velit bibendum. Aenean feugiat lobortis tincidunt.
    
    -----
    
    <ul id="choices">
    	<li>[[Next]]</li>
    </ul>
    
    -----
    

    And this is how the formatting appears with div elements

    a57FdQ0.png
    [
    <hr>
    <br><font size="2">"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mi felis, feugiat a augue ac, posuere volutpat nibh. Cras vel iaculis nulla, sed semper turpis. Aenean et lorem accumsan, finibus libero at, feugiat magna. Morbi posuere elit commodo, placerat velit at, fermentum nulla. Sed in enim viverra, iaculis nunc ut, accumsan orci. Integer vel orci leo. Vivamus arcu magna, pretium eu faucibus a, imperdiet eget ante. Suspendisse quis leo in leo gravida volutpat. Mauris lacus lorem, pretium eget libero ut, lobortis tristique quam.</font><br>
    <br><font size="2">Integer lobortis diam sed malesuada scelerisque. Nam pretium sollicitudin ex et varius. Proin consequat nunc at mi suscipit, vitae pretium velit bibendum. Aenean feugiat lobortis tincidunt.</font><br>
    
    <br><hr>
    
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    
    <hr>
    
  • edited February 2016
    One way to add a font to your story is by importing it from a font hosting site, the following CSS imports a similar font from google.
    note: The following needs to be place at the TOP of your Story Stylesheet!
    @import url(https://fonts.googleapis.com/css?family=EB+Garamond);
    

    If you look at the HTML being generated by Snowman 2 you will notice that it generally wraps text that ends with two or more line-breaks using a p (paragraph) element:
    eg.
    This text should be wrapped in a paragraph.
    
    The same with this text!
    
    ... becomes:
    <p>This text should be wrapped in a paragraph.</p>
    <p>The same with this text!</p>
    
    note: I say generally because it does not happen within div's created using [ ... ]{..} syntax.

    If you manually do the same with the text you place within your [ ... ]{#nameinput} you will be able to style it using CSS. So if I change your example to the following:
    [
    <hr>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc mi felis, feugiat a augue ac, posuere volutpat nibh. Cras vel iaculis nulla, sed semper turpis. Aenean et lorem accumsan, finibus libero at, feugiat magna. Morbi posuere elit commodo, placerat velit at, fermentum nulla. Sed in enim viverra, iaculis nunc ut, accumsan orci. Integer vel orci leo. Vivamus arcu magna, pretium eu faucibus a, imperdiet eget ante. Suspendisse quis leo in leo gravida volutpat. Mauris lacus lorem, pretium eget libero ut, lobortis tristique quam.</p>
    
    <p>Integer lobortis diam sed malesuada scelerisque. Nam pretium sollicitudin ex et varius. Proin consequat nunc at mi suscipit, vitae pretium velit bibendum. Aenean feugiat lobortis tincidunt.</p>
    <hr>
    <button>Next</button>
    ]{#nameinput}<% textBox("#nameinput", "name_player", "Next Passage") %>
    <hr>
    
    ... You can now style the above paragraphs using the following:
    #nameinput p {
    	font-family: 'EB Garamond', serif;
    	font-size: small;
    	margin-left: 3em;
    	margin-right: 3em;
    }
    
    note: If you want to style all paragraphs (including the ones generated by Snowman 2) then change the above CSS selector from #nameinput p to #passage p
  • Thanks for your help, you two. Your code helped a lot. I know it's been a while since this was posted, but could one of you help me with a minor Stylesheet issue?

    Everything works fine, but there is a size discrepancy between the Choice Button and the Name Input Button. (Shown below via Imgur.) Top button is the Name Input button, second is Choice Button.

    5rMk3Fq.png

    I'd like to have the Stylesheet code for the Name Input button resemble the Choice button Stylesheet, but am unsure how to correct this. The Name Input button won't move any further left when I adjust the size, and the Stylesheet code for both buttons differs in how they're built; so it's harder to match their height and width.

    Here's the Stylesheet for the Choice Button
    #choices {
    	list-style: none;
    	padding: 0;
    	border: 1px solid #bbb;
    }
    #choices li {
    	margin: 0;
    	padding: 0;
    }
    #choices li:not(:first-child) {
    	border-top: 1px solid #bbb;
    }
    #choices li a {
    	display: block;
    	margin: 0;
    	padding: 0.5em 0.8em;
    	border: none;
    	text-decoration: none;
    	font-size: 75%;
    }
    #choices li a:hover {
    	color: #fff;
    	background-color: #718389;
    }
    

    And here's the Stylesheet for the Name Input button.
    #nameinput button {
      display: block;
    	width: 100%;
    	border: 1px solid #bbb;
    	background-color: inherit;
    	line-height: inherit;
      	padding: 0.5em 0.8em;
    	text-align: left;
      	font-size: 85%;
      
    }
    #nameinput button:hover {
    	color: #fff;
    	background-color: #718389;
    }
    

    I'd appreciate any help offered on this little problem. Thanks!
Sign In or Register to comment.