title: Better event-based redraw() of Processing.js when using noLoop()
body: <p>I am using Processing.js, with jQuery 1.3.2 at my disposal, and targeting Firefox 3.5, Safari 4 and IE 8 (through ExplorerCanvas). The Processing.js website says "Using Explorer Canvas with Processing.js typically results in unusable frame-rates for moderately complex visualizations." Well, in this case, animation is not required, just some simple sketching, so frame rate is not an issue. I only need a redraw() every time there is a change in input data in a form. I am 99% there and need just one piece of inspiration to get IE under control! </p>
  
  <p>keyPressed() responds to changes in input fields perfectly, but redraws on changes in checkbox and select fields are unfortunately delayed until an actual key is pressed. mousePressed() only causes an update when clicked <em>inside the canvas</em>. The user experience is a bit jerky and confusing. How do I get the sketch to immediately redraw on any keyboard/mouse event?</p>
  
  <p>CODE</p>
  
  <p>In the page's main JavaScript block, I set up an object for passing JSON data that is dependent on select fields between the form and Processing.js, and also as a place to put the IE flag:</p>
  
  <pre><code>window.common = {};
  </code></pre>
  
  <p>I put a boolean in the "common" object when the browser is IE using a "conditional comment" script:</p>
  
  <pre><code>&lt;!--[if IE]&gt;
      &lt;script type="text/javascript"&gt;
          window.common.IE = true;
      &lt;/script&gt;
  &lt;![endif]--&gt;
  </code></pre>
  
  <p>For completeness, the "common" object receives the JSON data in this fashion, using the wonderful jQuery getJSON function:</p>
  
  <pre><code>$.getJSON(xhr_url, function(json, status){
      /*  
          This is the equivalent of writing either 
          "window.common.global_d_b = json[d];" or
          "window.common.global_d_c = json[d];" for 
          each property, such as "d," in the json object,
          and subscripts "_b" or "_c".  
      */
      for (var property in json) {
          window.common['global_' + property + subscript] = json[property];
      }
  });
  </code></pre>
  
  <p>The Processing.js setup looks like this:</p>
  
  <pre><code>flag_for_IE = window.common.IE;
  
  void setup()
  {
      size(int(W), int(H));       // Canvas size as set above
      frameRate(4);               // Refresh rate in fps for FF &amp; Safari
      stroke(darkSteelGrey);      // Set default linework color
      fill(medSteelGrey);         // Set default fill color
      background(lightBlue);      // Set background color
      if (flag_for_IE) {
          noLoop();               // Stop looping for IE.
      }
  }
  </code></pre>
  
  <p>The draw loop starts like this, getting needed parametric data direct from the form:</p>
  
  <pre><code>void draw() {
  
  /*  *****  ORDINARY DYNAMIC DATA FROM INPUT AND SELECT ELEMENTS  *****  */
  /*
  Some jQuery JavaScript is used here to get data provided by the user. Where 
  necessary, invalid form entries are set equal to zero so the interactive 
  sketching will be smoother.
  */
      var tp = float($('#id_tp').val());       // End plate thickness
      tp = isNaN(tp) ? 0.0 : tp;
      var bp = float($('#id_bp').val());       // End plate width
      bp = isNaN(bp) ? 0.0 : bp;
      var db = float($('#id_db').val());       // Bolt diameter
  </code></pre>
  
  <p>When a change in the form kicks off an AJAX request, the data comes into the draw() loop like this:</p>
  
  <pre><code>d_b = window.common.global_d_b;
  tf_b = window.common.global_tf_b;
  </code></pre>
  
  <p>After the draw() loop comes the conditional redraw logic:</p>
  
  <pre><code>/*  Redraw control for IE.  */
  if (flag_for_IE) {
      redraw();
  
      void keyPressed() {
        redraw();
      }
  
      void mousePressed() {
        redraw();
      }
  }
  </code></pre>