Howdy, Stranger!

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

How to vertically align (bottom) images in passages? (Harlowe)

Hey all,

I'm working on a game called REFT in Twine 2.0 (Harlowe) as a final project for an experimental narratives course and have made a ton of progress with the mechanics. Now I'm trying to improve the aesthetics.

I use right and left arrow images to move forward and backward through passages, and these appear at the end of the text in each passage. A big part of the game is moving left and right through passages quickly, so I would like to make these arrow buttons stationary at the bottom of each passage. This would allow players to keep their cursor in one place and spam the buttons to quickly travel through passages.

I'm having trouble fixing these buttons in place at the bottom of the passages, though. I've tried adding align="bottom" (and other variations) inside the <img> code but this does nothing. I've also tried to create tables with <table><tr></tr></table> but these also don't show up. Any thoughts on how I can stick these buttons down there?

If you want, you can play the current prototype of REFT here to see what I'm working with.

Thanks!

Comments

  • Your issue is made up of two parts:

    1. Where is the bottom of the passage?

    You have assigned the tw-story element a height of 853px so you may think that the bottom of the passage (the tw-passage element) is somewhere around that point, but by default the height of a block element (like tw-passage) is automatically calculated to be the minimum needed to fix the element's contents.

    eg. If the contents is a single line of text then the bottom of the passage is just under that single line.

    You can change this behaviour by assigning the tw-passage a height like so:
    tw-passage {
    	height: 100%;
    }
    

    2. Forcing content to appear at the (new) bottom of the passage. (tw-passage)

    I would first suggest wrapping your images within a div element with an ID like the following, it will make them easier to move as a set:
    <div id="options"><img src="left-arrow.png"  /><img src="right-arrow.png" /></div>
    
    ... obviously your actual code looks different to the above example but the principle is the same.

    You can now move the #options element using CSS position related properties like position, left and bottom.
    tw-passage #options {
    	position: absolute;
    	bottom: 0px;
    	left: 0px;
    }
    
  • Hey greyelf! Thanks for your reply.

    Assigning tw-passage a height makes a lot of sense. Unfortunately I've followed your steps and the position of the images are still top aligned. It seems like
    tw-passage {
    	height: 100%;
    }
    
    isn't actually changing anything. I tried setting it to a pixel height as a test and nothing changed then either.

    Any ideas why this is the case?
  • Did you do the steps in the second point of my previous comment?

    eg. If you modify your New Game passage content like so:
    <center>(transition: "dissolve")[//Awaking from unconsciousness, you feel dizzy as you try to make sense of the spinning lights inside your head. Suddenly, a disembodied voice speaks to you from the void.//
    
    ''Welcome, Wanderer. You have been chosen from among those who seek the Will to End. Your time has come. Release your fear and wander forth.
    
    Pay attention not only to the world itself but also your feelings, for they too may help guide you.''
    
    Select your starting element to enter the world.
    ]</center>
    <div id="options">[[<img src="http://gdriv.es/twine/icon/fire_icon.png">->New Game Fire]]   [[<img src="http://gdriv.es/twine/icon/water_icon.png">->New Game Water]]   [[<img src="http://gdriv.es/twine/icon/earth_icon.png">->New Game Earth]]</div>
    
    ... then the following CSS should style it so that the three image links are centred at the bottom of the passage:
    tw-passage {
    	height: 100%;
    }
    tw-passage #options {
    	position: absolute;
    	bottom: 0px;
    	left: 0px;
    	
    	width: 100%;
    	text-align: center;
    }
    
  • Ah that works perfectly, but I guess the problem is the way I've nested passages with the (display:) macro to display the arrows. In the main story passages I have:
    (display: "Left Arrow")(display: "Right Arrow")
    

    In "Left Arrow" and "Right Arrow" I have:
    [[<img src="http://gdriv.es/twine/ui/arrowbrown_right.png"; align="right">->Next Level]]
    

    And then in "Next Level" I put:
    (if: $currentLevel is 1)[
        (goto: "Hills 2")]
    (else-if: $currentLevel is 2)[
        (goto: "Hills 3")]
    etc...
    

    So if I were to simply put
    [[<img src="http://gdriv.es/twine/ui/arrowbrown_right.png">->Next Level]]
    
    into each passage your method works, but something is getting messed up if I want to keep things minimal and only use (display: "Right Arrow"). I've tried wrapping the contents of "Next Level" with <div id="options"></div> but this has no effect.

    I don't mind making the code less neat if it means better UX, but is there a way to get the arrows bottom-aligned with the way I've set up the nested passages?

    Thanks again!
  • edited April 2016
    I based my previous New Game passage example on the hosted version of your game accessible via the link you supplied in your original post.

    If I change my example to include your (display:) macro based links then the CSS I supplied still works:
    <center>(transition: "dissolve")[//Awaking from unconsciousness, you feel dizzy as you try to make sense of the spinning lights inside your head. Suddenly, a disembodied voice speaks to you from the void.//
    
    ''Welcome, Wanderer. You have been chosen from among those who seek the Will to End. Your time has come. Release your fear and wander forth.
    
    Pay attention not only to the world itself but also your feelings, for they too may help guide you.''
    
    Select your starting element to enter the world.
    ]</center>
    <div id="options">(display: "Left Arrow")(display: "Right Arrow")</div>
    

    note: you can remove the text-align: center; rule from the tw-passage #options selector if you are going to align the images using the element's align attribute.
  • Okay so I've got it working when it's simply:
    <div id="options">(display: "Left Arrow")(display: "Right Arrow")</div>
    

    I've also figured out that the div element needs to be outside of (if:) macros, like so:
    <div id="options">(if: not ((history:) contains "Hills 5"))[(display: "Right Arrow")]</div>
    

    But now I can't get it to work with (click-replace:). For example, the following has no effect on the right arrow:
    Reach inside to reveal your inventory.(click-replace: "Reach inside to reveal your inventory.")[(display: "Inventory No Click")
    //It doesn't seem to matter which way you go, so you walk to the right.//]]<div id="options">(click-replace: "It doesn't seem to matter which way you go, so you walk to the right.")[(display: "Right Arrow")]</div>
    

    Am I missing something with the syntax or will it not work with (click-replace:)? Is there a workaround?

    Thank you for your patience and continued help, greyelf. When I give a progress report to my class on Wednesday I'm going to give you a shoutout, haha.
  • edited April 2016
    There is at least one syntax error in your last example.

    I think you are mis-understanding how the (click-replace:) macro works, the link is not created where the macro is, it is created where the selected text is.

    eg. The (click-replace: "It doesn't seem ...") is not creating the link inside the #options div element, it is being created before that div where the original "It doesn't seem ..." is located.

    You can see this by examining the page HTML after you have clicked on both the "Reach inside..." and the "It doesn't seem..." links. You can use your web-browser's Developer Tools or Inspect (Element) features to see the HTML, it will looks something like the following:
    <tw-expression type="macro" name="display">... contents of Inventory No Click passage ...</tw-expression>
    <i><tw-expression type="macro" name="display">... contenct of Right Arrow passage ...</tw-expression></i>
    <tw-expression type="macro" name="click-replace" class="false"></tw-expression>
    <tw-hook></tw-hook>
    <div id="options" data-raw=""><tw-expression type="macro" name="click-replace" class="false"></tw-expression><tw-hook></tw-hook></div>
    
    ... as you can see the contents of the Right Arrow passage is not inside the #options div so there-for the related CSS has no effect on the Right Arrow.

    You could restructure your code like so:
    Reach inside to reveal your inventory.(click-replace: "Reach inside to reveal your inventory.")[(display: "Inventory No Click")
    <div id="options">//It doesn't seem to matter which way you go, so you walk to the right.//</div>](click-replace: "It doesn't seem to matter which way you go, so you walk to the right.")[(display: "Right Arrow")]
    
    ... or even replace the String based (click-replace:) macros with named hook ones like so:
    |line1>[Reach inside to reveal your inventory.]
    (click-replace: ?line1)[(display: "Inventory No Click")
    |line2>[//It doesn't seem to matter which way you go, so you walk to the right.//]]
    (click-replace: ?line2)[<div id="options">(display: "Right Arrow")</div>]
    
  • I've got it working now! Just uploaded a new version of the game and the arrows stay planted at the bottom of each passage, making navigation much easier. Thank you again.
Sign In or Register to comment.