Hello there, I'm trying to get Twine into a more advanced state using scripting, but I'm running into trouble and I'm not sure if it is my dillentante abilities with Javascript/Jquery or a peculiarity of the Twine engine...
Essentially I have a <div>, id'ed '#toprighticons' which is partially off-screen when my Start passage loads. So far, so good. Now, I want it so that when I click the part of
#toprighticons which is visible, that it will move up from below the bottom of the screen and to be fully visible.
#toprighticons starts with a CSS value of
bottom:-7%;
So, I wrote a script passage in my Twine game that looks like this:
//requires jquery
var popup = function() {
$('#toprighticons').click(function() {
$('#toprighticons').animate({
bottom: "1%"
}, 200);
});
};
$(document).ready(popup);
But when I load the passage with
#toprighticons in it, I can't click on it - it just sits partially below the bottom edge of the page.
Happy to be called an idiot on this.
Comments
2. You fail to mention when/where
#toprighticons
is being created. No, "when my Start passage loads" does not address this (that only tells us that it exists at that point).Anyway, for now, I'll assume that
#toprighticons
is being created within your story passages. If so, that's part of your problem. All story formats executescript
-tagged passages long before any story passages are rendered onscreen (meaning the target you're trying to select won't be there). And no, using theready()
method does not help in this situation (story formats are applications, which have likely only started execution of user content because the document ready state has already been reached).If I've guessed what you're doing/wanting to do correctly, then you'll probably want to setup a delegated handler. For example: (goes in a
script
-tagged passage) That will only animate#toprighticons
open/out/up, however. If you wanted them to be more drawer like, meaning they could also be closed, then you'll want something more like the following:Thank you for clarifying how Twine handles script-tagged passages; this was the explanation I was looking for. I did assume that the way Twine worked meant that the loading order of scripts and HTML elements was a little different. Yes, indeed, my
#toprighticon
s is being created in theStart
story passage....And, lo and behold, your code works. Thank you so much. If I wanted to change an additional CSS value when #toprighticon is clicked, a CSS value for a different div, how would I fit this into the code? I'm still learning my Javascript syntax...
If you have time, I wonder if you could help me with one other thing.
I have some Javascript (attached) which sits in a separate .js file in the root folder of the Twine game. What it basically does is apply a snowstorm effect to the
<div>
#'edsnowstormdiv
. Currently, this<div>
is only found in my Start passage. The code works fine if, after building my Twine story, I manually insert the following Javascript call into the<head>
of the outputted .html file:So far so good; the Javascript runs when the Start passage loads. However, if I click through to another Passage and then RETURN to the Start passage, the Javascript does not run; no snowstorm. I guess this has something to do with what you were mentioning in your post; not only would I like that Javascript to run whenever I return to the Start passage, but I may want to call it in other, select passages later, by including the
snowstormdiv
and calling the Javascript. Perhaps I need to set up the Javascript in a handler?You've already helped a lot, but if you do have time, I'd appreciate your thoughts on this, and will happily give you credit for helping so much with the project!
Well, you could give the new action its own handler, which also listens for
click
events on#toprighticon
, or simply add it to the current handler. Unless this new action should have a different lifetime than the current action, then you might as well go with the latter. You can do that by inserting it after the original action(s), like so:snowstormdiv
and calling the Javascript. Perhaps I need to set up the Javascript in a handler?Oy vey, not that thing. That is a terribly written script and the author should feel bad.
Okay. I've attached a module containing your version of
snowstorm.js
and related plumbing which should work. Just put it in ascript
-tagged passage, no need to manually insertsnowstorm.js
anymore. That module will setup and teardown the snowstorm as necessary.All you should need to do is to add an appropriately styled element with the ID
snowstormdiv
to any passage in which you want a snowstorm....ah. Slight problem. When I load a passage that has 'snowstormdiv' in it, I get an alert saying 'Snowstorm Script:predisplay not defined.' Do you have any idea what this might be? I see the 'predisplay' at the top of the module...
=================================
... And on the other part, I messed up as well. I'm sorry. What I meant was that I wanted to change the CSS value of a different div with an animation that runs at the same length as the original one. I tried adapted the code you sent me thus to do this (the additional div to be animated, with a rotate, is
#arrow
):But it seems to have no effect. I have a lot to learn...
Either you're not using SugarCube, as you claimed, or you're using a version older than v1.0.9, which is when
predisplay
/postdisplay
were introduced.If it's the latter, you should upgrade (latest is v1.0.16).
If it's the former, then you've probably confused Sugarcane (vanilla/built-in) and SugarCube (not vanilla/built-in). If so, that would require a modification of the module, as the vanilla story formats do not offer
predisplay
/postdisplay
.You cannot mix jQuery animations and CSS transformations as you're trying to do. My suggestion would be to use a CSS transform and simply add/remove a triggering class via jQuery. For example:
Add this to your CSS (after your basic rules for
#arrow
, if any): Then change your code to something like this:#arrow
and#toprighticons
problem is completely solved. Not only this, I now understand what you did - as the animation that I am trying to do is CSS, not jQuery, I cannot used '.animate' with it - I have to instead, add remove classes and then use the transition-duration to make it appear animated over a number of millseconds. And now I know what to do in the future. Thank you so much.And, as you correctly surmised, I did write Sugarcube when I meant Sugarcane - I am in fact using the vanilla format. If you can help with this final problem, I'll have learnt a lot.
And here is a picture from the 'About' page of my game, showing what I promised. The link goes to this thread, in the spirit of Net openness.