Example

We're going to create a simple animation that causes a button to move back and forth on command. To start off, we're going to create a sleep method that yields execution for a specified number of milliseconds:

    function sleep(millis) {
        var notifier = new EventNotifier();
        setTimeout(notifier, millis);
        notifier.wait->();
    }    
Now with our sleep method implemented, we're able to implement a generalized animation method that doesn't require callbacks:
    function animate(element, property, endValue, duration, frequency) {    
        // calculate animation variables
        var frameCount = Math.ceil(duration/frequency);
        var startValue = parseInt(element.style[property], 10);
        var distance = endValue - startValue;
        var jumpSize = Math.ceil(distance/frameCount);
    
        // do the animation
        for (var i = 0; i < frameCount - 1; i++) {
            var nextValue = startValue + (jumpSize * i);
            element.style[property] = nextValue + "px";
    
            // note the yielding operation
            sleep->(frequency);
        }
    
        element.style[property] = endValue + "px";
    }
    
In addition to animation and sleeping, we'll create a method that will yield until a DOM element has been clicked:
    function waitForClick(element) {
        var notifier = new EventNotifier();
        element.onclick = notifier;
        notifier.wait->();
    }    
Now we can use our animate and waitForClick methods to create an interactive animation that bounces a button back and forth on screen at the user's request:
    function run() {
        var theButton = document.getElementById("theButton");
        while(true) {
            theButton.innerHTML = "go right";
            
            // move the button to the right (note the blocking operations)
            waitForClick->(theButton);
            theButton.innerHTML = "-->";
            animate->(theButton, "left", 200, 1000, 20);
    
            theButton.innerHTML = "go left";
    
            // move the button to the left (again note the blocking operations)
            waitForClick->(theButton);
            theButton.innerHTML = "<--";
            animate->(theButton, "left", 0, 1000, 20);
        }
    }
    spawn(run());
    
We put all of the above code into one file, moveButton.njs. After compiling moveButton.njs the compiled code may look a little scary, but keep in mind that even it is fairly unreadable, line numbering is consistent with the original source to help with the debugging process.

Finally, we need to whip up our HTML and JavaScript to load and compile moveButton.js:

    <button id="theButton" style="left:0px;"></button>
    <script src="../deploy/njs_compile.js"></script>
    <script>NjsCompiler.load("moveButton.njs");<</script>

Here's the browser rendering of the above HTML and JavaScript:

The next section describes how to compile Narrative JavaScript into regular JavaScript.