On this page:
big-bang
to-draw
stop-when
on-tick
on-key
key=?
to-draw-page
4.1 Jsworld Types
4.2 HTML user interface constructors
js-div
js-p
js-button
js-text
js-input
js-img
js-select

4 Jsworld

jsworld provides a world programming library that allows simple animation and games, as well as reactive HTML graphical user interfaces.

 (require (planet dyoo/js-vm:1:6/jsworld/jsworld))

(big-bang a-world handlers ...)  world
  a-world : world
  handlers : handler
Starts a reactive computation with big-bang. The rest of the arguments hook into the reactive computation.

By default, the page that’s displayed contains a rendering of the world value. In the presence of an to-draw or to-draw-page handler, big-bang will show a customized view.

The majority of the handlers register different stimuli that can trigger changes to the world. One instance is on-tick, which registers a function to update the world on a clock tick.

When the big-bang computation terminates through a stop-when, the final world is returned as its value.

(to-draw hook)  handler
  hook : (world -> scene)
For simple applications, to-draw is sufficient to draw a scene onto the display. The following program shows a ball falling down a scene.

  #lang planet dyoo/js-vm:1:6
  (define WIDTH 320)
  (define HEIGHT 480)
  (define RADIUS 15)
  
  (define INITIAL-WORLD 0)
  
  (define (tick w)
  (+ w 5))
  
  (define (hits-floor? w)
  (>= w HEIGHT))
  
  (check-expect (hits-floor? 0) false)
  (check-expect (hits-floor? HEIGHT) true)
  
  (define (render w)
  (place-image (circle RADIUS "solid" "red") (/ WIDTH 2) w
               (empty-scene WIDTH HEIGHT)))
  
  (big-bang INITIAL-WORLD
    (on-tick tick 1/15)
    (to-draw render)
    (stop-when hits-floor?))

(stop-when stop?)  handler?
  stop? : (world -> boolean)
When the world should be stopped – when stop? applied to the world produces true – then the big-bang terminates.

The program:
  #lang planet dyoo/js-vm:1:6
  (define (at-ten x)
  (>= x 10))
  
  (big-bang 0
    (on-tick add1 1)
    (stop-when at-ten))
counts up to ten and then stops.

(on-tick world-updater [delay])  handler?
  world-updater : (world -> world)
  delay : number? = 1/20
Produces a handler that responds to clock ticks. By default, every tick comes every 1/20’th of a second.

(on-key world-updater)  handler?
  world-updater : (world key? -> world)
Produces a handler that responds to key events.

(key=? key1 key2)  boolean?
  key1 : key?
  key2 : key?
Produces true if key1 is equal to key2.

(to-draw-page to-dom to-css)  handler
  to-dom : (world -> (DOM-sexp))
  to-css : (world -> (CSS-sexp))
One of the main handlers to big-bang is to-draw-page, which controls how the world is rendered on screen. The first argument computes a rendering of the world as a DOM tree, and the second argument computes that tree’s styling.

4.1 Jsworld Types

A dom-sexp describes the structure of a web page:

  dom-sexp = (list dom-element dom-sexp ...)

a css-sexp describes the structure of a page’s styling:

  css-sexp = 
(listof (cons (or dom-element string)
              (listof attrib)))

An attrib is a:
  attrib = (list string string)

Each of the dom-elements can take in an optional attribute list to assign to the new dom element; the common useful attribute is a key-value binding for an "id", which can be used to identify an element in the css-drawing function.

Here are examples of a dom-expr and a css-sexp.
  (define a-dom-sexp (list (js-div '(("id" "main-div")))
                           (list (js-text "Hello world"))))
  
  (define a-css-sexp (list (list "main-div"
                                 (list "background" "white")
                                 (list "font-size" "40px"))))

4.2 HTML user interface constructors

Here are the dom-element constructors.

(js-div [attribs])  dom-element?
  attribs : (listof attrib?) = '()
Constructs a div element.

(js-p [attribs])  dom-element?
  attribs : (listof attrib?) = '()
Constructs a paragraph element.

(js-button world-update-f [attribs])  dom-element
  world-update-f : (world -> world)
  attribs : (listof attrib) = '()
Constructs a button. When the button is pressed, the world is updated through world-update-f.

The following example counts how many times a button has been clicked.
  #lang planet dyoo/js-vm:1:6
  (define (press w)
  (add1 w))
  
  (define (draw w)
  (list (js-div)
        (list (js-button press) (list (js-text "Press me")))
        (list (js-text (format "Button presses: ~a" w)))))
  
  (define (draw-css w)
  '())
  
  (big-bang 0
   (to-draw-page draw draw-css))

(js-text text)  dom-element
  text : string?
Constructs regular text.

(js-input type world-update-f [attribs])  dom-element
  type : string
  world-update-f : 
(or/c (world string -> world)
      (world boolean -> world))
  attribs : (listof attrib) = '()
Creates an input form element. The types that are currently supported are:
  • "text"

  • "password"

  • "checkbox"

When the user changes the content of the form element, the runtime uses world-update-f to update the world. If the type is either "text" or "password", then the string value of the element will be passed as the second argument to it. If type is "checkbox", a boolean representing the checked status of the element will be passed to it.

The example below has a single text input form element, which allows the user to enter some value.
  #lang planet dyoo/js-vm:1:6
  (define (refresh w form-val)
  form-val)
  
  (define input-node
  (js-input "text" refresh '(("id" "myname"))))
  
  (define (draw w)
  (list (js-div)
        (list (js-div) (list (js-text (format "I see: ~s~n" w))))
        (list (js-div) (list input-node))))
  
  
  (define (draw-css w)
  '())
  
  (big-bang ""
   (to-draw-page draw draw-css))

The example below uses a checkbox to select among three elements:
  #lang planet dyoo/js-vm:1:6
  (define (make-ingredient-checkbox-sexp ingredient)
  (local [(define (on-check w v)
  (cond
    [v
     (cons ingredient w)]
    [else
     (remove ingredient w)]))]
  (list (js-div)
        (list (js-text ingredient))
        (list (js-input "checkbox"
                        on-check
                        `(("value" ,ingredient)))))))
  
  (define c1 (make-ingredient-checkbox-sexp "mushrooms"))
  (define c2 (make-ingredient-checkbox-sexp "green peppers"))
  (define c3 (make-ingredient-checkbox-sexp "olives"))
  
  (define (draw w)
  (list (js-div)
        c1
        c2
        c3
        (list (js-text (format "The world is: ~s" w)))))
  
  (define (draw-css w)
  '())
  
  (big-bang '()
   (to-draw-page draw draw-css))

(js-img url [attribs])  dom-element
  url : string
  attribs : (listof attrib) = '()
Creates an image element.

(js-select options world-update-f [attribs])  dom-element
  options : (listof string?)
  world-update-f : (world string -> world)
  attribs : (listof attrib) = '()
Constructs a select element with the given options. Whenever a new option is selected, the world-update-f function is called to get the new world.

The example below has a select with five elements.
  #lang planet dyoo/js-vm:1:6
  (define (select-house w an-option)
  an-option)
  
  (define a-select-element
  (js-select (list ""
                   "Gryffindor"
                   "Hufflepuff"
                   "Ravenclaw"
                   "Slytherin")
   select-house))
  
  (define (draw w)
  (list (js-div)
        (list a-select-element)
        (list (js-text (format "House: ~a" w)))))
  
  (define (draw-css w)
  '())
  
  (big-bang ""
   (to-draw-page draw draw-css))