0 votes
by (150 points)

I'm trying to implement a dictionary into my Twine project, meaning I want to include a button the reader can click whenever they need to look up a term and then quickly return to whatever they're reading. I've managed to work out most of the logic except having the button function as a button. (I'm also planning on making it a modal (using this code) which may create problems, but so far as all my tests are concerned, the image problem is the main obstacle.) I want to be able to use a small image as an icon, and while Twine can render and place that image very easily, I can't get it to work as a link. I can't use <a href> because I don't know how to link to a passage through that (and from what I've read, I don't think it's possible anyway), and using (link: ) commands or even the basic link syntax in Twine (EG [[image.png|Passage]]) confuses Twine and throws up syntax errors.

1 Answer

0 votes
by (63.1k points)
selected by
 
Best answer

Unlike SugarCube, Harlowe doesn't have built in image support or modals, so you've chosen an uphill battle here. Regardless, I've found that the easiest (but not likely best) way to do this is to essentially use jQuery to map the action of the element to a hidden link. This is a sneaky, hacky workaround more than a solution. 

To do this, create your Harlowe link as normal using link markup or a (link:)-style macro (don't use (click:)), and wrap it in a hidden named hook: 

|dummylink)[(link: "dummy")[
    <!-- code here -->
]]

Next, you need to use a script element and jQuery to cause clicking on your image element to fire the link. To accomplish this, you need a way to target that image. Giving it an "id" attribute is probably easiest. 

<img id='modal-button' role='button' tabindex='0' src='url/to/your/image.png' />

You should probably set the tabindex and role as above to maintain accessibility. 

Now for the jQuery: 

<script>
setTimeout( function () {
    $('img#modal-button').on('click', function (ev) {
        ev.preventDefault();
        $('tw-hook[name=dummylink] tw-link').trigger('click');
    });
}, 40);
</script>

I wrote this from memory, so it may contain stupid mistakes or syntax errors, but that's the general concept. 

You can also trick the parser into rendering html code (like <img>) inside macros and markup links, but I've had issues with getting that to work consistently, and it will probably not be good for accessibility. 

by (150 points)

I don't think this code is working. It doesn't show up as a link in the Twine editor (no arrow pointing to the passage I'm linking to), and the image doesn't show up when I test play the passage. The only problem I can think of is that I put the jQuery in the generic Javascript file rather than the passage itself, although I just tried copy/pasting it directly into my test passage and got the same result.

by (63.1k points)
edited by
It needs to be in the passage, not in the story JavaScript area. The two are not the same, that is, you don't want to put code that should be in your passages in the JavaScript area and vice versa. In this case our jQuery is targeting transient page elements that need to be rendered to be targeted, it won't have anything to target if it isn't in the passages, and will silently fail.

(link:) macros do not generate passage arrows. If you were using markup links instead they would. And they would create the arrows even if the code didn't work.

Were your images working before? Nothing i have here would stop them from working, even if there were errors. Where are you storing these images and how are you linking to them? You may just want to post the code in question.
by (63.1k points)

Hmm, I did make a mistake though, on testing it.  Apparently Harlowe's 'hidden hooks' aren't hidden at all, they simply aren't rendered. On testing it, I needed to change the link part to this:

|dummylink>[(link: "dummy")[
    <!-- code here -->
]]

Which forced me to also add this CSS to my story stylesheet:

tw-hook[name=dummylink] {
    display: none;
}

And that worked fine.  Full code I used:

PASSAGE:

|test>[]
<img id='modal-button' role='button' tabindex='0' width='200' src='http://www.clker.com/cliparts/3/m/v/Y/E/V/small-red-apple-hi.png' />
{
|dummylink>[(link: "dummy")[
    (replace: ?test)[WORKED!]
]]

<script>
setTimeout( function () {
    $('img#modal-button').on('click', function (ev) {
        $('tw-hook[name=dummylink] tw-link').trigger('click');
    });
}, 40);
</script>
}

CSS:

tw-hook[name=dummylink] {
    display: none;
}
img {
    cursor: pointer;
}

 

by (150 points)

This new code works. Also, for the previous tests, I was using a basic <img> tag with the following URL: https://static.getjar.com/icon-50x50/36/907281_thm.png

...