idmillington / undum

A client-side framework for narrative hypertext interactive fiction.
https://idmillington.github.com/undum
MIT License
336 stars 80 forks source link

Add transitions when writing content/an API for configuring Undum #37

Closed sequitur closed 9 years ago

sequitur commented 9 years ago

Currently, content written with System.prototype.write() and other API functions that use doWrite simply pops into existence, without a transition or animation. For presentation reasons, it would be nice if that weren't the case - if paragraphs written into a situation would slide or fade in instead.

This is easy enough to do:

var doWrite = function(content, selector, addMethod, appendMethod) {
    continueOutputTransaction();
    var output = augmentLinks(content)
    .hide(); // Compose hide() method so element won't show up when created
    var element;
    if (selector) element = $(selector);
    if (!element) {
        $('#content')[addMethod](output);
    }
    else {
        element[appendMethod](output);
    }
    output.fadeIn({duration: 200}); // Reveal the element
    /* rest of function */

The problem is that this would be hard-coded, and not only would it change the presentation of existing stories, it would also not be configurable by authors. As far as I can tell, however, the API doesn't have any existing entry point for authors to configure the global behaviour of Undum. Ideally, they would be able to write something similar:

undum.game.init = function(character, system) {
    system.setWriteTransition('fadeIn', {duration: 200});
    /* or alternatively */
    undum.game.config.transition = {methodName: 'fadeIn', methodArguments: {duration: 200}};
    /*...*/

To set up this behaviour, while the default would be the current behaviour of having no transition at all. There are other ways of setting this up; for instance, by holding this as a property of Situation, so that globally it can be achieved by:

undum.game.init = function(character, system) {
    Situation.prototype.transition = {methodName: 'fadeIn', methodArguments: {duration: 200}};
    /*...*/

Or similar. I don't want to write some version of this and send in a pull request for this because it's kind of an involved decision as to how exactly it should work.

idmillington commented 9 years ago

My feeling is that, if it is done so it looks good, then it can be hardcoded. I've never tried to make Undum be everything to everyone: it is a programmers framework, and as such, there are plenty of things you might need to change to make it work. It is also quite opinionated about its UI, I think it looks good. I've not added other themes and such, because I think making it into something that would meet every need out of the box is not quite what I wanted for the system.

So my gut would be to just hard code the 200ms fade in. That is fast enough that it is unlikely to cause a problem. It wouldn't really harm existing games in the wild, since they are unlikely to be redeployed with later code-bases. And it would look a little nicer.

The only thing I do wonder is whether it can be done with CSS animation, like the existing animation. Do you know? I haven't done CSS animation for a while (since writing undum). If it can, that's the best of all worlds, rather than use jQuery. But as I said above, jQuery animation hardcoded wouldn't worry me.

sequitur commented 9 years ago

I originally thought no, because an element being inserted into the DOM isn't something that would trigger the CSS transition property, but it turns out I am just ignorant; this works:

    @keyframes fadeIn {
      from {opacity: 0;}
      to {opacity: 1;}
    }

    @-webkit-keyframes fadeIn {
      from {opacity: 0;}
      to {opacity: 1;}
    }

    @-moz-keyframes fadeIn {
      from {opacity: 0;}
      to {opacity: 1;}
    }

    #content p {
      animation: fadeIn 200ms;
      -moz-animation: fadeIn 200ms;
      -webkit-animation: fadeIn 200ms;
    }

(The last selector could be .fade-in to create a class that authors can use, for example; or it could be #content p,span,a; I'm not sure which approach makes more sense).

I guess you can close this issue, since I went out of my way to forget an easier way of doing things. Thank you.

idmillington commented 9 years ago

Thanks Bruno. I'd be happy to merge a pull request for the CSS addition, if you figure out which selector works best. I do like things beautifully animated.

sequitur commented 9 years ago

I'll look into it more closely when I have a good test case to check things against, as the tutorial game is currently broken.