Howdy, Stranger!

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

A bunch of questions [Sugarcube]

Hey!

I have successfully converted my map-generator to sugarcube, and it's so much better... not having to simulate for-loops alone removes so much clutter from the code and the performance has improved a lot. However, there are some issues that i can't tackle yet...

1. The process of processing the map takes some time, meanwhile the screen freezes before the passage which includes the map is rendered. To avoid the impression, that the browser has crashed I would like to have a loading-screen, like the one sugarcube displays when initialising the story. How can I do that?

2. This one is probably more tricky... The map is composed of single images, which are placed in the passage by a loop according to an array. I'd like to integrate a link into every tile, that allows me to draw a new map based on the surrounding tiles of the tile that was clicked. For this, somehow the position within the array, that the tile represents, needs to be passed on with the link. I thought this could be done with a setter link, but since the variable that would be used in this process would be updated continuously while the loop is running, only the final position could be passed on. I tried writing it into the link itself, but a solution like that would require hundreds of prepared passages... so, is there a way to do that?

3. I am trying to get html2canvas ( http://html2canvas.hertzen.com/ ) to work, in order to offer a convenient saving option for the generated maps. I put the map within a <div class="canvas"></div> tag and tried to run the script with the following code within a <<script>>-tag
html2canvas(canvas, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
however, I get the error "bad evaluation: canvas is not defined". Any clues on how to get this to run? :)

Comments

  • 1. To use SugarCube's built-in loading screen:

    <<run document.documentElement.classList.add("init-loading")>>

    /% Long running thing... %/

    <<run document.documentElement.classList.remove("init-loading")>>

    2. The easiest way would be to force early binding on the $variables via printing.  How exactly would depend on how you're creating the images and links.  Details would help.


    3. Two things:
    [list type=decimal]
    You need to select the element.
    You cannot do that from within the same passage that you created the &lt;div class=&quot;canvas&quot;&gt;, because the passage is still rendering and not on the page yet and you have no way of getting at the render buffer from inside of the rendering passage.

    So, you'll either need to put something like this in the PassageDone special passage:

    <<script>>
    var canvas = document.querySelector("#passages .canvas");
    if (canvas !== null) {
    html2canvas(canvas, {
    onrendered : function (canvas) {
    document.body.appendChild(canvas);
    }
    });
    }
    <</script>>
    Or, something like this in a script tagged passage:

    postrender["canvasSetup"] = function (content) {
    var canvas = content.querySelector(".canvas");
    if (canvas === null) { return; }
    html2canvas(canvas, {
    onrendered : function (canvas) {
    document.body.appendChild(canvas);
    }
    });
    };
  • Thank you, Madexile! :)

    I got number 3 to working with your code, even though that will still require some fiddling, because apparently html-linked images don't qualify as "same origin" but imported images work.

    Number 1 still puzzles me... If I only put in the first line I can summon the loading-screen but never get rid of it anymore... but if I place the second line anywhere in the code the loading-screen doesnt even show up at all and everything just behaves as if I hadn't included the code at all (ok, when put in to PassageDone it seems to mess with the way the page is rendered a bit).

    About number 2: I posted the loop here, I only left out the majority of the tiles. Right now, I still have regular html links in my script but I brought them in the form of twine syntax for this. I thought about using <<print>> but I have no idea how to access anything that has been "printed" as data.

    <<for $i to 0, $line to 0;$i lt $horizontal*$vertikal; $i++, $line++>>

    <<if $line gt $horizontal -1>>

    <<set $line to -1>>
    <<set $i to $i -1>>
    <br>

    <<else>>
    <<if $map[$i] eq 1>>
    [img[water.gif][passage][$foo to "bar"]]
    <<elseif $map[$i] eq 2>>
    [img[grass.gif][passage][$foo to "bar"]]

    /% etc... &amp;/

    <<endif>>

    <</for>>
  • 1. Yeah, sorry, I didn't think that through.  That's obviously not going to work.

    You're probably better off by doing something like the following.  Put this in a new passage, replacing REAL_MAP_GEN_PASSAGE_TITLE appropriately, and link to the new passage to generate your map (it will call your actual map generation passage):

    <<script>>
    jQuery(UISystem.setup()).append("<h1>Generating map (please wait)...</h1>");
    UISystem.open();
    setTimeout(function () {
    state.display("REAL_MAP_GEN_PASSAGE_TITLE", null, "replace");
    }, 250);
    <</script>>
    Then, in your real map generation passage, add this to the very end (after all of the map generation stuff):

    <<script>>
    UISystem.close();
    <</script>>
    I chose to use a UISystem modal for two reasons:
    [list type=decimal]
    You get to easily use a custom message.
    The built-in loading screen isn't going to animate anyway, since the map generation is blocking the tab's UI thread.

    Anyway, try that out.  If you don't like it, then let me know and I can tell you how to use the loading screen instead.


    2. For example:

    <<print "[img[water.gif][passage][$foo to " + JSON.stringify($variable) + "]]">>
    The call to JSON.stringify() is there to ensure that the $variable is properly stringified.
Sign In or Register to comment.