[system] / trunk / pg / macros / CanvasObject.pl Repository:
ViewVC logotype

View of /trunk/pg/macros/CanvasObject.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6316 - (download) (as text) (annotate)
Thu Jul 1 21:47:45 2010 UTC (9 years, 6 months ago) by gage
File size: 16762 byte(s)
This revision works for ie8 and firefox most of the time for both java and flash applets.  Sometimes there will be a failure for the applet to load, followed by a successful load -- there is apparently still a race condition in determining whether an applet - particularly a flash applet -- is ready

    1 #! /usr/bin/perl -w
    2 
    3 $appletName="drawCanvas";
    4 $canvasName = "cv";
    5 
    6 HEADER_TEXT(<<END_HEADER_TEXT);
    7 <script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    8 <script language="javascript" src="${webworkHtmlURL}js/sketchgraphhtml5b/SketchGraph.pjs"></script>
    9 <script language="javascript" src="${webworkHtmlURL}js/sketchgraphhtml5b/processing-dgfix.js"></script>
   10 
   11 
   12 <script>
   13 // define your canvasObject here
   14 var $appletName = new Object
   15 $appletName.name = "$appletName";
   16 $appletName.id   = "$appletName";
   17 $appletName.setPoints = function(state){setPoints1()}
   18 $appletName.getPoints = function(state){return( getPoints1() )}
   19 
   20 
   21 //set your limits here
   22 var xmin = -5, xmax = 5, ymin = -5, ymax = 5;
   23 var points;
   24 var showGrid = true;
   25 var yValues = new Array();
   26 var derivatives = new Array();
   27 var canvasWidth = 400, canvasHeight = 400;
   28 var padding =3;
   29 
   30 
   31 
   32 //-------------------  Listeners ---------------------------
   33     //had to add the listeners with javascript
   34     //because it's not currently possible to reference processing methods from the html
   35 
   36     //reset the graph to 0
   37     function my_reset() {
   38       for (var i = 0; i < points; i++) {
   39 
   40         yValues[i] = 0.5;
   41         derivatives[i] = 0;
   42       }
   43       setPoints();
   44     }
   45 
   46     //toggle grid
   47     function toggleGrid() {
   48       showGrid = !showGrid;
   49     }
   50 
   51     //smooth the current graph
   52     function smooth() {
   53       var newPoints = new Array(points);
   54       for (var i = 0; i < points; i++) {
   55         var sum = 0.3 * yValues[i];
   56         sum += 0.2 * (i > 0? yValues[i-1] : yValues[i]);
   57         sum += 0.2 * (i < points-1? yValues[i+1] : yValues[i]);
   58         sum += 0.1 * (i > 1? yValues[i-2] : yValues[i]);
   59         sum += 0.1 * (i < points - 2? yValues[i+2] : yValues[i]);
   60         sum += 0.05 * (i > 2? yValues[i-3] : yValues[i]);
   61         sum += 0.05 * (i < points - 3? yValues[i+3] : yValues[i]);
   62         newPoints[i] = sum;
   63       }
   64       yValues = newPoints;
   65     }
   66 
   67 //     //grab points from graph and print
   68 //     function getPoints() {
   69 //       var temp = "";
   70 //       for(var i = 0; i < points; i++){
   71 //         temp += xmin + i*(xmax-xmin)/(points-1) + " ";
   72 //         temp += ymin + yValues[i]*(ymax - ymin) + " ";
   73 //         var dx = 1.0/points * (xmax - xmin);
   74 //         if (i == 0)
   75 //           temp += (yValues[1] - yValues[0])*(ymax-ymin)/dx + "\\n";
   76 //         else if (i == points-1)
   77 //           temp += (yValues[points-1] - yValues[points-2])*(ymax-ymin)/dx + "\\n";
   78 //         else {
   79 //           var i = i;
   80 //           var left = Math.abs(yValues[i] - yValues[i-1]);
   81 //           var right = Math.abs(yValues[i+1] - yValues[i]);
   82 //           if (left < 1e-20 || right < 1e-20)
   83 //             temp += 0 + "\\n";
   84 //           else
   85 //             temp += ((1/right)*(yValues[i+1]-yValues[i]) - (1/left)*(yValues[i]-yValues[i-1]))/(2*dx*((1/right)+(1/left))) + "\\n";
   86 //         }
   87 //       }
   88 //       \$('#pointDisplay').val(temp);
   89 //     }
   90 //
   91 //     //load points from y-values
   92 //     function setPoints() {
   93 //       var tempString = \$('#points1').val();
   94 //       var tempPoints = tempString.split(',');
   95 //       var vals = new Array(tempPoints.length);
   96 //       for(var i = 0; i < tempPoints.length; i++){
   97 //         vals[i] = parseInt(tempPoints[i]);
   98 //       }
   99 //       points = vals.length;
  100 //       yValues = new Array(points);
  101 //       derivatives = [points];
  102 //       for (var i = 0; i < points; i++)
  103 //         yValues[i] = 0.5;
  104 //       for (var i = 0; i < vals.length; i++) {
  105 //         if (vals[i] > ymax)
  106 //           yValues[i] = 1;
  107 //         else if (vals[i] < ymin)
  108 //           yValues[i] = 0;
  109 //         else
  110 //           yValues[i] = (vals[i]-ymin)/(ymax-ymin);
  111 //       }
  112 //     }
  113     //grab points from graph and print
  114 
  115     function getPoints1() {
  116       var temp = "";
  117       var temp2 = "";
  118       for(var i = 0; i < points; i++){
  119         temp += xmin + i*(xmax-xmin)/(points-1) + " ";
  120         temp += ymin + yValues[i]*(ymax - ymin) + " ";
  121         if (i!=0) { temp2 +=","};
  122         temp2 += ymin + yValues[i]*(ymax - ymin);
  123         var dx = 1.0/points * (xmax - xmin);
  124         if (i == 0)
  125           temp += (yValues[1] - yValues[0])*(ymax-ymin)/dx + "\\n";
  126         else if (i == points-1)
  127           temp += (yValues[points-1] - yValues[points-2])*(ymax-ymin)/dx + "\\n";
  128         else {
  129           var i = i;
  130           var left = Math.abs(yValues[i] - yValues[i-1]);
  131           var right = Math.abs(yValues[i+1] - yValues[i]);
  132           if (left < 1e-20 || right < 1e-20)
  133             temp += 0 + "\\n";
  134           else
  135             temp += ((1/right)*(yValues[i+1]-yValues[i]) - (1/left)*(yValues[i]-yValues[i-1]))/(2*dx*((1/right)+(1/left))) + "\\n";
  136         }
  137       }
  138       //alert("printing temp to ${appletName}_state" + temp );
  139       temp = "<xml>" + temp + "</xml>";
  140       \$('#${appletName}_state').val(temp);
  141       \$('#answerBox').val(temp2);
  142       return(temp);
  143     }
  144 
  145     //load points from y-values
  146     function setPoints1() {
  147       var tempString = \$('#answerBox').val();
  148       //alert("getting temp string from  $answerBox" + tempString );
  149       var tempPoints = tempString.split(',');
  150       var vals = new Array(tempPoints.length);
  151       for(var i = 0; i < tempPoints.length; i++){
  152         vals[i] = parseFloat(tempPoints[i]);
  153       }
  154       if (vals.length>2) points = vals.length;
  155       yValues = new Array(points);
  156       derivatives = [points];
  157       for (var i = 0; i < points; i++)
  158         yValues[i] = 0.5;
  159       for (var i = 0; i < vals.length; i++) {
  160         if (vals[i] > ymax)
  161           yValues[i] = 1;
  162         else if (vals[i] < ymin)
  163           yValues[i] = 0;
  164         else
  165           yValues[i] = (vals[i]-ymin)/(ymax-ymin);
  166       }
  167     }
  168 </script>
  169 
  170 END_HEADER_TEXT
  171 
  172 sub insertCanvas {
  173     my $myWidth = shift() || 200;
  174     my $myHeight = shift() ||200;
  175   $canvasObject = MODES(TeX=>"canvasObject",HTML=><<END_CANVAS);
  176   <script> var canvasWidth = $myWidth; var canvasHeight = $myHeight;</script>
  177   <canvas id="cv" data-src="${webworkHtmlURL}js/sketchgraphhtml5b/SketchGraph.pjs" width="$myWidth" height="$myHeight"></canvas>
  178 END_CANVAS
  179 # keep END_CANVAS flush left!!
  180   return $canvasObject;
  181 }
  182 
  183 sub insertYvaluesInputBox {
  184   $yValuesInput = MODES(TeX=>"yVAluesInput",HTML=><<EOF);
  185   <p>
  186   Y-values:
  187   <input type="text" id="points1" size=50></input>
  188   <button type="button" id="setPts" onClick="setPoints();">Set</button>
  189   </p>
  190 EOF
  191   return $yValuesInput;
  192 
  193 }
  194 
  195 sub insertGridButtons {
  196   $gridButtons = MODES(TeX=>"gridButtons",HTML=><<EOF);
  197   <button type="button" id="hideGrid" onClick="toggleGrid();">Toggle Grid</button>
  198   <button type="button" id="reset1" onClick="my_reset();">Reset to Zero</button>
  199   <button type="button" id="smooth1" onClick="smooth();">Smooth</button>
  200   <br><br>
  201 
  202 EOF
  203   return $gridButtons;
  204 }
  205 # sub stateAndDebugBoxes {  ## inserts both header text and object text
  206 #   #my $self = shift;
  207 #   my %options = @_;
  208 #
  209 #
  210 #   ##########################
  211 #   # determine debug mode
  212 #   # debugMode can be turned on by setting it to 1 in either the applet definition or at insertAll time
  213 #   ##########################
  214 #
  215 #   my $debugMode = (defined($options{debug}) and $options{debug}>0) ? $options{debug} : 0;
  216 #   my $includeAnswerBox = (defined($options{includeAnswerBox}) and $options{includeAnswerBox}==1) ? 1 : 0;
  217 #   $debugMode = $debugMode || 0; #   $self->debugMode;
  218 #     #$self->debugMode( $debugMode);
  219 #
  220 #
  221 #   my $reset_button = $options{reinitialize_button} || 0;
  222 #   warn qq! please change  "reset_button=>1" to "reinitialize_button=>1" in the applet->installAll() command \n! if defined($options{reset_button});
  223 #
  224 #   ##########################
  225 #   # Get data to be interpolated into the HTML code defined in this subroutine
  226 #   #
  227 #     # This consists of the name of the applet and the names of the routines
  228 #     # to get and set State of the applet (which is done every time the question page is refreshed
  229 #     # and to get and set Config  which is the initial configuration the applet is placed in
  230 #     # when the question is first viewed.  It is also the state which is returned to when the
  231 #     # reset button is pressed.
  232 #   ##########################
  233 #
  234 #   # prepare html code for storing state
  235 #   my $appletName      = 'cv';        # $self->appletName;
  236 #   my $appletStateName = "${appletName}_state";   # the name of the hidden "answer" blank storing state FIXME -- use persistent data instead
  237 #   my $getState        = 'getPoints()'; # $self->getStateAlias;    # names of routines for this applet
  238 #   my $setState        = 'setPoints()'; # $self->setStateAlias;
  239 #   my $getConfig       = '';          # $self->getConfigAlias;
  240 #   my $setConfig       = '';          # $self->setConfigAlias;
  241 #
  242 #   my $base64_initialState     = '';  # encode_base64($self->initialState);
  243 #   main::RECORD_FORM_LABEL($appletStateName);            #this insures that the state will be saved from one invocation to the next
  244 #                                                         # FIXME -- with PGcore the persistant data mechanism can be used instead
  245 #     my $answer_value = '<xml></xml>';
  246 #
  247 #   ##########################
  248 #   # implement the sticky answer mechanism for maintaining the applet state when the question page is refreshed
  249 #   # This is important for guest users for whom no permanent record of answers is recorded.
  250 #   ##########################
  251 #
  252 #     if ( defined( ${$inputs_ref}{$appletStateName} ) and ${$main::inputs_ref}{$appletStateName} =~ /\S/ ) {
  253 #     $answer_value = ${$main::inputs_ref}{$appletStateName};
  254 #   } elsif ( defined( $main::rh_sticky_answers->{$appletStateName} )  ) {
  255 #       warn "type of sticky answers is ", ref( $main::rh_sticky_answers->{$appletStateName} );
  256 #     $answer_value = shift( @{ $main::rh_sticky_answers->{$appletStateName} });
  257 #   }
  258 #   $answer_value =~ tr/\\$@`//d;   #`## make sure student answers can not be interpolated by e.g. EV3
  259 #   $answer_value =~ s/\s+/ /g;     ## remove excessive whitespace from student answer
  260 #
  261 #   ##########################
  262 #   # insert a hidden answer blank to hold the applet's state
  263 #   # (debug =>1 makes it visible for debugging and provides debugging buttons)
  264 #   ##########################
  265 #
  266 #
  267 #   ##########################
  268 #   # Regularize the applet's state -- which could be in either XML format or in XML format encoded by base64
  269 #   # In rare cases it might be simple string -- protect against that by putting xml tags around the state
  270 #   # The result:
  271 #   # $base_64_encoded_answer_value -- a base64 encoded xml string
  272 #   # $decoded_answer_value         -- and xml string
  273 #   ##########################
  274 #
  275 #   my $base_64_encoded_answer_value;
  276 #   my $decoded_answer_value;
  277 #   $answer_value = '<xml></xml>'; #(defined( $answer_value) and $answer_value =~/\S/)? $answer_value : '<xml></xml>';
  278 #   if ( $answer_value =~/<XML|<?xml/i) {
  279 #     $base_64_encoded_answer_value = $answer_value;  #encode_base64($answer_value);  #FIXME
  280 #     $decoded_answer_value = $answer_value;
  281 #   } else {
  282 #         $decoded_answer_value = $answer_value;  #    decode_base64($answer_value);
  283 #     if ( $decoded_answer_value =~/<XML|<?xml/i) {  # great, we've decoded the answer to obtain an xml string
  284 #       $base_64_encoded_answer_value = $answer_value;
  285 #     } else {    #WTF??  apparently we don't have XML tags
  286 #       $answer_value = "<xml>$answer_value</xml>";
  287 #       $base_64_encoded_answer_value = $answer_value; #  encode_base64($answer_value);
  288 #       $decoded_answer_value = $answer_value;
  289 #     }
  290 #   }
  291 #     $base_64_encoded_answer_value =~ s/\r|\n//g;    # get rid of line returns
  292 #
  293 #   ##########################
  294 #     # Construct answer blank for storing state -- in both regular (answer blank hidden)
  295 #     # and debug (answer blank displayed) modes.
  296 #   ##########################
  297 #
  298 #   ##########################
  299 #     # debug version of the applet state answerBox and controls (all displayed)
  300 #     # stored in
  301 #     # $debug_input_element
  302 #   ##########################
  303 #
  304 #     my $debug_input_element  = qq!\n<textarea  rows="4" cols="80"
  305 #      name = "$appletStateName" id = "$appletStateName">$decoded_answer_value</textarea><br/>!;
  306 #   if ($getState=~/\S/) {   # if getStateAlias is not an empty string
  307 #     $debug_input_element .= qq!
  308 #           <input type="button"  value="$getState"
  309 #                  onClick="debugText='';
  310 #                           ww_applet_list['$appletName'].getState();
  311 #                           if (debugText) {alert(debugText)};"
  312 #           >!;
  313 #   }
  314 #   if ($setState=~/\S/) {   # if setStateAlias is not an empty string
  315 #     $debug_input_element .= qq!
  316 #           <input type="button"  value="$setState"
  317 #                  onClick="debugText='';
  318 #                           ww_applet_list['$appletName'].setState();
  319 #                           if (debugText) {alert(debugText)};"
  320 #           >!;
  321 #   }
  322 #   if ($getConfig=~/\S/) {   # if getConfigAlias is not an empty string
  323 #     $debug_input_element .= qq!
  324 #           <input type="button"  value="$getConfig"
  325 #                  onClick="debugText='';
  326 #                           ww_applet_list['$appletName'].getConfig();
  327 #                           if (debugText) {alert(debugText)};"
  328 #           >!;
  329 #   }
  330 #   if ($setConfig=~/\S/) {   # if setConfigAlias is not an empty string
  331 #     $debug_input_element .= qq!
  332 #         <input type="button"  value="$setConfig"
  333 #                  onClick="debugText='';
  334 #                           ww_applet_list['$appletName'].setConfig();
  335 #                           if (debugText) {alert(debugText)};"
  336 #             >!;
  337 #     }
  338 #
  339 #   ##########################
  340 #     # Construct answerblank for storing state
  341 #     # using either the debug version (defined above) or the non-debug version
  342 #     # where the state variable is hidden and the definition is very simple
  343 #     # stored in
  344 #     # $state_input_element
  345 #   ##########################
  346 #
  347 #   my $state_input_element = ($debugMode) ? $debug_input_element :
  348 #         qq!\n<input type="hidden" name = "$appletStateName" id = "$appletStateName"  value ="$base_64_encoded_answer_value">!;
  349 #
  350 #   ##########################
  351 #     # Construct the reset button string (this is blank if the button is not to be displayed
  352 #     # $reset_button_str
  353 #   ##########################
  354 #
  355 #     my $reset_button_str = ($reset_button) ?
  356 #             qq!<input type='submit' name='previewAnswers' id ='previewAnswers' value='return this question to its initial state'
  357 #                  onClick="setAppletStateToRestart('$appletName')"><br/>!
  358 #             : ''  ;
  359 #
  360 #   ##########################
  361 #   # Combine the state_input_button and the reset button into one string
  362 #   # $state_storage_html_code
  363 #   ##########################
  364 #
  365 #
  366 #     $state_storage_html_code = qq!<input type="hidden"  name="previous_$appletStateName" id = "previous_$appletStateName"  value = "$base_64_encoded_answer_value">!
  367 #                               . $state_input_element. $reset_button_str
  368 #                              ;
  369 #   ##########################
  370 #   # Construct the answerBox (if it is requested).  This is a default input box for interacting
  371 #   # with the applet.  It is separate from maintaining state but it often contains similar data.
  372 #   # Additional answer boxes or buttons can be defined but they must be explicitly connected to
  373 #   # the applet with additional javaScript commands.
  374 #   # Result: $answerBox_code
  375 #   ##########################
  376 #
  377 #     my $answerBox_code ='';
  378 #     if ($includeAnswerBox) {
  379 #     if ($debugMode) {
  380 #
  381 #       $answerBox_code = $main::BR . main::NAMED_ANS_RULE('answerBox', 50 );
  382 #       $answerBox_code .= qq!
  383 #                <br/><input type="button" value="get Answer from applet" onClick="eval(ww_applet_list['$appletName'].submitActionScript )"/>
  384 #                <br/>
  385 #               !;
  386 #     } else {
  387 #       $answerBox_code = main::NAMED_HIDDEN_ANS_RULE('answerBox', 50 );
  388 #     }
  389 #   }
  390 #
  391 #   ##########################
  392 #     # insert header material
  393 #   ##########################
  394 #   #main::HEADER_TEXT($self->insertHeader());
  395 #   # update the debug mode for this applet.
  396 #     main::HEADER_TEXT(qq!<script> ww_applet_list["$appletName"].debugMode = $debugMode;\n</script>!);
  397 #
  398 #   ##########################
  399 #     # Return HTML or TeX strings to be included in the body of the page
  400 #   ##########################
  401 #
  402 #     return main::MODES(TeX=>' {\bf  applet } ',
  403 #     #HTML=>$self->insertObject.$main::BR.$state_storage_html_code.$answerBox_code);
  404 #      HTML=>$main::BR.$state_storage_html_code.$answerBox_code
  405 #      );
  406 #  }
  407 
  408 sub insertPointsArea {
  409   $pointsArea = MODES(TeX=>"pointsArea",HTML=><<EOF);
  410   <button type="button" id="getPts" onClick="getPoints();">Get Points</button><br/>
  411   <textarea id="pointDisplay" rows=10 cols=60></textarea>
  412 EOF
  413   return $pointsArea;
  414 }

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9