Howdy, Stranger!

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

Randomized backgrounds per passage

Hello! I've been trying to add backgrounds to specific passages in a Harlowe Twine 2 project using javascript. It's fairy easy to show a random background image from a directory attached to <body onload="..") but that would only randomize the background when reloading the game, which is not what I want.

The closest thing to a solution I have seen is this- http://twinery.org/forum/discussion/2529/harlowe-1-0-1-javascript-dynamic-background-images which is doing something with hidden inline images that doesn't quite make sense to me.

Is there another way to do this? Again, what I am attempting is to pick a random numbered image from images/ as a page background, but only for specific passages.

Thanks in advance!

Comments

  • edited February 2017
    Which version of Harlowe.

    That JavaScript looks kinda hacky. There's a slightly easier way to do it if you're willing to do a lot more leg work, but I've only got it working in Harlowe 1.2.3. Adapting this solution from greyelf, you can use this code:

    In a header-tagged passage:
    {
    (print: "<script>$('html').removeClass(\)</script>")
    (if: (passage:)'s tags's length > 0)[(print: "<script>$('html').addClass('" + $background + "'\)</script>")]
    }
    

    Set up some base line CSS for all the images using the html element, to your preference. For example:
    html {
      background-attachment: fixed; 
      background-repeat: no-repeat;
      background-size: contain;
     }
    

    Then whip up some specific CSS:
    html.first {
      background-image: url("url1")
     }
    
    html.second {
      background-image: url("url2")
     }
    
    html.third {
      background-image: url("url3")
     }
    

    Then you can control the image via the $background variable. To make every passage do it, go the same header-tagged passage and place this:
    {
    (set: $background to (either: "first", "second", "third"))
    (print: "<script>$('html').removeClass(\)</script>")
    (if: (passage:)'s tags's length > 0)[(print: "<script>$('html').addClass('" + $background + "'\)</script>")]
    }
    

    You can also include the either statement directly in your passages. You can also easily manipulate which passage to have the random backgrounds on through tags, passage names, etc using Harlowe's built in functions and methods.

    This does not work in 2.0.0, and I'm not familiar enough with Harlowe to know why, but I'm sure it can be adapted somehow.
  • Chapel wrote: »
    This does not work in 2.0.0, and I'm not familiar enough with Harlowe to know why, but I'm sure it can be adapted somehow.
    I have added an amendment to the Basic Harlowe Passage Tag Based Styling thread explaining the related differences between Harlowe 1.x and 2.x, and why it may be effecting the CSS examples in this thread.
  • edited February 2017
    greyelf wrote: »
    Chapel wrote: »
    This does not work in 2.0.0, and I'm not familiar enough with Harlowe to know why, but I'm sure it can be adapted somehow.
    I have added an amendment to the Basic Harlowe Passage Tag Based Styling thread explaining the related differences between Harlowe 1.x and 2.x, and why it may be effecting the CSS examples in this thread.

    Ah okay. Makes sense. Also, note that I made a pretty dumb error above. The header code shouldn't be testing tag length at all. I wrote:
    {
    (print: "<script>$('html').removeClass(\)</script>")
    (if: (passage:)'s tags's length > 0)[(print: "<script>$('html').addClass('" + $background + "'\)</script>")]
    }
    

    I should've wrote:
    {
    (print: "<script>$('html').removeClass(\)</script>")
    (print: "<script>$('html').addClass('" + $background + "'\)</script>")
    }
    

    If you're using harlowe 2.x, then change "html" to "tw-story" in both that code and the css and you should be good. I'll test it out later when I'm back at my computer, but I wanted to fix that error now.
  • I should clarify, this is in 2.0
  • Thanks so much for helping with this, I'll see if I can implement your suggestions tonight.
  • So am I adding and removing backgrounds to tw-story? I tried that once before and it caused a lot of formatting problems with the text. Since I can add classes to html with tags, and it might be nice if it just added a random background to every html or body element with that tag.
  • edited March 2017
    You're stuck with tw-story as far as I know. Html might, might just work, but it will probably just get overwritten by tw-story. In my example you're using a variable to add the class in order to randomize it via something like (either:). If you don't want it to be random, then you can just set the variable to something static. You can't really make random tags, though you could incorporate tags to control the variable for you, though I don't think that'd save all that much time.

    I'm not sure why or how altering tw-story would break the formatting, at least if all you're doing is adding background images and associated properties.

    Edit: Just tested it using the tw-story element in Harlowe 2.0.0 and it worked exactly as it did in Harlowe 1.2.3 using the html selector, and did not seem to break formatting. Here's the exact code I used:

    In stylesheet:
    tw-story {
      background-attachment: fixed; 
      background-repeat: no-repeat;
      background-size: cover;
     }
    
    tw-story.base {
      background-image: none;
     }
    
    tw-story.first {
      background-image: url("https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQoVHq8EKwv90U6jRVuZjmfEDspakEAcXQY-glV78kMTvnypwGZ";);
     }
    
    tw-story.second {
      background-image: url("http://i.telegraph.co.uk/multimedia/archive/03519/potd-squirrel_3519920k.jpg";);
     }
    
    tw-story.third {
      background-image: url("https://s-media-cache-ak0.pinimg.com/originals/41/b6/d0/41b6d0cac893197d9b05b19b397d72d8.jpg";);
     }
    

    In the passages:
    ::header [header]
    {
      (print: "<script>$('tw-story').removeClass(\)</script>")
      (print: "<script>$('tw-story').addClass('" + $background + "'\)</script>")
     }
    
    ::init [startup]
    (set: $background to "base")
    
    ::main
    Some text.
    (set: $background to (either: "first", "second", "third"))
    [[<button type="button">Change Background</button>|main]]
    
  • Any idea why I'd be seeing:

    "the number 0 isn't the same type of data as the string "')</script>"
    I tried to use an operation on some data, but the data's type was incorrect."
  • edited March 2017
    You need to give $background a string variable in a startup tagged passage. In the example above I used "base".
  • edited March 2017
    Got it. I had my variable in the wrong passage.
  • edited March 2017
    wiley wrote: »
    I had copied it exactly into the first passage.
    You should be initialising the $background variable (as well as your other variables) within your story's startup tagged passage, as explained by @Chapel.

    If you had done that then $background would of had a default value before your "header print statements".
  • edited March 2017
    it doesn't seem to ever change the tw-story class from base to anything else... (apologies if I'm being dense, I'm a regular webdesigner trying to help out a friend with their twine game, so I might be missing something obvious.)

    intro passage:
    I had been wandering in the snow for...days? I couldn't be sure.
    
    (set: $background to (either: "first", "second", "third"))
    (link-goto: "I was cold", "intro 2")
    

    header passage (has some extra existing class adds for html):
    {
    (print: "<script>$('html').removeClass(\)</script>")
    (if: (passage:)'s tags's length > 0)[
    (print: "<script>$('html').addClass('" + (passage:)'s tags.join(' ') + "'\)</script>")
    ]
    (print: "<script>$('tw-story').removeClass(\)</script>")
    (print: "<script>$('tw-story').addClass('" + $background + "'\)</script>")
    }
    

    startup passage has lots of existing variables, but
    $background to "base",
    
    is in there with the sets too, I know that's working because I can see the base class added to tw-story in the inspector.


    Anything I should be looking for?
  • I tested the above and assuming you have assigned the correct Passage Tag your startup and header passages (startup and header respectively), that you are using the Harlowe 2.0.0 story format, and that you are using the CSS from Chapel's comment then when the intro passage is shown there should be no background image, and when the intro 2 passage is shown it should have one of the three background images.

    notes:
    1. The passage names of the startup and header tagged passages can be whatever you want because their names have no meaning to the Harlowe engine, only which special passage tag has been assigned.

    2. Unless you are planing to use both custom passage tags and the $background variable to style your story then you should do as Chapel suggested and replace the contents of your header tagged passage with the following:
    {
    (print: "<script>$('html').removeClass(\)</script>")
    (print: "<script>$('html').addClass('" + $background + "'\)</script>")
    }
    
    ... even if you are considering using both techniques to style the story I would suggest using Harlowe 2.0.0's built-in passage tag support which is mentioned in this amendment to the Basic Harlowe Passage Tag Based Styling thread.
  • It's working now! I was actually using the html class add/remove too in order to scope which passages got the backgrounds.

    Thanks so much! I've been stuck for a while trying to do this conventionally and it looks like Twine actually makes it pretty easy now that I see it working.

    (Has anyone else got a problem where hitting 'undo' deletes a whole passage though? It's happening for me on the mac twine app and I did quite a bit of cussing at it as a result)
  • wiley wrote: »
    .. it looks like Twine actually makes it pretty easy now that I see it working.
    This has nothing to do with the Twine application, it is the story format that is doing all the work.
  • One last detail- is there a way to fade these backgrounds in? It doesn't seem like I can just add a css transition (like the "appear" keyframes that harlowe is already using) because of the way the background is loaded? Nothing that I've tried along those lines seem to work, the backgrounds always pop in.
  • edited March 2017
    wiley wrote: »
    One last detail- is there a way to fade these backgrounds in? It doesn't seem like I can just add a css transition (like the "appear" keyframes that harlowe is already using) because of the way the background is loaded? Nothing that I've tried along those lines seem to work, the backgrounds always pop in.

    Sorry, lost track of this. If you haven't figured it out yet, you can try something like this in your story JavaScript:
    //fade-in tw-story on link-click
    $(document).on('click', 'tw-link', function () { 
        $('tw-story').hide().fadeIn(1000); //play with the fadeIn(x) number to your liking, it's in ms
     });
    

    This has a couple of weird hiccups, as it fires the transition on the link click instead of on the passage loading, but I couldn't for the life of me figure out how to do something closer to a post-render.

    In other words, while this code "works," you might want to check back in a bit to see if anyone else has anything better, and bumping with this code should help with that. Good luck!
Sign In or Register to comment.