Rev 18641 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
15111 | schaersvoo | 1 | /*27/7/2013 version 0.01 |
7614 | schaersvoo | 2 | "Inspired" by FLY program: http://martin.gleeson.com/fly |
3 | ********************************************************************************* |
||
18552 | bpr | 4 | * J.M. Evers 7/2013 * |
5 | * This is all just amateur scriblings... So no copyrights. * |
||
6 | * This source code file, and compiled objects derived from it, * |
||
7 | * can be used and distributed without restriction, including for commercial use * |
||
8 | * No warrenty whatsoever * |
||
7614 | schaersvoo | 9 | ********************************************************************************* |
10 | */ |
||
18552 | bpr | 11 | #define VERSION "0.5" |
18104 | georgesk | 12 | |
13 | #define _GNU_SOURCE |
||
14 | #include <string.h> |
||
15 | |||
7848 | bpr | 16 | #include "canvasdraw.h" |
15348 | bpr | 17 | void *tmp_buffer; |
18552 | bpr | 18 | FILE *js_include_file; |
7614 | schaersvoo | 19 | /****************************************************************************** |
20 | ** Internal Functions |
||
21 | ******************************************************************************/ |
||
18552 | bpr | 22 | void add_to_buffer(char *tmp); /* add tmp_buffer to the buffer */ |
23 | void sync_input(FILE *infile);/* proceed with inputfile */ |
||
24 | void reset();/* reset some global variables like "use_filled", "use_dashed" */ |
||
25 | int get_token(FILE *infile); /* read next char until EOL*/ |
||
18623 | bpr | 26 | char *fillcolor; |
27 | int x2px(double x); |
||
28 | int y2px(double y); |
||
18606 | bpr | 29 | |
18552 | bpr | 30 | double px2x(int x); |
31 | double px2y(int y); |
||
32 | double get_real(FILE *infile,int last); /* read a value; calculation and symbols allowed */ |
||
33 | char *str_replace ( const char *word, const char *sub_word, const char *rep_word ); |
||
18623 | bpr | 34 | char *get_color(FILE *infile,int last); /* read hex-color or colorname -> hex */ |
18552 | bpr | 35 | char *get_string(FILE *infile,int last); /* get the string at the end of a command */ |
36 | char *get_string_argument(FILE *infile,int last); /* the same, but with "comma" as separator */ |
||
18558 | bpr | 37 | int hypgeodaux(double *q, double* res, int full); |
18552 | bpr | 38 | char *convert_hex2rgb(char *hexcolor); |
39 | void make_js_include(int canvas_root_id); |
||
40 | void check_string_length(int length);/* checks if the length of string argument of command is correct */ |
||
41 | FILE *js_include_file; |
||
42 | FILE *get_file(int *line_number, char **filename); |
||
43 | FILE *infile; /* will be stdin */ |
||
7614 | schaersvoo | 44 | /****************************************************************************** |
45 | ** global |
||
46 | ******************************************************************************/ |
||
47 | int finished = FALSE;/* main variable for signalling the end of the fly-script ; if finished = 1 ; write to stdout or canvasz */ |
||
48 | int line_number = 1;/* used in canvas_error() ; keep track of line number in canvasdraw/fly - script */ |
||
49 | /* set some variables to avoid trouble (NaN) in case of syntax and other usage errors */ |
||
50 | int xsize = 320; |
||
51 | int ysize = 320; |
||
52 | double xmin = 0.0; |
||
53 | double xmax = 320.0; |
||
54 | double ymin = 0.0; |
||
55 | double ymax = 320.0; |
||
11893 | schaersvoo | 56 | double tmax = 0; |
57 | double tmin = 0; |
||
7614 | schaersvoo | 58 | /* flag to indicate parsing of line status */ |
8224 | bpr | 59 | int done = FALSE; |
7614 | schaersvoo | 60 | int type; /* eg command number */ |
15111 | schaersvoo | 61 | int onclick = 0; |
62 | /* |
||
15116 | bpr | 63 | |
64 | 1 = onclick ; |
||
65 | 2 = draggable ; |
||
66 | 3 = click+slideable ; |
||
67 | 4 = slideable without click |
||
15111 | schaersvoo | 68 | 5 = draggable + slideable |
69 | */ |
||
14208 | schaersvoo | 70 | char *slider_type="0"; |
15111 | schaersvoo | 71 | char *my_sliders = "[-1]"; |
72 | int use_slider = -1; |
||
73 | int last_slider = 0; |
||
74 | double double_data[MAX_INT+1]; |
||
75 | int int_data[MAX_INT+1]; |
||
76 | int dragstuff[MAX_DRAGSTUFF]; |
||
77 | int js_function[MAX_JS_FUNCTIONS]; /* javascript functions include objects on demand basis: only once per object type */ |
||
78 | double affine_matrix[] = {1,0,0,1,0,0}; |
||
7785 | schaersvoo | 79 | int use_affine = FALSE; |
7614 | schaersvoo | 80 | int use_rotate = FALSE; |
14078 | bpr | 81 | int use_filled = 0; /* 0:no fill, 1:fill,2=grid?,3=hatch?,4=diamond?,5=dot?,6=image? */ |
82 | int use_dashed = FALSE; /* dashing not natively supported in firefox, for now... */ |
||
15111 | schaersvoo | 83 | double angle = 0.0; |
7614 | schaersvoo | 84 | char buffer[MAX_BUFFER];/* contains js-functions with arguments ... all other basic code is directly printed into js-include file */ |
9329 | schaersvoo | 85 | char *getfile_cmd = ""; |
15111 | schaersvoo | 86 | int reply_format = 0; |
87 | unsigned int canvas_root_id; |
||
88 | char *css_class; |
||
89 | int font_size; |
||
90 | char *draw_type; |
||
91 | int jsplot_cnt = -1; /* keepint track on the curve identity */ |
||
92 | int input_cnt = 0; |
||
93 | int dashtype[2] = { 4 , 4 }; /* just line_px and space_px: may have more arguments...if needed in future */ |
||
94 | char *function_label = "[\"f(x)=\",\"g(x)=\",\"h(x)=\"]"; |
||
95 | int drag_type = -1;/* 0,1,2: xy,x,y */ |
||
96 | int use_offset = 0;/* use_offset only for text shape objects... 0=none;1=yoffset;2=xoffset;3=xyoffset;4=centered*/ |
||
97 | int linegraph_cnt = 0; /* identifier for command 'linegraph' ; multiple line graphs may be plotted in a single plot*/ |
||
98 | int barchart_cnt = 0; /* identifier for command 'barchart' ; multiple charts may be plotted in a single plot*/ |
||
99 | int legend_cnt = -1; /* to allow multiple legends to be used, for multiple piecharts etc */ |
||
100 | int use_axis = FALSE; |
||
101 | int use_axis_numbering = -1; |
||
102 | int no_reset = FALSE; |
||
103 | |||
7614 | schaersvoo | 104 | /****************************************************************************** |
105 | ** Main Program |
||
106 | ******************************************************************************/ |
||
107 | int main(int argc, char *argv[]){ |
||
18552 | bpr | 108 | /* need unique id for every call to canvasdraw: rand(); is too slow...will result in many identical id's */ |
109 | struct timeval tv;struct timezone tz;gettimeofday(&tv, &tz); |
||
110 | canvas_root_id = (unsigned int) tv.tv_usec; |
||
111 | infile = stdin;/* read flyscript via stdin */ |
||
112 | int i,c; |
||
113 | for(i=0;i<MAX_DRAGSTUFF;i++){dragstuff[i] = 0;} |
||
114 | for(i=0;i<MAX_INT;i++){int_data[i]=0;double_data[i]=0;} |
||
115 | int use_snap = 0; /* 0 = none 1=grid: 2=x-grid: 3=y-grid: 4=snap to points */ |
||
116 | int print_drag_params_only_once = FALSE;/* avoid multiple useless identical lines about javascript precision and use_dragdrop */ |
||
18589 | bpr | 117 | int line_width = 2; |
18552 | bpr | 118 | int decimals = 2; |
119 | int use_dragstuff = 0; |
||
120 | int precision = 100; /* 10 = 1;100=2;1000=3 decimal display for mouse coordinates or grid coordinate.May be redefined before every object */ |
||
121 | int use_userdraw = 0; /* 0=none,1=userdraw,2=multidraw flag to indicate user interaction */ |
||
122 | int use_tooltip = -1; /* 1= tooltip 2= popup window*/ |
||
123 | int use_parametric = FALSE;/* will be reset after parametric plotting */ |
||
124 | char *tooltip_text = "Click here"; |
||
125 | char *temp = ""; /* */ |
||
126 | char *bgcolor = "";/* used for background of canvas_div ; default is tranparent */ |
||
127 | char *stroke_color = "255,0,0"; |
||
128 | char *fill_color = "255,255,255"; |
||
129 | char *font_family = "12px Arial"; /* commands xaxistext,yaxistext,legend,text/textup/string/stringup may us this */ |
||
130 | char *font_color = "#00000"; |
||
131 | draw_type = "points"; |
||
132 | char *fly_font = "normal"; |
||
133 | css_class = "none"; |
||
134 | char *flytext = ""; |
||
135 | int canvas_type = DRAG_CANVAS; /* to use a specific canvas for filling etc */ |
||
136 | int pixelsize = 1; |
||
137 | int fill_cnt = 0; |
||
138 | int use_zoom = 0; |
||
139 | font_size = 12;/* this may lead to problems when using something like <code>fontfamily Italic 24px Arial</code> the ''fontsize`` value is not substituted into fontfamily !! */ |
||
140 | int fly_font_size = 12; /*fly_font_size is relative to this... */ |
||
141 | for(i=0;i<MAX_JS_FUNCTIONS;i++){js_function[i]=0;} |
||
142 | int arrow_head = 8; /* size in px needed for arrow based userdraw: "userdraw arrow,color" */ |
||
143 | int crosshair_size = 5; /* size in px*/ |
||
144 | int plot_steps = 250;/* the js-arrays with x_data_points and y_data_points will have size 250 each: use with care !!! use jscurve when precise plots are required */ |
||
145 | int found_size_command = 0; /* 1 = found size ; 2 = found xrange; 3 = found yrange: just to flag an error message */ |
||
146 | int object_cnt = 0; /*counter to identify the "onclick" ojects ; 0 is first object set onclick: reply[object_cnt]=1 when clicked ; otherwise reply[object_cnt]=0 ; object_cnt is only increased when another object is set again */ |
||
147 | int clock_cnt = 0; /* counts the amount of clocks used -> unique object clock%d */ |
||
148 | int boxplot_cnt = 0; |
||
149 | int drawxml_cnt = 0; |
||
150 | int numberline_cnt = 0; |
||
151 | int snap_to_points_cnt = 0; |
||
152 | int reply_precision = 100; /* used for precision of student answers / drawings */ |
||
153 | char *rotation_center = "null";/* needs to be removed... but is used for canvas CTX based rotation*/ |
||
154 | double rotationcenter[] = {0,0}; /* use for recalculating x/y values on rotation() */ |
||
155 | int use_animate = 0; /* used for jscurve / js parametric */ |
||
156 | int use_input_xy = 0; /* 1= input fields 2= textarea 3=calc y value*/ |
||
157 | size_t string_length = 0; /* measure the size of the user input fly-string */ |
||
18609 | bpr | 158 | double stroke_opacity = 0.95; /* use some opacity as default */ |
18552 | bpr | 159 | double fill_opacity = 0.5;/* use some opacity as default */ |
160 | char *URL = "http://localhost/images"; |
||
161 | memset(buffer,'\0',MAX_BUFFER); |
||
162 | void *tmp_buffer = ""; |
||
18615 | bpr | 163 | double res[10]; |
18552 | bpr | 164 | /* default writing a unzipped js-include file into wims getfile directory */ |
165 | char *w_wims_session = getenv("w_wims_session"); |
||
166 | if( w_wims_session == NULL || *w_wims_session == 0 ){canvas_error("Hmmm, your wims environment does not exist...\nCanvasdraw should be used within wims.");} |
||
167 | int L0=strlen(w_wims_session) + 21; |
||
168 | char *getfile_dir = my_newmem(L0); /* create memory to fit string precisely */ |
||
169 | snprintf(getfile_dir,L0, "../sessions/%s/getfile",w_wims_session);/* string will fit precisely */ |
||
170 | mode_t process_mask = umask(0); /* check if file exists */ |
||
171 | int result = mkdir(getfile_dir, S_IRWXU | S_IRWXG | S_IRWXO); |
||
172 | if( result == 0 || errno == EEXIST ){ |
||
173 | umask(process_mask); /* be sure to set correct permission */ |
||
174 | char *w_session = getenv("w_session"); |
||
175 | int L1 = (int) (strlen(w_session)) + find_number_of_digits(canvas_root_id) + 48; |
||
176 | getfile_cmd = my_newmem(L1); /* create memory to fit string precisely */ |
||
177 | snprintf(getfile_cmd,L1,"wims.cgi?session=%s&cmd=getfile&special_parm=%d.js",w_session,canvas_root_id);/* extension ".gz" is MANDATORY for webserver */ |
||
13306 | obado | 178 | /* write the include tag to html page:<script src="wims.cgi?session=%s&cmd=getfile&special_parm=11223344_js"></script> */ |
7614 | schaersvoo | 179 | /* now write file into getfile dir*/ |
14066 | bpr | 180 | char *w_wims_home = getenv("w_wims_home"); /* "/home/users/wims": we need absolute path for location */ |
7614 | schaersvoo | 181 | int L2 = (int) (strlen(w_wims_home)) + (int) (strlen(w_wims_session)) + find_number_of_digits(canvas_root_id) + 23; |
182 | char *location = my_newmem(L2); /* create memory to fit string precisely */ |
||
183 | snprintf(location,L2,"%s/sessions/%s/getfile/%d.js",w_wims_home,w_wims_session,canvas_root_id);/*absolute path */ |
||
184 | js_include_file = fopen(location,"w");/* open the file location for writing */ |
||
14066 | bpr | 185 | /* check on opening...if nogood: mount readonly? disk full? permissions not set correctly? */ |
186 | if(js_include_file == NULL){ canvas_error("SHOULD NOT HAPPEN: could not write to javascript include file...check your system logfiles !" );} |
||
7614 | schaersvoo | 187 | |
188 | /* ----------------------------------------------------- */ |
||
11997 | schaersvoo | 189 | |
18552 | bpr | 190 | /* while more lines to process */ |
7614 | schaersvoo | 191 | |
192 | while(!finished){ |
||
18552 | bpr | 193 | if(line_number>1 && found_size_command == 0 && use_tooltip != 2 ){canvas_error("command \"size xsize,ysize\" needs to come first ! ");} |
194 | type = get_token(infile); |
||
195 | done = FALSE; |
||
196 | /* |
||
197 | @ canvasdraw |
||
198 | @ Canvasdraw will try use the same basic syntax structure as flydraw |
||
18627 | bpr | 199 | @ General syntax <ul><li>The transparency of all objects can be controlled by command <a href="#opacity">opacity [0-255],[0,255]</a></li><li>Line width of any object can be controlled by command <a href="#linewidth">linewidth int</a></li><li>Any may be dashed by using keyword <a href="#dashed">dashed</a> before the object command.<br> the dashing type can be controled by command <a href="#dashtype">dashtype int,int</a>please note: dashing may have different spacing depending on the angle of the line<br>see https://wimsedu.info/?topic=dashed-arrows-not-dashed-in-canvasdraw</li><li>A fillable object can be set fillable by starting the object command with an ''f`` (like ''frect``,''fcircle``,''ftriangle`` ...) or by using the keyword <a href="#filled">filled</a> before the object command.<br>Non-solid filling (grid,hatch,diamond,dot,text) is provided using command <a href="#fillpattern">fillpattern a_pattern</a><br>note: do not use a <b>f</b> with this non-solid pattern filling.<br>For <a href="#filltoborder">filltoborder x0,y0,bordercolor,color</a> (fill a region around x0,y0 with color until a border of color borderolor is encountered) or <a href="#filltoborder">fill x0,y0,color</a> type filling (fill a region around x0,y0 with color until a border is encountered), there are non-solid pattern fill analogues:<ul><li><a href="#gridfill">gridfill x,y,dx,dy,color</a></li><li><a href="#hatchfill">hatchfill x,y,dx,dy,color</a></li><li><a href="#diamondfill">diamondfill x,y,dx,dy,color</a></li><li><a href="#dotfill">dotfill x,y,dx,dy,color</a></li><li><a href="#textfill">textfill x,y,color,sometext_or_char</a></li></ul></li><li>All draggable objects may have a <a href="#slider">slider</a> for translation / rotation; several objects may be translated / rotated by a single slider</li><li>A draggable object can be set draggable by a preceding command <a href="#drag">drag x/y/xy</a><br>The translation can be read by javascript:read_dragdrop();The replyformat is: object_number : x-orig : y-orig : x-drag : y-drag<br>The x-orig/y-orig will be returned in maximum precision (javascript float)...<br>the x-drag/y-drag will be returned in defined ''precision`` number of decimals<br>Multiple objects may be set draggable / clickable (no limit)<br>not all flydraw objects may be dragged / clicked<br>Only draggable / clickable objects will be scaled on <a href="#zoom">zoom</a> and will be translated in case of panning.</li><li>A ''onclick object`` can be set ''clickable`` by the preceding keyword <a href="#onclick">onclick</a><br>Not all flydraw objects can be set clickable</li><li><b>Remarks using a '';`` as command separator</b>. Commands with only numeric or color arguments may be using a '';`` as command separator (instead of a new line). Commands with a string argument may not use a '';`` as command separator.<br>These exceptions are not really straight forward... so keep this in mind.</li><li>Almost every <a href="#userdraw">userdraw object,color</a> or <a href="#multidraw">multidraw</a> command ''family`` may be combined with keywords <a href="#snaptogrid">"snaptogrid | xsnaptogrid | ysnaptogrid | snaptofunction</a> or command <code>snaptopoints x1,y1,x2,y2,...</code></li><li>Every draggable | onclick object may be combined with keywords <a href="#snaptogrid">snaptogrid | xsnaptogrid | ysnaptogrid | snaptofunction</a> or command <code>snaptopoints x1,y1,x2,y2,...</code></li><li>Almost every command for a single object has a multiple objects counterpart: <ul>general syntax rule:<li><code>object x1,y1,...,color</code></li><li><code>objects color,x1,y1,...</code></li></ul><li>All inputfields or textareas generated, can be styled individually using command <a href="#css">css some_css</a>: the fontsize used for labeling these elements can be controlled by command <a href="#fontsize">fontsize int</a> command <code>fontfamily</code> is <b>not</b> active for these elements.</li></ul> |
200 | @ If needed multiple interactive scripts (*) may be used in a single webpage.<br>A function <code>read_canvas()</code> and / or <code>read_dragdrop()</code> can read all interactive userdata from these images.<br>The global array <code>canvas_scripts</code>will contain all unique random "canvas_root_id" of the included scripts.<br>The included local javascript "read" functions ''read_canvas%d()`` and ''read_dragdrop%d()`` will have this ''%d = canvas_root_id``<br>e.g. canvas_scripts[0] will be the random id of the first script in the page and will thus provide a function<br><code>fun = eval("read_canvas"+canvas_scripts[0])</code> to read user based drawings / inputfield in this first image.<br>The read_dragdrop is analogue.<br>If the default reply formatting is not suitable, use command <a href='#replyformat'>replyformat</a> to format the replies for an individual canvas script,<br>To read all user interactions from all included canvas scripts, use something like:<br><code>function read_all_canvas_images(){<br> var script_len = canvas_scripts.length;<br> var draw_reply = "";<br> var found_result = false;<br> for(var p = 0 ; p < script_len ; p++){<br> var fun = eval("read_canvas"+canvas_scripts[p]);<br> if( typeof fun === 'function'){<br> var result = fun();<br> if( result && result.length != 0){<br> if(script_len == 1 ){.return result;};<br> found_result = true;<br> draw_reply = draw_reply + result + "newline";<br> };<br> };<br> };<br> if( found_result ){return draw_reply;}else{return null;};<br>};</code> <br>(*) Note: the speed advantage over <em>canvas-do-it-all</em> libraries is reduced to zero, when multiple canvasdraw scripts are present in a single page... For example a typical canvasdraw script is between 5 and 40 kB...a large library like JSXgraph is approx 600 kB. In these cases it would be much faster to load a static general HTML5 canvas javascript draw library and parse it multiple raw fly instructions. |
||
201 | @ Canvasdraw can be used to paint a html5 bitmap image by generating a tailor-made javascript include file: providing only the js-functionality needed to perform the job, thus ensuring a minimal strain on the client browser (unlike some popular ''canvas-do-it-all`` libraries, who have proven to be not suitable for low-end computers found in schools...) |
||
18552 | bpr | 202 | @ You can check the javascript reply format in the wims tool <a href="http://localhost/wims/wims.cgi?lang=en&module=tool/directexec">direct exec</a> |
203 | @ For usage within OEF (without anstype ''draw``), something like this (a popup function plotter) will work:<br><code>\\text{popup_grapher=wims(exec canvasdraw <br>popup<br>size 400,400<br>xrange -10,10<br>yrange -10,10<br>axis<br>axisnumbering<br>opacity 100,100<br>grid 2,2,grey,2,2,6,black<br>snaptogrid<br>linewidth 2<br>jsplot red,5*sin(1/x)<br>strokecolor green<br>functionlabel f(x)=<br>userinput function<br>mouse blue,22<br>)<br>}<br>\\statement{<br>\\popup_grapher<br>}</code>. |
||
18627 | bpr | 204 | @ Be aware that older browsers will probably not work correctly. no effort has been undertaken to add glue code for older browsers !! In any case it is not wise to use older browsers...not just for canvasdraw. |
18552 | bpr | 205 | @ Be aware that combining several different objects and interactivity may lead to problems. |
206 | @ If you find flaws, errors or other incompatibilities -not those mentioned in this document- send <a href='mailto:jm.evers-at-schaersvoorde.nl'>me</a> an email with screenshots and the generated javascript include file. |
||
18627 | bpr | 207 | @ There is limited support for touch devices: touchstart, touchmove and touchend in commands <a href="#userdraw">userdraw primitives </a>, <a href="#multidraw">multidraw primitives </a>, <a href="#protractor">protractor</a>, <a href="#ruler">ruler</a> and probably a few others... Only single finger gestures are supported (for now). The use of a special pen is advised for interactive drawing on touch devices. For more accurate user-interaction (numeric, eg keyboard driven drawings) with canvasdraw on touch devices: use the command family <a href="#userinput_xy">userinput</a>. |
18552 | bpr | 208 | */ |
209 | switch(type){ |
||
210 | case END:finished = 1;done = TRUE;break; |
||
211 | case 0:sync_input(infile);break; |
||
212 | case AFFINE: |
||
213 | /* |
||
18556 | bpr | 214 | @ affine a,b,c,d,tx,ty |
215 | @ defines a transformation matrix for subsequent objects |
||
216 | @ use keyword <a href='#killaffine'>killaffine</a> to end the transformation...the next objects will be drawn in the original x/y-range |
||
217 | @ a: Scales the drawings horizontally |
||
218 | @ b: Skews the drawings horizontally |
||
219 | @ c: Skews the drawings vertically |
||
220 | @ d: Scales the drawings vertically |
||
221 | @ tx: Moves the drawings horizontally in xrange coordinate system |
||
222 | @ ty: Moves the drawings vertically in yrange coordinate system |
||
223 | @ the data precision may be set by preceding command ''precision int`` |
||
224 | @ <b>note</b>: not all affine operations on canvasdraw objects will be identical to flydraw's behaviour. Make sure to check ! |
||
225 | @%affine%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%#use larger linewith to improve selecting a draggable object !%linewidth 4%drag xy%frect 0,5,3,3,red%affine cos(pi/4),sin(pi/4),-cos(pi/2),sin(pi/2),-5,-5%drag xy%frect 0,5,3,3,red |
||
226 | @%affine+latex%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%strokecolor blue%fontfamily 42px Arial%centered%drag xy%latex 5,5,\\frac{123}{\\pi^{234}}%affine cos(pi/4),sin(pi/4),-cos(pi/2),sin(pi/2),-5,-5%drag xy%latex 5,5,\\frac{123}{\\pi^{234}} |
||
18552 | bpr | 227 | */ |
228 | for(i = 0 ; i<6;i++){ |
||
229 | switch(i){ |
||
230 | case 0: affine_matrix[0] = get_real(infile,0);break; |
||
231 | case 1: affine_matrix[1] = get_real(infile,0);break; |
||
232 | case 2: affine_matrix[2] = get_real(infile,0);break; |
||
233 | case 3: affine_matrix[3] = get_real(infile,0);break; |
||
234 | case 4: affine_matrix[4] = get_real(infile,0);break; |
||
235 | case 5: affine_matrix[5] = get_real(infile,1); |
||
236 | use_affine = TRUE; |
||
237 | break; |
||
238 | default: break; |
||
239 | } |
||
240 | } |
||
241 | break; |
||
14394 | schaersvoo | 242 | case ALLOW_DUPLICATES: |
18556 | bpr | 243 | /* |
244 | @ duplicates || allowdups |
||
245 | @ keyword (no arguments) |
||
246 | @ only useful in case of a <a href="#multidraw">multidraw</a> student reply. |
||
247 | @ only useful in default <a href="#replyformat">replyformat</a> (eg in case of a not specified replyformat). |
||
248 | @ if set, duplicate (x:y) coordinates will not be removed from the student reply. |
||
249 | @ technical: a javascript variable "allow_duplicate_answer = 1;" is declared. |
||
250 | @ default for command multidraw is: removal of duplicates. |
||
251 | */ |
||
18552 | bpr | 252 | fprintf(js_include_file,"var allow_duplicate_answers = 1;"); |
253 | break; |
||
254 | case ANGLE: |
||
18556 | bpr | 255 | /* |
256 | @ angle xc,yc,width,start_angle,end_angle,color |
||
257 | @ width is in x-range |
||
258 | @ angles are in degrees |
||
259 | @ not compatible with ''flydraw`` |
||
260 | @ will zoom in/out |
||
261 | @ may be set onclick or drag&drop |
||
262 | @ if angle size is controlled by command <a href='#slider'>slider</a>, use radians to set limits of slider |
||
263 | @ ''angle`` and <a href="#arc">arc</a> are exceptions in case of sliders...they are always active (e.g. not click-activated) |
||
264 | @%angle%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor orange%angle 0,0,4,10,135,blue |
||
265 | @%angle_slider%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 3%strokecolor blue%slider -2*pi,2*pi,260,28,angle active degree,blue arrow%arrow 0,0,8,0,8,blue%fillpattern diamond%angle 0,0,2,0,0,blue%killslider%strokecolor red%slider -2*pi,2*pi,260,28,angle active radian,red arrow%arrow 0,1,8,1,8,red%fillpattern dot%angle 0,1,2,0,0,red |
||
266 | */ |
||
18552 | bpr | 267 | for(i=0;i<7;i++){ |
268 | switch(i){ |
||
269 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
270 | case 1:double_data[1] = get_real(infile,0); |
||
271 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
272 | if(use_affine == TRUE ){ transform(2,2);} |
||
273 | break; /* y-values */ |
||
274 | case 2:double_data[2] = get_real(infile,0);break; /* width x-range ! */ |
||
275 | case 3:double_data[3] = 0.0174532925*(get_real(infile,0) - angle);break; /* start angle in degrees -> radians */ |
||
276 | case 4:double_data[4] = 0.0174532925*(get_real(infile,0) - angle);break; /* end angle in degrees -> radians */ |
||
277 | case 5:stroke_color = get_color(infile,1);/* name or hex color */ |
||
278 | if( use_slider != -1 ){ onclick = 3; }/* always active in case of slider */ |
||
279 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 280 | tmp_buffer=my_newmem(MAX_BUFFER); |
281 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,17,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[0],decimals,double_data[1],decimals,double_data[1],decimals,double_data[2],decimals,double_data[2],decimals,double_data[3],decimals,double_data[4],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 282 | add_to_buffer(tmp_buffer); |
283 | dragstuff[17] = 1; |
||
284 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
285 | if(onclick != 0){object_cnt++;}/* object_cnt++;*/ |
||
286 | break; |
||
287 | } |
||
288 | } |
||
289 | break; |
||
290 | case ANIMATE: |
||
291 | /* |
||
18556 | bpr | 292 | @ animate |
293 | @ keyword |
||
294 | @ if set, it will animate a point on a curve |
||
295 | @ all other canvas object or group of objects (like lines,circles,rects,points...images,svg,latex,mathml etc)<br>may be animated using command <a href='#slider'>slider</a> with keyword 'anim' |
||
18627 | bpr | 296 | @ the animated point is a filled rectangle ; adjust color with command <code>fillcolor colorname/hexnumber</code> |
18556 | bpr | 297 | @ use linewidth to adjust size of the points |
298 | @ will animate a point on -only- the next <a href='#jsplot'>jsplot/jscurve command</a>. Only a single call to <code>animate</code> is allowed...in case of multiple <code>animate</code> keywords, only the last one is valid |
||
299 | @ only usable in combination with command <a href='#jsplot'>jsplot</a> (normal functions or parametric) |
||
300 | @ moves repeatedly from <a href='#xrange'>xmin to xmax</a> or in case of a parametric function from <a href='#trange'>tmin to tmax</a> |
||
301 | @ use commands <a href='#multilinewidth'>multilinewidth</a>, <a href='#multistrokecolor'>multistrokecolor</a> etc in case of multiple animated functions.<br>use multiple functions as argument in a single call to <a href='#jsplot'>jsplot color,fun1,fun2,fun3...fun_n</a> |
||
302 | @%animate_1%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 100%linewidth 4%fillcolor red%animate%trange -2*pi,2*pi%linewidth 1%opacity 255,50%canvastype 100%fill 1.2,1.2,red%canvastype 101%fill -1.2,-1.2,blue%jsplot blue,7*cos(x),5*sin(2*x) |
||
303 | @%animate_2%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 100%linewidth 4%fillcolor red%animate%trange -2*pi,2*pi%linewidth 1%opacity 255,50%canvastype 100%fill 1.2,1.2,red%canvastype 101%fill -1.2,-1.2,blue%multistrokecolors blue,blue,green,green,orange,orange%multilinewidth 2,2,3,3,1,1%jsplot blue,7*cos(x),5*sin(2*x),9*sin(x),5*cos(x),x^2,x |
||
18552 | bpr | 304 | */ |
305 | use_animate++; |
||
306 | if( use_animate == 1 ){ |
||
307 | fprintf(js_include_file,"\nvar trace_canvas = create_canvas%d(%d,xsize,ysize);\ |
||
308 | var trace_ctx = trace_canvas.getContext('2d');\ |
||
309 | trace_ctx.fillStyle = 'rgba(%s,%f)';\ |
||
310 | trace_ctx.strokeStyle = 'rgba(%s,%f)';\ |
||
311 | trace_ctx.lineWidth = %d;var anim_pos = 0;\n\ |
||
312 | function animate_this(){\ |
||
313 | var sync;\ |
||
314 | var synchrone = Math.floor(animation_steps/animation_funs);\ |
||
315 | trace_ctx.clearRect(0,0,xsize,ysize);\ |
||
316 | for(var p=0; p<animation_funs;p++){\ |
||
317 | sync = p*synchrone;\ |
||
318 | trace_ctx.fillRect(x_anim_points[sync+anim_pos]-%d, y_anim_points[sync+anim_pos]-%d,%d,%d);\ |
||
319 | };\ |
||
320 | setTimeout(function(){\ |
||
321 | requestAnimationFrame(animate_this); anim_pos++;}, 50\ |
||
322 | );\ |
||
323 | if(anim_pos >= animation_steps){anim_pos = 0;};\ |
||
324 | };",canvas_root_id,ANIMATE_CANVAS,fill_color,fill_opacity,stroke_color,stroke_opacity,line_width,line_width,line_width,2*line_width,2*line_width); |
||
325 | } else { |
||
326 | canvas_error("animate can only be used once<br>multiple curves may be animated using something like:<br>jsplot red,sin(x),cos(x),x^2,sin(2*x)"); |
||
327 | } |
||
328 | break; |
||
329 | case ARC: |
||
330 | /* |
||
18556 | bpr | 331 | @ arc xc,yc,x-width,y-height,start_angle,end_angle,color |
332 | @ may be set ''onclick`` or ''drag xy`` |
||
333 | @ compatible with ''flydraw`` |
||
334 | @ attention: width & height in x/y-range |
||
335 | @ for arrow hats on an arc, see command <a href='#arcarrow'>arcarrow or arrowarc</a> |
||
336 | @ better use command <a href='#angle'>angle</a> for use with a <a href='#slider'>slider</a> |
||
337 | @%arc%size 400,400%xrange -10,10%yrange -10,10%arc 0,0,4,4,10,135,red |
||
338 | @%arc_filled%size 400,400%xrange -10,10%yrange -10,10%opacity 255,60%filled%fillcolor green%arc 0,0,4,4,10,135,red |
||
18552 | bpr | 339 | */ |
18641 | bpr | 340 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 341 | for(i=0;i<7;i++){ |
342 | switch(i){ |
||
343 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
344 | case 1:double_data[1] = get_real(infile,0); |
||
345 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
346 | if(use_affine == TRUE ){ transform(4,2);} |
||
347 | break; /* y-values */ |
||
348 | case 2:double_data[2] = get_real(infile,0);break; /* width x-range no pixels ! */ |
||
349 | case 3:double_data[3] = get_real(infile,0); |
||
350 | break; /* height y-range no pixels ! */ |
||
351 | case 4:double_data[4] = get_real(infile,0) - angle ;break; /* start angle in degrees */ |
||
352 | case 5:double_data[5] = get_real(infile,0) - angle;break; /* end angle in degrees */ |
||
353 | case 6:stroke_color = get_color(infile,1);/* name or hex color */ |
||
354 | /* in Shape library: |
||
355 | x[0] = x[1] = xc = double_data[0] |
||
356 | y[0] = y[1] = yc = double_data[1] |
||
357 | w[0] = width = double_data[2] |
||
358 | w[1] = height = double_data[3] |
||
359 | h[0] = start_angle = double_data[4] |
||
360 | h[1] = end_angle = double_data[5] |
||
361 | */ |
||
18555 | bpr | 362 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
363 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 364 | |
365 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
366 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,12,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[0],decimals,double_data[1],decimals,double_data[1],decimals,double_data[2],decimals,double_data[3],decimals,double_data[4],decimals,double_data[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18555 | bpr | 367 | add_to_buffer(tmp_buffer);reset(); |
368 | dragstuff[12] = 1; |
||
369 | if(onclick != 0){object_cnt++;} |
||
370 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
18552 | bpr | 371 | break; |
372 | } |
||
373 | } |
||
374 | break; |
||
375 | case ARCARROW: |
||
376 | /* |
||
18556 | bpr | 377 | @ arrowarc xc,yc,x-width,y-height,start_angle,end_angle,color,type |
378 | @ alternative: arcarrow |
||
379 | @ uses same syntax as <a href='#arc'>arc</a> |
||
380 | @ for arrow hat: type = 1 : right<br>type = 2 : left<br>type = 3 : left&right |
||
381 | @ if the default arrow hat/head is not satisfactory , the size of the arrow may be set with command <a href='#arrowhead'>arrowhead</a> |
||
382 | @ no other arrow types are implemented...yet |
||
383 | @ may be set draggable or onclick |
||
384 | @ attention: when width ad height are very different, the arrow hat is not drawn correctly. This is a flaw and not a feature...(for now: too much calculations to correct) |
||
385 | @%arcarrow%size 400,400%xrange -10,10%yrange -10,10%noreset%onclick%arcarrow 0,0,7,7,50,275,blue,3%arcarrow 0,0,8,8,50,275,red,2%arcarrow 0,0,9,9,50,275,green,1 |
||
18552 | bpr | 386 | */ |
387 | for(i=0;i<8;i++){ |
||
388 | switch(i){ |
||
389 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
390 | case 1:double_data[1] = get_real(infile,0); |
||
391 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
392 | if(use_affine == TRUE ){ transform(4,2);} |
||
393 | break; /* y-values */ |
||
394 | case 2:double_data[2] = get_real(infile,0);break; /* width x-range no pixels ! */ |
||
395 | case 3:double_data[3] = get_real(infile,0); |
||
396 | break; /* height y-range no pixels ! */ |
||
397 | case 4:double_data[4] = get_real(infile,0) - angle ;break; /* start angle in degrees */ |
||
398 | case 5:double_data[5] = get_real(infile,0) - angle;break; /* end angle in degrees */ |
||
399 | case 6:stroke_color = get_color(infile,0);/* name or hex color */ |
||
400 | break; |
||
401 | case 7:int_data[0] = (int) get_real(infile,1); |
||
402 | switch(int_data[0]){ |
||
403 | case 1: int_data[1] = 24;break; /* right */ |
||
404 | case 2: int_data[1] = 25;break; /* left */ |
||
405 | case 3: int_data[1] = 26;break; /* left&right */ |
||
406 | default:int_data[1] = 24;break; |
||
407 | } |
||
408 | if(int_data[0] == 1 ){int_data[1] = 24;} |
||
409 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
410 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 411 | |
412 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
413 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"var arrow_head = %d;dragstuff.addShape(new Shape(%d,%d,%d,%d,%d,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",arrow_head,drag_type,object_cnt,onclick,use_snap,int_data[1],decimals,double_data[0],decimals,double_data[0],decimals,double_data[1],decimals,double_data[1],decimals,double_data[2],decimals,double_data[3],decimals,double_data[4],decimals,double_data[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 414 | add_to_buffer(tmp_buffer); |
415 | dragstuff[int_data[1]] = 1; |
||
416 | if(onclick != 0){object_cnt++;} |
||
417 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
418 | js_function[JS_ARROWHEAD] = 1; |
||
419 | reset(); |
||
420 | } |
||
421 | } |
||
422 | break; |
||
423 | case ARROW: |
||
424 | /* |
||
425 | @ arrow x1,y1,x2,y2,h,color |
||
426 | @ alternative: vector |
||
427 | @ draw a single headed arrow / vector from (x1:y1) to (x2:y2)<br>with arrowhead size h in px and in color ''color`` |
||
428 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
429 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
430 | @%arrow_drag%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 2%drag xy%arrow 0,0,4,3,8,blue%drag xy%arrow 0,0,-4,3,8,green%drag xy%arrow 0,0,4,-3,8,orange%drag xy%arrow 0,0,-4,-3,8,cyan |
||
431 | @%arrow_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%%onclick%arrow 0,0,4,4,8,blue%onclick%arrow 0,0,-4,5,8,green%onclick%arrow 0,0,4,-6,8,orange%onclick%arrow 0,0,-4,-2,8,cyan |
||
432 | */ |
||
433 | for(i=0;i<6;i++){ |
||
434 | switch(i){ |
||
435 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
436 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
437 | case 2: double_data[2] = get_real(infile,0);break; /* x */ |
||
438 | case 3: double_data[3] = get_real(infile,0);break; /* y */ |
||
439 | case 4: arrow_head = (int) get_real(infile,0);break;/* h */ |
||
440 | case 5: stroke_color = get_color(infile,1);/* name or hex color */ |
||
441 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
442 | if(use_affine == TRUE ){ transform(4,2);} |
||
443 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
444 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 445 | tmp_buffer=my_newmem(MAX_BUFFER); |
446 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,8,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],arrow_head,arrow_head,arrow_head,arrow_head,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 447 | if(onclick != 0){object_cnt++;} |
448 | /* object_cnt++;*/ |
||
449 | add_to_buffer(tmp_buffer);reset(); |
||
450 | dragstuff[8] = 1; |
||
451 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
452 | break; |
||
453 | } |
||
454 | } |
||
455 | break; |
||
456 | case ARROWS: |
||
457 | /* |
||
458 | @ arrows color,head (px),x1,y1,x2,y2...x_n,y_n |
||
459 | @ alternative: vectors |
||
460 | @ draw single headed arrows / vectors from (x1:y1) to (x2:y2) ... (x3:y3) to (x4:y4) etc ... in color 'color' |
||
461 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
462 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
||
463 | @%arrows_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%arrows red,8,0,0,4,3,0,0,2,4,0,0,-2,4,0,0,-3,-4,0,0,3,-2% |
||
464 | @%arrows_drag%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag xy%arrows red,8,0,0,4,3,0,0,2,4,0,0,-2,4,0,0,-3,-4,0,0,3,-2% |
||
465 | @%arrows_drag_slider%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag xy%# Click arrow(s) to activate %slider 0,2*pi,300,30,angle degrees,Rotate%slider -5,5*pi,300,30,x display,move in x-direction%slider -10,10*pi,300,30,y display,move in y-direction%arrows red,8,0,0,4,3,0,0,2,4,0,0,-2,4,0,0,-3,-4,0,0,3,-2% |
||
466 | */ |
||
467 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
468 | fill_color = stroke_color; |
||
469 | arrow_head = (int) get_real(infile,0);/* h */ |
||
470 | i=0; |
||
471 | while( ! done ){ /* get next item until EOL*/ |
||
472 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
473 | if(i%2 == 0 ){ |
||
474 | double_data[i] = get_real(infile,0); /* x */ |
||
475 | } else { |
||
476 | double_data[i] = get_real(infile,1); /* y */ |
||
477 | } |
||
478 | i++; |
||
479 | } |
||
480 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
481 | if( use_affine == TRUE ){ transform(i-1,2);} |
||
482 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
483 | decimals = find_number_of_digits(precision); |
||
484 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18557 | bpr | 485 | tmp_buffer=my_newmem(MAX_BUFFER); |
486 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,8,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],arrow_head,arrow_head,arrow_head,arrow_head,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 487 | add_to_buffer(tmp_buffer); |
488 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
489 | } |
||
490 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
491 | dragstuff[8] = 1; |
||
492 | reset(); |
||
493 | break; |
||
494 | case ARROW2: |
||
495 | /* |
||
496 | @ arrow2 x1,y1,x2,y2,h,color |
||
497 | @ draw a double headed arrow/vector from (x1:y1) to (x2:y2)<br>with arrowhead size h in px and in color ''color`` |
||
498 | @ use command <code>arrowhead int</code> to adjust the arrow head size |
||
499 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
500 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
501 | @%arrow2%size 400,400%xrange -10,10%yrange -10,10%drag xy%arrow2 0,0,4,3,8,blue% |
||
502 | */ |
||
503 | for(i=0;i<6;i++){ |
||
504 | switch(i){ |
||
505 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
506 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
507 | case 2: double_data[2] = get_real(infile,0);break; /* x */ |
||
508 | case 3: double_data[3] = get_real(infile,0);break; /* y */ |
||
509 | case 4: arrow_head = (int) get_real(infile,0);break;/* h */ |
||
510 | case 5: stroke_color = get_color(infile,1);/* name or hex color */ |
||
511 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
512 | if( use_affine == 1 ){ transform(4,2);} |
||
513 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
514 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 515 | tmp_buffer=my_newmem(MAX_BUFFER); |
516 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,10,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],arrow_head,arrow_head,arrow_head,arrow_head,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 517 | add_to_buffer(tmp_buffer); |
518 | if(onclick != 0){object_cnt++;}/* object_cnt++;*/ |
||
519 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
520 | dragstuff[10] = 1; |
||
521 | reset(); |
||
522 | break; |
||
523 | } |
||
524 | } |
||
525 | break; |
||
526 | case ARROWS2: |
||
527 | /* |
||
528 | @ arrows2 color,head (px),x1,y1,x2,y2...x_n,y_n |
||
529 | @ draw double headed arrows / vectors from (x1:y1) to (x2:y2) ... (x3:y3) to (x4:y4) etc ... in color ''color`` |
||
530 | @ use command <code>linewidth int</code> to adjust thickness of the arrows |
||
531 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
||
532 | @%arrows2%size 400,400%xrange -10,10%yrange -10,10%onclick%arrows2 red,8,0,0,4,3,1,1,2,4,2,2,-2,4,3,3,-3,-4,0,0,3,-2% |
||
533 | */ |
||
534 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
535 | fill_color = stroke_color; |
||
536 | arrow_head = (int) get_real(infile,0);/* h */ |
||
537 | i=0; |
||
538 | while( ! done ){ /* get next item until EOL*/ |
||
539 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
540 | if(i%2 == 0 ){ |
||
541 | double_data[i] = get_real(infile,0); /* x */ |
||
542 | } else { |
||
543 | double_data[i] = get_real(infile,1); /* y */ |
||
544 | } |
||
545 | i++; |
||
546 | } |
||
547 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
548 | if( use_affine == 1 ){ transform(i-1,2);} |
||
549 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
8386 | schaersvoo | 550 | |
18552 | bpr | 551 | decimals = find_number_of_digits(precision); |
552 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18557 | bpr | 553 | tmp_buffer=my_newmem(MAX_BUFFER); |
554 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,10,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],arrow_head,arrow_head,arrow_head,arrow_head,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 555 | add_to_buffer(tmp_buffer); |
556 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
557 | } |
||
558 | dragstuff[10] = 1; |
||
559 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
560 | reset(); |
||
561 | break; |
||
562 | case ARROWHEAD: |
||
563 | /* |
||
564 | @ arrowhead int |
||
565 | @ default 8 (pixels) |
||
566 | */ |
||
567 | arrow_head = (int) (get_real(infile,1)); |
||
568 | break; |
||
569 | case AUDIO: |
||
570 | /* |
||
571 | @ audio x,y,w,h,loop,visible,audiofile location |
||
572 | @ x,y: left top corner of audio element (in xrange / yrange) |
||
573 | @ w,y: width and height in pixels |
||
574 | @ loop: 0 or 1 ( 1 = loop audio fragment) |
||
575 | @ visible: 0 or 1 (1 = show controls) |
||
576 | @ audio format may be in *.mp3 or *.ogg |
||
577 | @ If you are using *.mp3: be aware that FireFox will not (never) play this ! (Pattented format) |
||
578 | @ if you are using *.ogg: be aware that Microsoft based systems not support it natively |
||
579 | @ To avoid problems supply both types (mp3 and ogg) of audiofiles.<br>the program will use both as source tag |
||
580 | */ |
||
581 | js_function[DRAW_AUDIO] = 1; |
||
582 | for(i=0;i<7;i++){ |
||
583 | switch(i){ |
||
584 | case 0: int_data[0] = x2px(get_real(infile,0)); break; /* x in x/y-range coord system -> pixel */ |
||
585 | case 1: int_data[1] = y2px(get_real(infile,0)); break; /* y in x/y-range coord system -> pixel */ |
||
586 | case 2: int_data[2] = (int) (get_real(infile,0)); break; /* pixel width */ |
||
587 | case 3: int_data[3] = (int) (get_real(infile,0)); break; /* height pixel height */ |
||
588 | case 4: int_data[4] = (int) (get_real(infile,0)); if(int_data[4] != TRUE){int_data[4] = FALSE;} break; /* loop boolean */ |
||
589 | case 5: int_data[5] = (int) (get_real(infile,0)); if(int_data[5] != TRUE){int_data[5] = FALSE;} break; /* visible boolean */ |
||
590 | case 6: |
||
591 | temp = get_string(infile,1); |
||
592 | if( strstr(temp,".mp3") != 0 ){ temp = str_replace(temp,".mp3","");} |
||
593 | if( strstr(temp,".ogg") != 0 ){ temp = str_replace(temp,".ogg","");} |
||
18557 | bpr | 594 | tmp_buffer=my_newmem(MAX_BUFFER); |
595 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_audio(%d,%d,%d,%d,%d,%d,%d,\"%s.ogg\",\"%s.mp3\");\n", canvas_root_id, int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],int_data[5],temp,temp)); |
||
18552 | bpr | 596 | add_to_buffer(tmp_buffer); |
597 | break; |
||
598 | default:break; |
||
599 | } |
||
600 | } |
||
601 | reset(); |
||
602 | break; |
||
603 | case AXIS_NUMBERING: |
||
604 | /* |
||
18556 | bpr | 605 | @ axisnumbering |
606 | @ keyword (no arguments required) |
||
607 | @ for special numbering of x-axis or y-axis see grid related commands <a href="#axis">axis</a> <a href="#xaxis">xaxis</a>, <a href="#xaxisup">xaxisup</a>, <a href="#noxaxis">noxaxis</a>, <a href="#yaxis">yaxis</a>, <a href="#yaxisup">yaxisup</a>, <a href="#noyaxis">noyaxis</a> |
||
608 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
18552 | bpr | 609 | */ |
610 | use_axis_numbering++; |
||
611 | break; |
||
612 | case AXIS: |
||
613 | /* |
||
18556 | bpr | 614 | @ axis |
615 | @ keyword (no arguments required) |
||
616 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
8386 | schaersvoo | 617 | |
18552 | bpr | 618 | */ |
619 | use_axis = TRUE; |
||
620 | break; |
||
621 | case BARCHART: |
||
622 | /* |
||
623 | @ barchart x_1:y_1:color_1:x_2:y_2:color_2:...x_n:y_n:color_n |
||
624 | @ may <b>only</b> to be used together with command <a href='#grid'>grid</a> |
||
625 | @ can be used together with freestyle x-axis/y-axis texts: see commands <a href='#xaxis'>xaxis</a>,<a href='#xaxisup'>xaxisup</a> and <a href='#yaxis'>yaxis</a> |
||
626 | @ use command <a href='#legend'>legend</a> to provide an optional legend in right-top-corner |
||
627 | @ multiple barchart command may be used in a single script |
||
628 | @ also see command <a href='#piechart'>piechart</a> |
||
629 | @ note: your arguments are not checked by canvasdraw: use your javascript console in case of trouble... |
||
630 | @%barchart%size 400,400%xrange -1,10%yrange -2,14%legend legend Z:legend A:this is B:C:D:E:F:G:H:X%legendcolors green:red:orange:lightblue:cyan:gold:purple:darkred:yellow:lightgreen%xaxis 0:Z:1:A:2:B:3:C:4:D:5:E:6:F:7:G:8:H:9:X%noyaxis%precision 1%fontfamily bold 15px Arial%grid 1,1,white%barchart 0:5.5:green:2:5.5:red:4:6.5:orange:6:8:lightblue:8:11:cyan:1:5.5:gold:3:9:purple:5:4:darkred:7:7:yellow:9:1:lightgreen%mouse red,14 |
||
631 | */ |
||
632 | temp = get_string(infile,1); |
||
633 | if( strstr( temp,":" ) != 0 ){ temp = str_replace(temp,":","\",\""); } |
||
634 | fprintf(js_include_file,"var barchart_%d = [\"%s\"];",barchart_cnt,temp); |
||
635 | barchart_cnt++; |
||
636 | reset(); |
||
637 | break; |
||
638 | case BEZIER: |
||
639 | /* |
||
640 | @ bezier color,x_start,y_start,x_first,y_first,x_second,y_second,x_end,y_end |
||
641 | @ draw a bezier curve between points, starting from (x_start:y_start) |
||
642 | @ can <b>not</b> be dragged or set onclick |
||
643 | */ |
||
644 | js_function[DRAW_BEZIER] = 1; |
||
645 | decimals = find_number_of_digits(precision); |
||
646 | for(i = 0 ; i < 9; i++){ |
||
647 | switch(i){ |
||
648 | case 0: stroke_color = get_color(infile,0);break; |
||
649 | case 1: double_data[0] = get_real(infile,0);break;/* start x */ |
||
650 | case 2: double_data[1] = get_real(infile,0);break;/* start y */ |
||
651 | case 3: double_data[2] = get_real(infile,0);break;/*The x-coordinate of the first Bézier control point */ |
||
652 | case 4: double_data[3] = get_real(infile,0);break;/*The y-coordinate of the first Bézier control point */ |
||
653 | case 5: double_data[4] = get_real(infile,0);break;/*The x-coordinate of the second Bézier control point */ |
||
654 | case 6: double_data[5] = get_real(infile,0);break;/*The y-coordinate of the second Bézier control point */ |
||
655 | case 7: double_data[6] = get_real(infile,0);break;/*The x-coordinate of the Bézier end point */ |
||
656 | case 8: double_data[7] = get_real(infile,1);/*The y-coordinate of the Bézier end point */ |
||
657 | if(use_rotate == TRUE ){rotate(8,angle,rotationcenter,2);} |
||
658 | if(use_affine == TRUE ){ transform(2,5);} |
||
18557 | bpr | 659 | tmp_buffer=my_newmem(MAX_BUFFER); |
660 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"draw_bezier(%d,%d,[%f,%f,%f,%f,%f,%f,%f,%f],\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.2f);",STATIC_CANVAS,line_width,double_data[0],double_data[1],double_data[2],double_data[3],double_data[4],double_data[5],double_data[6],double_data[7],fill_color,fill_opacity,stroke_color,stroke_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle)); |
||
18552 | bpr | 661 | add_to_buffer(tmp_buffer); |
662 | break; |
||
663 | default: break; |
||
664 | } |
||
665 | } |
||
666 | reset(); |
||
667 | break; |
||
668 | case BGCOLOR: |
||
669 | /* |
||
18556 | bpr | 670 | @ bgcolor colorname or #hex |
671 | @ use this color as background of the "div" containing the canvas(es) |
||
672 | @%bgcolor%size 400,400%xrange -10,10%yrange -10,10%bgcolor lightblue |
||
18552 | bpr | 673 | */ |
674 | /* [255,255,255]*/ |
||
675 | bgcolor = get_string(infile,1); |
||
676 | if(strstr(bgcolor,"#") == NULL){ /* convert colorname -> #ff00ff */ |
||
677 | int found = 0; |
||
678 | for( i = 0; i < NUMBER_OF_COLORNAMES ; i++ ){ |
||
679 | if( strcmp( colors[i].name , bgcolor ) == 0 ){ |
||
680 | bgcolor = colors[i].hex; |
||
681 | found = 1; |
||
682 | break; |
||
683 | } |
||
684 | } |
||
685 | if(found == 0){canvas_error("your bgcolor is not in my rgb.txt data list: use hexcolor...something like #a0ffc4");} |
||
686 | } |
||
687 | fprintf(js_include_file,"/* set background color of canvas div */\ncanvas_div.style.backgroundColor = \"%s\";canvas_div.style.opacity = %f;\n",bgcolor,fill_opacity); |
||
688 | break; |
||
689 | case BGIMAGE: |
||
690 | /* |
||
18556 | bpr | 691 | @ bgimage image_location |
692 | @ use an image as background; technical: we use the background of ''canvas_div`` |
||
693 | @ the background image will be resized to match "width = xsize" and "height = ysize" |
||
694 | @%bgimage%size 400,400%xrange -10,10%yrange -10,10%bgimage https://wims.unice.fr/wims/gifs/en.gif |
||
18552 | bpr | 695 | */ |
696 | URL = get_string(infile,1); |
||
697 | fprintf(js_include_file,"/* set background image to canvas div */\ncanvas_div.style.backgroundImage = \"url(%s)\";canvas_div.style.backgroundSize = \"%dpx %dpx\";\n",URL,xsize,ysize); |
||
698 | break; |
||
699 | case BLINK: |
||
700 | /* |
||
18556 | bpr | 701 | @ blink time(seconds) |
702 | @ NOT IMPLEMETED -YET |
||
18552 | bpr | 703 | */ |
704 | break; |
||
705 | case BOXPLOT: |
||
706 | /* |
||
707 | @ boxplot x_or_y,box-height_or_box-width,position,min,Q1,median,Q3,max |
||
708 | @ example:<br><code>xrange 0,300<br>yrange 0,10<br>boxplot x,4,8,120,160,170,220,245</code><br>meaning: create a boxplot in x-direction, with height 4 (in yrange) and centered around line y=8 |
||
709 | @ example:<br><code>xrange 0,10<br>yrange 0,300<br>boxplot y,4,8,120,160,170,220,245</code><br>meaning: create a boxplot in y-direction, with width 4 (in xrange) and centered around line x=8 |
||
710 | @ use command <a href='#filled'>filled</a> to fill the box<br><b>note:</b> the strokecolor is used for filling Q1, the fillcolor is used for filling Q3 |
||
711 | @ use command <a href='#fillpattern'>fillpattern some_pattern</a> to use a (diamond for Q1, hatch for Q3) pattern. |
||
18627 | bpr | 712 | @ use command <a href='#opacity'>opacity</a> to adjust fill_opacity of stroke and fill colors |
18552 | bpr | 713 | @ use command <a href='#legend'>legend</a> to automatically create a legend <br>unicode allowed in legend<br>use command <a href='#fontfamily'>fontfamily</a> to set the font of the legend. |
714 | @ there is no limit to the number of boxplots used. |
||
715 | @ can <b>not</b> be set draggable and <a href='#onclick'>onclick</a> is not ready yet |
||
716 | @ use keyword <a href="#userboxplot">userboxplot</a> before command boxplot, if a pupil must draw a boxplot (using his own min,Q1,median,Q3,max data) |
||
717 | @ use keyword <a href="#userboxplotdata">userboxplotdata</a> before command boxplot, if a pupil must generate the data by some means. |
||
718 | @ use command <a href="#boxplotdata">boxplotdata</a> when the boxplot should be drawn from wims-generated raw statistical date |
||
719 | @%boxplot_1%size 400,400%xrange 0,300%yrange 0,10%opacity 120,50%filled%fillcolor orange%strokecolor blue%linewidth 2%boxplot x,4,8,120,160,170,220,245 |
||
720 | @%boxplot_2%size 400,400%xrange 0,10%yrange 0,300%opacity 120,50%filled%fillcolor orange%strokecolor blue%linewidth 2%boxplot y,4,8,120,160,170,220,245 |
||
721 | @%boxplot_3%size 400,400%xrange 0,100%yrange 0,10%fillpattern hatch%linewidth 3%fillcolor red%strokecolor green%boxplot x,1,2,4,14,27,39,66%strokecolor blue%boxplot x,1,4,15,45,50,66,87%strokecolor red%boxplot x,1,6,45,70,80,90,100%strokecolor orange%boxplot x,1,8,28,38,48,56,77%mouse red,16 |
||
722 | */ |
||
723 | js_function[DRAW_BOXPLOT] = 1; |
||
724 | for(i=0;i<8;i++){ |
||
725 | switch(i){ |
||
726 | case 0: temp = get_string_argument(infile,0); |
||
727 | if( strstr(temp,"x") != 0){int_data[0] = 1;}else{int_data[0] = 0;} break; /* x or y */ |
||
728 | case 1: double_data[0] = get_real(infile,0);break;/* height | width */ |
||
729 | case 2: |
||
730 | if( js_function[DRAW_JSBOXPLOT] == 0 ){ |
||
731 | double_data[1] = get_real(infile,0); |
||
732 | fprintf(js_include_file,"var boxplot_source = 0;\n");/* we use given min,Q1,median,Q3,max */ |
||
733 | } |
||
734 | else { |
||
735 | double_data[1] = get_real(infile,1); |
||
736 | double_data[2] = 1; |
||
737 | double_data[3] = 1; |
||
738 | double_data[4] = 1; |
||
739 | double_data[5] = 1; |
||
740 | double_data[6] = 1; |
||
741 | double_data[7] = 1; |
||
742 | i=8; |
||
743 | } |
||
744 | break;/* center value x or y */ |
||
745 | case 3: double_data[2] = get_real(infile,0); break;/* min */ |
||
746 | case 4: double_data[3] = get_real(infile,0); break;/* Q1 */ |
||
747 | case 5: double_data[4] = get_real(infile,0); break;/* median */ |
||
748 | case 6: double_data[5] = get_real(infile,0); break;/* Q3 */ |
||
749 | case 7: double_data[6] = get_real(infile,1); break;/* max */ |
||
750 | default:break; |
||
751 | } |
||
752 | } |
||
753 | decimals = find_number_of_digits(precision); |
||
754 | /*function draw_boxplot(canvas_type,xy,hw,cxy,data,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1)*/ |
||
18557 | bpr | 755 | tmp_buffer=my_newmem(MAX_BUFFER); |
756 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"draw_boxplot(%d,%d,%.*f,%.*f,[%.*f,%.*f,%.*f,%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d);\n",BOXPLOT_CANVAS+boxplot_cnt,int_data[0],decimals,double_data[0],decimals,double_data[1],decimals,double_data[2],decimals,double_data[3],decimals,double_data[4],decimals,double_data[5],decimals,double_data[6],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1])); |
||
18552 | bpr | 757 | add_to_buffer(tmp_buffer); |
758 | boxplot_cnt++; |
||
759 | reset(); |
||
760 | break; |
||
761 | case BOXPLOTDATA: |
||
762 | /* |
||
763 | @ boxplotdata some_data |
||
764 | @ 'some_data' are a list of numbers separated by a comma "," (items) |
||
765 | @ only be used before command <code>boxplot</code>: the command <a href="#boxplot">boxplot</a> will provide the boxplot drawing of the data. |
||
766 | @ xrange 0,100<br>yrange 0,10<br>boxplotdata 11,22,13,15,23,43,12,12,14,2,45,32,44,13,21,24,13,19,35,21,24,23<br>boxplot x,4,5 |
||
767 | @ note: wims will not check your data input | format. use js-error console to debug any problems. |
||
768 | @ a javascript function <code>statistics()</code> will parse the data and calculate the values [min,Q1,median,Q3,max] and hand them to the boxplot draw function. |
||
769 | @ only a single call to <code>boxplotdata</code> can be made. If multiple boxplots should be present in a single canvas, then use multiple calls to command <a href='#boxplot'>boxplot</a> |
||
770 | @%boxplotdata%size 400,400%xrange 0,100%yrange 0,10%strokecolor orange%fillpattern hatch%linewidth 3%strokecolor green%boxplotdata 11,22,13,15,23,43,12,12,14,2,45,32,44,13,21,24,13,19,35,21,24,23%boxplot x,2,2%mouse red,16 |
||
771 | */ |
||
772 | js_function[DRAW_JSBOXPLOT] = 1; |
||
773 | js_function[DRAW_BOXPLOT] = 1; |
||
774 | fprintf(js_include_file,"var boxplot_source = 1;var jsboxplot_data = [%s];\n",get_string(infile,1)); |
||
775 | break; |
||
776 | case CANVASTYPE: |
||
777 | canvas_type = (int) (get_real(infile,1)); |
||
778 | /* |
||
779 | @ canvastype TYPE |
||
780 | @ for now only useful before commands filltoborder / floodfill / clickfill etc operations<br>Only the images of this TYPE will be scanned and filled |
||
781 | @ default value of TYPE is DRAG_CANVAS e.g. 5 (all clickable / draggable object are in this canvas) |
||
782 | @ use another TYPE, if you know what you are doing... |
||
18627 | bpr | 783 | @ other possible canvasses (e.g. transparent PNG pictures, xsize × ysize on top of each other)<ul><li>EXTERNAL_IMAGE_CANVAS 0</li><li>BG_CANVAS 1</li><li> STATIC_CANVAS 2</li><li> MOUSE_CANVAS 3</li><li> GRID_CANVAS 4</li><li> DRAG_CANVAS 5</li><li> DRAW_CANVAS 6</li><li> TEXT_CANVAS 7</li><li> CLOCK_CANVAS 8</li><li> ANIMATE_CANVAS 9</li><li> TRACE_CANVAS 10</li><li>BOXPLOT_CANVAS 11</li><li> JSPLOT_CANVAS 100, will increase with every call</li><li> FILL_CANVAS 200, will increase with every call</li><li> USERDRAW_JSPLOT 300, will increase with every call</li><li>CLICKFILL_CANVAS 400, will increase with every call/click</li><li>BOXPLOT_CANVAS 500, will increase with every call</li></ul> |
18552 | bpr | 784 | */ |
785 | break; |
||
786 | case CENTERED: |
||
787 | use_offset = 4; |
||
788 | /* |
||
18556 | bpr | 789 | @ centered |
790 | @ keyword ; to place the text centered (in width and height) on the text coordinates(x:y) |
||
791 | @ may be used for text exactly centered on its (x;y) |
||
792 | @ use <a href="#fontfamily">fontfamily</a> for setting the font |
||
793 | @ may be active for commands <a href="#text">text</a> and <a href="#string">string</a> (e.g. objects in the ''drag/drop/onclick-library``) |
||
794 | @%centered%size 400,400%xrange -10,10%yrange -10,10%fontfamily 12pt Arial%string blue,-9,-9,no offset%point -9,-9,red%centered%string blue,-6,-6,centered%point -6,-6,red%xoffset%string blue,-3,-3,xoffset%point -3,-3,red%yoffset%string blue,0,0,yoffset%point 0,0,red%xyoffset%string blue,3,3,xyoffset%point 3,3,red%resetoffset%string blue,6,6,resetoffset%point 6,6,red |
||
18552 | bpr | 795 | */ |
18556 | bpr | 796 | break; |
18552 | bpr | 797 | case CENTERSTRING: |
798 | /* |
||
18556 | bpr | 799 | @ centerstring color,y-value,the text string |
800 | @ title color,y-value,the text string |
||
801 | @ draw a string centered on the canvas at y = y-value |
||
802 | @ can not be set ''onclick`` or ''drag xy`` (...) |
||
803 | @ unicode supported: <code>centerstring red,5,\\u2232</code> |
||
804 | @ use a command like <code>fontfamily italic 24pt Arial</code> to set fonts on browser that support font change |
||
805 | @%centerstring%size 400,400%xrange -10,10%yrange -10,10%bgcolor lightblue%fontfamily italic 22pt Courier%centerstring blue,7,the center |
||
18552 | bpr | 806 | */ |
807 | js_function[DRAW_CENTERSTRING] = 1; |
||
808 | for(i=0;i<3;i++){ |
||
809 | switch(i){ |
||
810 | case 0: stroke_color = get_color(infile,0);break;/* name or hex color */ |
||
811 | case 1: double_data[0] = get_real(infile,0);break; /* y in xrange*/ |
||
812 | case 2: temp = get_string_argument(infile,1); |
||
813 | /* draw_text = function(canvas_type,y,font_family,stroke_color,stroke_opacity,text) */ |
||
814 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 815 | tmp_buffer=my_newmem(MAX_BUFFER); |
816 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_centerstring(%d,%.*f,\"%s\",\"%s\",%.2f,\"%s\");\n",canvas_root_id,decimals,double_data[0],font_family,stroke_color,stroke_opacity,temp)); |
||
18552 | bpr | 817 | add_to_buffer(tmp_buffer); |
818 | break; |
||
819 | default:break; |
||
820 | } |
||
821 | } |
||
822 | break; |
||
823 | case CHEMTEX: |
||
824 | /* |
||
825 | chemtex |
||
826 | keyword...needs to be the first command in the script (even before the ''size`` command) |
||
827 | only for KaTeX enabled typesetting ! |
||
828 | will include 80kB large js-library for chemisty typesetting |
||
829 | using <a href="http://85.148.206.56/wims/download/katex.for.wims.tar.gz">KaTeX</a> : <code>katex x,y,\\ce{ chemistry tex code} like : \\ce{ Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2- }</code> |
||
830 | using MathJaX : <code>latex x,y,\\ce{ chemistry tex code} like : \\ce{ Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2- }</code> |
||
831 | see https://mhchem.github.io/MathJax-mhchem/ |
||
832 | %chemtex_katex_mathjax%chemtex%size 400,400%xrange -10,10%yrange -10,10%snaptogrid%fontfamily 22px Arial%strokecolor red%drag xy%centered%latex 0,8,\\ce{Hg^2+}%drag xy%centered%latex 0,4,\\ce{\\xrightarrow{\\text{I}^{-}}}%drag xy%centered%latex 0,0,\\ce{HgI2}%centered%drag xy%latex 0,-4,\\ce{\\xrightarrow{\\text{I}^{-}}}%drag xy%centered%latex 0,-8,\\ce{[Hg^{II}I4]^2-} |
||
833 | */ |
||
834 | found_size_command = 1; |
||
835 | fprintf(stdout,"\n<script src=\"scripts/js/KaTeX/mhchem.js\" defer></script>\n"); |
||
836 | break; |
||
8386 | schaersvoo | 837 | |
18552 | bpr | 838 | case CIRCLE: |
839 | /* |
||
840 | @ circle xc,yc,width (2*r in pixels),color |
||
841 | @ use command <code>fcircle xc,yc,d,color</code> |
||
842 | @ alternative: disk |
||
843 | @ use command <code>fillcolor color</code> to set the fillcolor |
||
844 | @ may be set <a href='#drag'>draggable</a> / <a href='#onclick'>onclick</a> |
||
845 | @ will shrink / expand on zoom out / zoom in |
||
846 | @%circle%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 255,50%drag xy%circle 0,0,60,red%zoom red |
||
847 | */ |
||
848 | for(i=0;i<4;i++){ |
||
849 | switch(i){ |
||
850 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
851 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
852 | case 2: double_data[2] = px2x((get_real(infile,0))/2) - px2x(0);break; /* for zoom in/out: radius in 'dx' xrange*/ |
||
853 | case 3: stroke_color = get_color(infile,1);/* name or hex color */ |
||
18623 | bpr | 854 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 855 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
856 | if(use_affine == TRUE ){ transform(2,2);} |
||
857 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
858 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 859 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 860 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,13,[%.*f],[%.*f],[%.3f],[%.3f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],double_data[2],double_data[2],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 861 | add_to_buffer(tmp_buffer); |
862 | if(onclick != 0){object_cnt++;}/* object_cnt++;*/ |
||
863 | dragstuff[13] = 1; |
||
864 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
865 | reset(); |
||
866 | break; |
||
867 | default : break; |
||
868 | } |
||
869 | } |
||
870 | break; |
||
871 | case CIRCLES: |
||
872 | /* |
||
873 | @ circles color,xc1,yc1,r1,xc2,yc2,r2...xc_n,yc_n,r_n |
||
874 | @ <b>attention</b> r = radius in x-range (!) |
||
875 | @ use keyword <code>filled</code> or command <code>fcircles</code> to produce solid circles |
||
876 | @ alternative: disks |
||
877 | @ use command <code>fillcolor color</code> to set the fillcolor |
||
878 | @ may be set <a href='#drag'>draggable</a> / <a href='#onclick'>onclick</a> (individually) |
||
879 | @ will shrink / expand on zoom out / zoom in |
||
880 | @%circles_drag%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 255,50%drag xy%circles blue,0,0,2,2,2,3,-3,-3,3,3,3,4,3,-4,2%zoom red |
||
881 | @%circles_onclick%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 255,50%onclick%circles blue,0,0,2,2,2,3,-3,-3,3,3,3,4,3,-4,2%zoom red |
||
882 | @%circles_drag_slider%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag xy%# Click circles(s) to activate%opacity 200,50%fillcolor orange%rotationcenter 2,3%slider 0,2*pi,300,30,angle degrees,Rotate%slider -5,5*pi,300,30,x display,move in x-direction%slider -10,10*pi,300,30,y display,move in y-direction%fcircles blue,0,0,0.5,2,2,1,-3,-3,1.5,3,3,0.5,3,-4,0.5 |
||
883 | */ |
||
884 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
18623 | bpr | 885 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 886 | i=1; |
887 | while( ! done ){ /* get next item until EOL*/ |
||
888 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
889 | switch (i%3){ |
||
890 | case 1:double_data[i-1] = get_real(infile,0);break; /* x */ |
||
891 | case 2:double_data[i-1] = get_real(infile,0);break; /* y */ |
||
892 | case 0:double_data[i-1] = get_real(infile,1);break; /* r */ |
||
893 | } |
||
894 | i++; |
||
895 | } |
||
896 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,3);} |
||
897 | if(use_affine == TRUE ){ transform(i-1,3);} |
||
898 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
8386 | schaersvoo | 899 | |
18552 | bpr | 900 | decimals = find_number_of_digits(precision); |
901 | for(c = 0 ; c < i-1 ; c = c+3){ |
||
18557 | bpr | 902 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 903 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,13,[%.*f],[%.*f],[%.3f],[%.3f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],double_data[c+2],double_data[c+2],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 904 | add_to_buffer(tmp_buffer); |
905 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
906 | } |
||
907 | reset(); |
||
908 | dragstuff[13] = 1; |
||
909 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
910 | break; |
||
911 | case CLEARBUTTON: |
||
912 | /* |
||
18556 | bpr | 913 | @ clearbutton value |
914 | @ alternative: delete |
||
915 | @ alternative: erase |
||
916 | @ adds a button to clear the <a href="#userdraw">userdraw</a> canvas with text ''value`` |
||
18572 | bpr | 917 | @ <b>attention</b> command <code>clearbutton</code> is incompatible with <a href="#multidraw">multidraw</a> based drawings<br>(in <code>multidraw</code> there is always a remove_object_button for every draw primitive) |
18556 | bpr | 918 | @ normally <a href="#userdraw">userdraw</a> primitives have the option to use middle/right mouse button on<br> a point of the object to remove this specific object...this clear button will remove all drawings |
919 | @ uses the tooltip placeholder div element: may not be used with command <code>intooltip</code> |
||
920 | @ use command <a href="#css">css</a> to style the button... |
||
921 | @ the clearbutton will have id="canvas_scripts[%d]" ; starting with %d=0 for the first script<br>to change the style of all ''clearbutton`` of all included canvasdraw scripts, use something like<br><code>if(document.getElementById("clearbutton"+canvas_scripts[0])){<br> var p = 0;<br> while(document.getElementById("clearbutton"+canvas_scripts[p])){<br> document.getElementById("clearbutton"+canvas_scripts[p]).className="some_class_name";<br> <!−−</code> or <code>document.getElementById("clearbutton"+canvas_scripts[p]).setAttribute("style","some_style"); −−><br> p++;<br> };<br>};</code> |
||
922 | @%clearbutton%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 255,50%userdraw circles,red%clearbutton Remove All |
||
18552 | bpr | 923 | */ |
924 | if(reply_format == 29){/* eg multidraw is selected */ |
||
925 | // canvas_error("command clearbutton incompatible with multidraw...only suitable for userdraw"); |
||
926 | } |
||
927 | add_clear_button(css_class,get_string(infile,1)); |
||
928 | break; |
||
929 | case CLOCK: |
||
930 | /* |
||
931 | @ clock x,y,r(px),H,M,S,type hourglass,interactive [ ,H_color,M_color,S_color,background_color,foreground_color ] |
||
932 | @ use command <code>opacity stroke-opacity,fill-opacity</code> to adjust foreground (stroke) and background (fill) transparency |
||
933 | @ type hourglass:<br>type = 0: only segments<br>type = 1: only numbers<br>type = 2: numbers and segments |
||
18627 | bpr | 934 | @ colors are optional: if not defined, default values will be used<br>default colors: clock 0,0,60,4,35,45,1,2<br>custom colors: clock 0,0,60,4,35,45,1,2,,,,yellow,red<br>custom colors: clock 0,0,60,4,35,45,1,2,white,green,blue,black,yellow |
18552 | bpr | 935 | @ if you don't want a seconds hand (or minutes...), just make it invisible by using the background color of the hourglass... |
936 | @ interactive <ul><li>0: not interactive, just clock(s)</li><li>1: function read_canvas() will read all active clocks in H:M:S format<br>The active clock(s) can be adjusted by pupils</li><li>2: function read_canvas() will return the clicked clock <br>(like multiplechoice; first clock in script in nr. 0 )</li><li>3: no prefab buttons...create your own buttons (or other means) to make the clock(s) adjustable by javascript function set_clock(num,type,diff)<br>wherein: num = clock id (starts with 0) ; type = 1 (hours) ; type = 2 (minutes) ; type = 3 (seconds) <br>and diff = the increment of 'type' (positive or negative)</li></ul> |
||
937 | @ canvasdraw will not check validity of colornames...the javascript console is your best friend |
||
938 | @ no combinations with other reply_types allowed, for now |
||
939 | @ if interactive is set to ''1``, 6 buttons per clock will be displayed for adjusting a clock (H+ M+ S+ H- M- S-)<br> set_clock(clock_id,type,incr) <br>first clock has clock_id=0 ; type: H=1,M=2,S=3 ; incr: increment integer |
||
18627 | bpr | 940 | @ note: if you need multiple -interactive- clocks on a webpage, use multiple ''clock`` commands in a single script<br>and <i>not multiple canvas scripts</i> in a single page |
18552 | bpr | 941 | @ note: clocks will not zoom or pan, when using command <a href='#zoom'>zoom</a> |
942 | @%clock_1%size 400,400%xrange -10,10%yrange -10,10%clock 0,0,120,4,35,45,0,0,red,green,blue,lightgrey,black |
||
943 | @%clock_2%size 400,400%xrange -10,10%yrange -10,10%clock 0,0,120,4,35,45,1,1,red,green,blue,lightgrey,black |
||
944 | @%clock_3%size 400,400%xrange -10,10%yrange -10,10%clock -5,0,80,4,35,45,2,2,red,green,blue,lightgrey,black%clock 5,0,80,3,15,65,2,2,red,green,blue,lightgrey,black |
||
945 | @%clock_4%size 400,400%xrange -10,10%yrange -10,10%clock 0,0,120,4,35,45,0,0,red,green,blue,lightgrey,black |
||
946 | @%clock_5%size 400,400%xrange -10,10%yrange -10,10%clock 0,0,120,4,35,45,1,1,red,green,blue,lightgrey,black |
||
947 | @%clock_6%size 400,400%xrange -10,10%yrange -10,10%clock -5,0,80,4,35,45,2,2,red,green,blue,lightgrey,black%clock 5,0,80,8,55,15,2,2,red,green,blue,lightgrey,black |
||
948 | @%clock_7%size 400,400%xrange -10,10%yrange -10,10%clock 0,0,120,4,35,45,2,0,red,green,blue,lightgrey,black |
||
949 | */ |
||
950 | js_function[DRAW_CLOCK] = 1; |
||
951 | js_function[INTERACTIVE] = 1; |
||
8386 | schaersvoo | 952 | |
18552 | bpr | 953 | /* var clock = function(xc,yc,radius,H,M,S,h_color,m_color,s_color,bg_color,fg_color) */ |
954 | for(i=0;i<9;i++){ |
||
955 | switch(i){ |
||
956 | case 0: int_data[0] = x2px(get_real(infile,0)); break; /* xc */ |
||
957 | case 1: int_data[1] = y2px(get_real(infile,0)); break; /* yc */ |
||
958 | case 2: int_data[2] = get_real(infile,0);break;/* radius in px */ |
||
959 | case 3: int_data[3] = get_real(infile,0);break;/* hours */ |
||
960 | case 4: int_data[4] = get_real(infile,0);break;/* minutes */ |
||
961 | case 5: int_data[5] = get_real(infile,0);break;/* seconds */ |
||
962 | case 6: int_data[6] = get_real(infile,0);if(int_data[6] < 0 || int_data[6] > 2){canvas_error("hourglass can be 0,1 or 2");}break;/* type hourglass */ |
||
963 | case 7: int_data[7] = (int)(get_real(infile,1));/* interactive 0,1,2*/ |
||
964 | switch(int_data[7]){ |
||
965 | case 0:break; |
||
966 | case 1: |
||
967 | if(clock_cnt == 0){ |
||
968 | if( reply_format == 0 ){ |
||
969 | reply_format = 18; /* user sets clock */ |
||
18557 | bpr | 970 | /* |
971 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
972 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "set_clock = function(num,type,diff){var name = eval(\"clocks\"+num);switch(type){case 1:name.H = parseInt(name.H+diff);break;case 2:name.M = parseInt(name.M+diff);break;case 3:name.S = parseInt(name.S+diff);break;default: break;};name = clock(name.xc,name.yc,name.radius,name.H,name.M,name.S,name.type,name.interaction,name.H_color,name.M_color,name.S_color,name.bg_color,name.fg_color);};\n")); |
||
18552 | bpr | 973 | add_to_buffer(tmp_buffer); |
974 | */ |
||
975 | fprintf(js_include_file,"set_clock = function(num,type,diff){if(wims_status == \"done\"){return;};var name = eval(\"clocks\"+num);switch(type){case 1:name.H = parseInt(name.H+diff);break;case 2:name.M = parseInt(name.M+diff);break;case 3:name.S = parseInt(name.S+diff);break;default: break;};name = new clock(name.xc,name.yc,name.radius,name.H,name.M,name.S,name.type,name.interaction,name.H_color,name.M_color,name.S_color,name.bg_color,name.fg_color);};\n"); |
||
976 | } |
||
977 | else { |
||
978 | canvas_error("interactive clock may not be used together with other reply_types..."); |
||
979 | } |
||
980 | } |
||
981 | fprintf(stdout,"<p style=\"text-align:center\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,1,1)\" value=\"H+\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,2,1)\" value=\"M+\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,3,1)\" value=\"S+\"><br><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,1,-1)\" value=\"H−\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,2,-1)\" value=\"M−\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,3,-1)\" value=\"S−\"></p>",css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt); |
||
982 | break; |
||
983 | case 3: |
||
984 | if(clock_cnt == 0){ |
||
985 | if( reply_format == 0 ){ |
||
986 | reply_format = 18; /* user sets clock */ |
||
987 | fprintf(js_include_file,"set_clock = function(num,type,diff){if(wims_status == \"done\"){return;};var name = eval(\"clocks\"+num);switch(type){case 1:name.H = parseInt(name.H+diff);break;case 2:name.M = parseInt(name.M+diff);break;case 3:name.S = parseInt(name.S+diff);break;default: break;};name = new clock(name.xc,name.yc,name.radius,name.H,name.M,name.S,name.type,1,name.H_color,name.M_color,name.S_color,name.bg_color,name.fg_color);};\n"); |
||
988 | } |
||
989 | else { |
||
990 | canvas_error("interactive clock may not be used together with other reply_types..."); |
||
991 | } |
||
992 | } |
||
993 | /* |
||
994 | fprintf(stdout,"<p style=\"text-align:center\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,1,1)\" value=\"H+\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,2,1)\" value=\"M+\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,3,1)\" value=\"S+\"><br><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,1,-1)\" value=\"H−\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,2,-1)\" value=\"M−\"><input class=\"%s\" type=\"button\" onclick=\"javascript:set_clock(%d,3,-1)\" value=\"S−\"></p>",css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt,css_class,clock_cnt); |
||
995 | */ |
||
996 | break; |
||
997 | case 2: |
||
998 | if( reply_format == 0 ){ |
||
999 | reply_format = 19; /* "onclick */ |
||
1000 | js_function[INTERACTIVE] = 1; |
||
1001 | fprintf(js_include_file,"\n/* begin onclick handler for clocks */\nvar reply = new Array();canvas_div.addEventListener( 'mousedown', user_click,false);\n\nfunction user_click(evt){if(evt.button == 1){var canvas_rect = clock_canvas.getBoundingClientRect();var x = evt.clientX - canvas_rect.left;var y = evt.clientY - canvas_rect.top;var p = 0;var name;var t = true;while(t){try{name = eval('clocks'+p);if( x < name.xc + name.radius && x > name.xc - name.radius ){if( y < name.yc + name.radius && y > name.yc - name.radius ){reply[0] = p;name = new clock(name.xc,name.yc,name.radius,name.H,name.M,name.S,name.type,name.interaction,name.H_color,name.M_color,name.S_color,\"lightblue\",name.fg_color);};}else{clock_ctx.clearRect(name.xc-name.radius,name.yc-name.radius,name.xc+name.radius,name.yc+name.radius);name = new clock(name.xc,name.yc,name.radius,name.H,name.M,name.S,name.type,name.interaction,name.H_color,name.M_color,name.S_color,name.bg_color,name.fg_color);};p++;}catch(e){t=false;};};};};\n"); |
||
1002 | } |
||
1003 | else { |
||
1004 | if( reply_format != 19){ |
||
1005 | canvas_error("clickable clock(s) may not be used together with other reply_types..."); |
||
1006 | } |
||
1007 | } |
||
1008 | break; |
||
1009 | default: canvas_error("interactive must be set 0,1 or 2");break; |
||
1010 | } |
||
1011 | break; |
||
1012 | case 8: |
||
1013 | if(clock_cnt == 0 ){ /* set opacity's just once .... it should be a argument to clock(), for now it's OK */ |
||
1014 | fprintf(js_include_file,"var clock_bg_opacity = %.2f;var clock_fg_opacity = %.2f;",fill_opacity,stroke_opacity); |
||
1015 | } |
||
1016 | temp = get_string(infile,3);/* optional colors, like: ,,red,,blue*/ |
||
1017 | if( strstr( temp,",") != 0 ){ temp = str_replace(temp,",","\",\""); } |
||
1018 | else{ |
||
1019 | /* h_color,m_color,s_color,bg_color,fg_color */ |
||
1020 | temp = ",black\",\"black\",\"black\",\"white\",\"black";} |
||
18557 | bpr | 1021 | tmp_buffer=my_newmem(MAX_BUFFER); |
1022 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "clocks%d = new clock(%d,%d,%d,%d,%d,%d,%d,%d,\"%s\");\n",clock_cnt,int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],int_data[5],int_data[6],int_data[7],temp)); |
||
18552 | bpr | 1023 | add_to_buffer(tmp_buffer); |
1024 | fprintf(js_include_file,"var clocks%d;",clock_cnt); |
||
1025 | clock_cnt++; |
||
1026 | break; |
||
1027 | default:break; |
||
1028 | } |
||
1029 | } |
||
1030 | break; |
||
1031 | case COLORPALETTE: |
||
1032 | /* |
||
18556 | bpr | 1033 | @ colorpalette color_name_1,color_name_2,...,color_name_8 |
1034 | @ opacity will be the same for all colors and is set by command <a href="#opacity">opacity [0-255],[0-255]</a> |
||
1035 | @ can be used with command <a href='#userdraw'>userdraw clickfill,color</a> when more than one fillcolor is wanted.<br>in that case use for example <a href='#replyformat'>replyformat 10</a> ... reply=x1:y1:color1,x2:y2:color2...<br>the pupil can choose from the given colors by clicking small coloured buttons.<br> the click coordinates and corresponding fillcolor will be stored in read_canvas()...when using the appropriate replyformat.<br>the first color of the palette is color=0 |
||
18642 | schaersvoo | 1036 | @ make sure to include the ''remove button`` by using command <a href='#clearbutton'>clearbutton some_text</a><br/>please note: right mouse click will alse remove last added item... |
1037 | @%colorpalette%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%circles blue,0,0,4,1,1,6,3,3,3,-3,-3,5%opacity 255,100%colorpalette red,green,yellow,blue%userdraw clickfill,green%clearbutton REMOVE |
||
18552 | bpr | 1038 | */ |
1039 | if( use_tooltip == 1 ){canvas_error("command 'colorpalette' is incompatible with command 'intooltip tip_text'");} |
||
1040 | fprintf(js_include_file,"var multifillcolors = [];var palettecolors = ["); |
||
1041 | while( ! done ){ |
||
1042 | temp = get_color(infile,1); |
||
18642 | schaersvoo | 1043 | fprintf(js_include_file,"\"%s,%d\",",temp,(int) (255*fill_opacity)); |
18552 | bpr | 1044 | } |
1045 | fprintf(js_include_file,"];");/* add black to avoid trouble with dangling comma... */ |
||
1046 | add_color_palette(css_class); |
||
1047 | break; |
||
15111 | schaersvoo | 1048 | |
18552 | bpr | 1049 | case COMMENT: |
1050 | sync_input(infile); |
||
1051 | break; |
||
11806 | schaersvoo | 1052 | |
18552 | bpr | 1053 | case COPY: |
1054 | /* |
||
1055 | @ copy x,y,x1,y1,x2,y2,[filename URL] |
||
1056 | @ The image may be "bitmap" or "SVG" |
||
1057 | @ Insert the region from (x1,y1) to (x2,y2) (in pixels) of [filename] to (x,y) in x/y-range |
||
1058 | @ If x1=y1=x2=y2=-1, the whole [filename URL] is copied. |
||
1059 | @ [filename] is the URL of the image |
||
1060 | @ <em>TODO:move special image functions to generic 'dragstuff' library</em> |
||
1061 | @ URL is normal URL of network reachable image file location |
||
1062 | @ if command <a href="#drag">drag x/y/xy</a> is set before command ''copy``, the images will be draggable<br>javascript function read_canvas(); will return the x/y coordinate data in xrange/yrange of all -including non draggable- images<br>the command drag is only valid for the next image<br>draggable / non-draggable images may be mixed<br>may be used together with preceding keywords ''snaptogrid``, ''xsnaptogrid``, ''ysnaptogrid`` or <code>snaptopoints x1,y1,x2,y2...</code>. |
||
1063 | @ if keyword <a href="#onclick">onclick</a> is set before command ''copy`` the image(s) is clickable (marked with a green rectangle around the image)<br>use 'read_dragdrop' to get the number of the clicked image(s)<br>use command 'clearbutton some_text' to reset the reply/click array.<br>example: 4 images; student clicked on image 2 and 3: reply = 0,1,1,0<br>after clicking the clear button: reply = 0,0,0,0<br>May be mixed with commands ''drag x|y|xy`` (use javascript read_canvas to get the new coordinates |
||
1064 | @ ''onclick`` for external images may be mixed with canvas generated stuff (like lines,curves, embeded XML etc) |
||
1065 | @ you may draw / userdraw / drag other stuff on top of an "imported" image |
||
1066 | @ the use of a slider is not possible: if needed, use command <a href='#html'>html x,y,<img src=my_image.svg /> </a> |
||
1067 | @ use keyword <a href='#centered'>centered</a> before command ''copy`` to place image center at given coordinates. |
||
1068 | @%copy_onclick%size 400,400%xrange -10,10%yrange -10,10%onclick%copy -5,5,-1,-1,-1,-1,gifs/fr.gif%onclick%copy 5,5,-1,-1,-1,-1,gifs/en.gif%onclick%copy 5,-5,-1,-1,-1,-1,gifs/it.gif%onclick%copy -5,-5,-1,-1,-1,-1,gifs/cn.gif |
||
1069 | @%copy_drag_xy%size 400,400%xrange -10,10%yrange -10,10%# attention: left mouse click on the image will activate dragging...%# keep left mouse button pressed while moving the image !%drag xy%copy -5,5,-1,-1,-1,-1,gifs/fr.gif%drag xy%copy 5,5,-1,-1,-1,-1,gifs/en.gif%drag xy%copy 5,-5,-1,-1,-1,-1,gifs/it.gif%drag xy%copy -5,-5,-1,-1,-1,-1,gifs/cn.gif |
||
1070 | @%copy_drag_xy_snaptogrid%size 400,400%xrange -10,10%yrange -10,10%grid 2,2,grey%# attention: left mouse click on the image will activate dragging...%# keep left mouse button pressed while moving the image !%drag xy%# a function read_canvas_images() %copy -6,6,-1,-1,-1,-1,gifs/fr.gif%snaptogrid%drag xy%copy 6,6,-1,-1,-1,-1,gifs/en.gif%snaptogrid%drag xy%copy 6,-6,-1,-1,-1,-1,gifs/it.gif%snaptogrid%drag xy%copy -6,-6,-1,-1,-1,-1,gifs/cn.gif |
||
1071 | */ |
||
1072 | for(i = 0 ; i<7;i++){ |
||
1073 | switch(i){ |
||
1074 | case 0: double_data[0]=get_real(infile,0);break; /* x left top corner in x/y range */ |
||
1075 | case 1: double_data[1]=get_real(infile,0);break; /* y left top corner in x/y range */ |
||
1076 | case 2: int_data[2]=(int)(get_real(infile,0));break;/* x1 in px of external image */ |
||
1077 | case 3: int_data[3]=(int)(get_real(infile,0));break;/* y1 in px of external image */ |
||
1078 | case 4: int_data[4]=(int)(get_real(infile,0));break;/* x2 --> width */ |
||
1079 | case 5: int_data[5]=(int)(get_real(infile,0)) ;break;/* y2 --> height */ |
||
1080 | case 6: URL = get_string(infile,1); |
||
1081 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
1082 | if(use_affine == TRUE ){transform(2,2);} |
||
1083 | int_data[0] = x2px(double_data[0]); |
||
1084 | int_data[1] = y2px(double_data[1]); |
||
1085 | int_data[6] = int_data[4] - int_data[2];/* swidth & width (if not scaling )*/ |
||
1086 | int_data[7] = int_data[5] - int_data[3];/* sheight & height (if not scaling )*/ |
||
1087 | if( onclick == 0 ){ /* no mouse needed static image copy */ |
||
1088 | if(js_function[DRAW_EXTERNAL_IMAGE] == 0){/* create canvas just once */ |
||
1089 | fprintf(js_include_file,"var image_copy_canvas = create_canvas%d(%d,xsize,ysize);",canvas_root_id,STATIC_IMAGE_CANVAS); |
||
1090 | js_function[DRAW_EXTERNAL_IMAGE] = 1; |
||
1091 | } |
||
18557 | bpr | 1092 | tmp_buffer=my_newmem(MAX_BUFFER); |
1093 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_external_image(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d);\n",URL,int_data[2],int_data[3],int_data[6],int_data[7],int_data[0],int_data[1],int_data[6],int_data[7],use_offset,int_data[10])); |
||
18552 | bpr | 1094 | } |
1095 | else /* onclick or drag & drop external copy images */ |
||
1096 | { |
||
1097 | js_function[DRAG_EXTERNAL_IMAGE] = 1; |
||
18557 | bpr | 1098 | tmp_buffer=my_newmem(MAX_BUFFER); |
1099 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "drag_external_image(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d);\n",URL,int_data[2],int_data[3],int_data[6],int_data[7],int_data[0],int_data[1],int_data[6],int_data[7],onclick,object_cnt,use_offset,use_snap,int_data[10])); |
||
18552 | bpr | 1100 | } |
1101 | add_to_buffer(tmp_buffer); |
||
1102 | object_cnt++; |
||
1103 | break; |
||
1104 | default: break; |
||
1105 | } |
||
1106 | } |
||
1107 | reset(); |
||
1108 | break; |
||
11806 | schaersvoo | 1109 | /* |
1110 | HTML5 specs: |
||
1111 | context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); |
||
18552 | bpr | 1112 | img Specifies the image, canvas, or video element to use |
1113 | sx The x coordinate where to start clipping: x1 = int_data[0] |
||
1114 | sy The y coordinate where to start clipping: x2 = int_data[1] |
||
1115 | swidth The width of the clipped image: int_data[2] - int_data[0] |
||
14066 | bpr | 1116 | sheight The height of the clipped image: int_data[3] - int_data[1] |
18552 | bpr | 1117 | x The x coordinate where to place the image on the canvas: dx1 = int_data[4] |
1118 | y The y coordinate where to place the image on the canvas: dy1 = int_data[5] |
||
1119 | width The width of the image to use (stretch or reduce the image): dx2 - dx1 = int_data[6] |
||
1120 | height The height of the image to use (stretch or reduce the image): dy2 - dy1 = int_data[7] |
||
11806 | schaersvoo | 1121 | */ |
18552 | bpr | 1122 | case COPYRESIZED: |
1123 | /* |
||
1124 | @ copyresized x1,y2,x2,y2,dx1,dy1,dx2,dy2,image_file_url |
||
1125 | @ The image may be any "bitmap" or "SVG" |
||
1126 | @ Insert the region from (x1,y1) to (x2,y2) (in pixels) of [ filename], <br>possibly resized,<br>to the region of (dx1,dy1) to (dx2,dy2) in x/y-range |
||
1127 | @ (dx1:dy1) must be left top corner; (dx2:dy2) must be right bottom corner of inserted image |
||
1128 | @ If x1=y1=x2=y2=-1, the whole [filename / URL ] is copied and resized. |
||
1129 | @ URL is normal URL of network reachable image file location<br>(as seen from public_html-root or network reachable 'http://some_server/my_images/test.gif'<br>(eg no special wims paths are searched !!) |
||
1130 | @ if command <a href="#drag">drag x/y/xy</a> is set before command ''copy``, the images will be draggable<br>javascript function read_canvas(); will return the x/y coordinate data in xrange/yrange of all -including non draggable- images<br>the command drag is only valid for the next image<br>draggable / non-draggable images may be mixed<br>may be used together with preceding keywords ''snaptogrid``,''xsnaptogrid``,''ysnaptogrid`` or <code>snaptopoints x1,y1,x2,y2...</code> |
||
1131 | @ if keyword <a href="#onclick">onclick</a> is set before command ''copy`` the image(s) is clickable (marked with a green rectangle around the image)<br>use ''read_dragdrop`` to get the number of the clicked image(s)<br>use command 'clearbutton some_text' to reset the reply/click array.<br>example: 4 images; student clicked on image 2 and 3: reply = 0,1,1,0<br>after clicking the clear button: reply = 0,0,0,0<br>May be mixed with commands ''drag x|y|xy`` (use javascript read_canvas to get the new coordinates |
||
1132 | @ ''onclick`` for external images may be mixed with canvas generated stuff (like lines,curves etc) |
||
1133 | @ you may draw / userdraw / drag stuff on top of an "imported" image |
||
1134 | @ when set draggable, there will be special function 'read_canvas_images()'<br>now dragging external images may be combined with 'read_canvas()' from <a href='#userdraw'>userdraw</a> or <a href='#multidraw'>multidraw</a><br>set command <a href='#precision'>precision</a> before command ''copy`` |
||
1135 | @ use keyword <a href='#centered'>centered</a> before command 'copyresized' to place image center at given coordinates. |
||
1136 | @ <em>TODO:move special image functions to generic 'dragstuff' library</em> |
||
1137 | */ |
||
1138 | for(i = 0 ; i<9;i++){ |
||
1139 | switch(i){ |
||
1140 | case 0: int_data[0] = (int)(get_real(infile,0));break; /* x1 */ |
||
1141 | case 1: int_data[1] = (int)(get_real(infile,0));break; /* y1 */ |
||
1142 | case 2: int_data[2] = (int)(get_real(infile,0));break;/* x2 */ |
||
1143 | case 3: int_data[3] = (int)(get_real(infile,0));break;/* y2 */ |
||
1144 | case 4: int_data[4] = x2px(get_real(infile,0));break;/* dx1 */ |
||
1145 | case 5: int_data[5] = y2px(get_real(infile,0));break;/* dy1 */ |
||
1146 | case 6: int_data[6] = x2px(get_real(infile,0));break;/* dx2 */ |
||
1147 | case 7: int_data[7] = y2px(get_real(infile,0));break;/* dy2 */ |
||
1148 | case 8: URL = get_string(infile,1); |
||
1149 | if( int_data[1] == -1 ){ int_data[10] = 1; }else{int_data[10] = 0; }/* resized / not resized */ |
||
1150 | /* flag error when wrong diagonal: copyresized -1,-1,-1,-1,0,0,7,7,testfig.gif */ |
||
1151 | if( int_data[7] < int_data[5] || int_data[6] < int_data[4]){ |
||
1152 | canvas_error("in copyresized, use:<br>left top corner (dx1:dy1) and right bottom corner (dx2:dy2) ! "); |
||
1153 | } |
||
1154 | int_data[2] = abs(int_data[2] - int_data[0]);/* swidth */ |
||
1155 | int_data[3] = abs(int_data[3] - int_data[1]);/* sheight */ |
||
1156 | int_data[6] = abs(int_data[6] - int_data[4]);/* width */ |
||
1157 | int_data[7] = abs(int_data[7] - int_data[5]);/* height */ |
||
1158 | if( onclick == 0 ){ /* no mouse needed static image copy */ |
||
1159 | if(js_function[DRAW_EXTERNAL_IMAGE] == 0){ |
||
1160 | fprintf(js_include_file,"var image_copy_canvas = create_canvas%d(%d,xsize,ysize);",canvas_root_id,STATIC_IMAGE_CANVAS); |
||
1161 | js_function[DRAW_EXTERNAL_IMAGE] = 1; |
||
1162 | } |
||
18557 | bpr | 1163 | tmp_buffer=my_newmem(MAX_BUFFER); |
1164 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_external_image(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d);\n",URL,int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],int_data[5],int_data[6],int_data[7],use_offset,int_data[10])); |
||
18552 | bpr | 1165 | } |
1166 | else /* onclick or drag & drop external copy images */ |
||
1167 | { |
||
1168 | js_function[DRAG_EXTERNAL_IMAGE] = 1; |
||
18557 | bpr | 1169 | tmp_buffer=my_newmem(MAX_BUFFER); |
1170 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "drag_external_image(\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d);\n",URL,int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],int_data[5],int_data[6],int_data[7],onclick,object_cnt,use_offset,use_snap,int_data[10])); |
||
18552 | bpr | 1171 | object_cnt++; |
1172 | } |
||
1173 | add_to_buffer(tmp_buffer); |
||
1174 | break; |
||
1175 | default: break; |
||
1176 | } |
||
1177 | } |
||
1178 | reset(); |
||
1179 | break; |
||
8386 | schaersvoo | 1180 | |
18552 | bpr | 1181 | case CROSSHAIR: |
1182 | /* |
||
1183 | @ crosshair x,y,color |
||
1184 | @ draw a single crosshair point at (x;y) in color ''color`` |
||
1185 | @ use command <code>crosshairsize int</code> and / or <code>linewidth int</code> to adjust |
||
1186 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1187 | @%crosshair%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%linewidth 2%onclick%crosshair 0,0,red%linewidth 1%onclick%crosshair 1,1,blue%linewidth 3%onclick%crosshair 3,3,green%linewidth 4%xrosshair 4,4,orange |
||
1188 | */ |
||
1189 | for(i=0;i<3;i++){ |
||
1190 | switch(i){ |
||
1191 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
1192 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
1193 | case 2: stroke_color = get_color(infile,1);/* name or hex color */ |
||
1194 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
1195 | if(use_affine == TRUE ){ transform(2,2);} |
||
1196 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1197 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 1198 | tmp_buffer=my_newmem(MAX_BUFFER); |
1199 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,7,[%.*f],[%.*f],[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],crosshair_size,crosshair_size,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1200 | add_to_buffer(tmp_buffer); |
1201 | if(onclick != 0){object_cnt++;} |
||
1202 | /* object_cnt++ */ |
||
1203 | reset(); |
||
1204 | dragstuff[7] = 1; |
||
1205 | break; |
||
1206 | default:break; |
||
1207 | } |
||
1208 | } |
||
1209 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1210 | break; |
||
11806 | schaersvoo | 1211 | |
18552 | bpr | 1212 | case CROSSHAIRS: |
1213 | /* |
||
1214 | @ crosshairs color,x1,y1,x2,y2,...,x_n,y_n |
||
1215 | @ draw multiple crosshair points at given coordinates in color ''color`` |
||
1216 | @ use command <code>crosshairsize int</code> and / or <code>linewidth int</code> to adjust |
||
1217 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
1218 | @%crosshairs_1%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%snaptogrid%linewidth 2%drag xy%crosshairs red,0,0,1,1,2,2,3,3%drag x%crosshairs blue,0,1,1,2,2,3,3,4 |
||
1219 | @%crosshairs_2%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%linewidth 2%onclick%crosshairs red,0,0,1,1,2,2,3,3%onclick%crosshairs blue,0,1,1,2,2,3,3,4 |
||
12107 | schaersvoo | 1220 | */ |
18552 | bpr | 1221 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
1222 | fill_color = stroke_color; |
||
1223 | i=0; |
||
1224 | while( ! done ){ /* get next item until EOL*/ |
||
1225 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
1226 | if(i%2 == 0 ){ |
||
1227 | double_data[i] = get_real(infile,0); /* x */ |
||
1228 | } |
||
1229 | else { |
||
1230 | double_data[i] = get_real(infile,1); /* y */ |
||
1231 | } |
||
1232 | i++; |
||
1233 | } |
||
1234 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
1235 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
1236 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1237 | decimals = find_number_of_digits(precision); |
||
1238 | for(c=0 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 1239 | tmp_buffer=my_newmem(MAX_BUFFER); |
1240 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,7,[%.*f],[%.*f],[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],crosshair_size,crosshair_size,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,1,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1241 | add_to_buffer(tmp_buffer); |
1242 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
1243 | } |
||
1244 | dragstuff[7] = 1; |
||
1245 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1246 | reset(); |
||
1247 | break; |
||
1248 | case CROSSHAIRSIZE: |
||
1249 | /* |
||
1250 | @ crosshairsize int |
||
1251 | @ default 8 (px) |
||
1252 | */ |
||
1253 | crosshair_size = (int) (get_real(infile,1)); |
||
1254 | break; |
||
1255 | case CSS: |
||
1256 | /* |
||
1257 | @ css css_class |
||
1258 | @ may be used before any ''style-able`` html object (like inputfields or buttons) or some html objects that are generated by some canvasdraw commands |
||
1259 | @ in case of <a href="#multidraw">multidraw</a> this command must be a table css class, for example "wimstable" |
||
1260 | @%css%size 400,400%xrange -10,10%yrange -10,10%css wims_button_help%input 0,0,10,1,Hello |
||
1261 | */ |
||
1262 | css_class = get_string(infile,1); |
||
1263 | break; |
||
1264 | case CURSOR: |
||
1265 | /* |
||
1266 | @ cursor some CSS cursor_style |
||
1267 | @ alternative: pointer |
||
1268 | @ style can be any valid CSS property value |
||
1269 | @ choose from these types:<br>alias,all-scroll,auto,cell,context-menu,col-resize,copy,crosshair,default,e-resize,<br>ew-resize,grab,grabbing,help,move,n-resize,ne-resize,nesw-resize,ns-resize,nw-resize,<br>nwse-resize,no-drop,none,not-allowed,pointer,progress,row-resize,s-resize,se-resize,<br>sw-resize,text,url(myBall.cur),auto,vertical-text,w-resize,wait,zoom-in,zoom-out,initial |
||
1270 | @ note: wims will not check the validity of your cursor declaration |
||
1271 | @%cursor_css%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 3%drag xy%opacity 200,75%fcircles blue,-5,5,3,-4,-2,6,0,0,5,3,4,2,4,-5,4 |
||
1272 | */ |
||
1273 | fprintf(js_include_file,"canvas_div%d.style.cursor = \"%s\";",canvas_root_id,get_string(infile,1)); |
||
1274 | break; |
||
1275 | case CURVE: |
||
1276 | /* |
||
18556 | bpr | 1277 | @ curve color,formula(x) |
1278 | @ alternative: plot |
||
18572 | bpr | 1279 | @ use command <a href="#trange">trange</a> in parametric functions before <b>every</b> command curve / plot <code>trange -pi,pi<br>curve color,formula1(t),formula2(t)</code><br>A next parametric curve will only be correctly plot when trange is set again !<br>this is a design flaw and not a feature... |
18556 | bpr | 1280 | @ use command <a href="#precision">precision</a> to increase the number of digits of the plotted points |
1281 | @ use command <a href="#plotsteps">plotsteps</a> to increase / decrease the amount of plotted points (default 150) |
||
1282 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1283 | @ if you need a plot beyond xrange / yrange, use <a href="#jsplot">jsplot</a> (command ''curve`` will only calculate points within the xrange) |
||
18569 | bpr | 1284 | @%curve%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%xlabel x-axis%ylabel y-axis%precision 1%grid 2,2,grey,2,2,6,grey%precision 1000%curve red,4*sqrt(x)%curve green,2*sqrt(abs(x))%curve blue,3*1/sqrt(x)%curve orange,4*sin(4/x)%dashed%curve red,4*cos(x) |
18552 | bpr | 1285 | */ |
1286 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
11806 | schaersvoo | 1287 | |
18552 | bpr | 1288 | if( use_parametric == TRUE ){ /* parametric color,fun1(t),fun2(t)*/ |
1289 | use_parametric = FALSE; |
||
1290 | stroke_color = get_color(infile,0); |
||
1291 | char *fun1 = get_string_argument(infile,0); |
||
1292 | char *fun2 = get_string_argument(infile,1); |
||
1293 | if( strlen(fun1) == 0 || strlen(fun2) == 0 ){canvas_error("parametric functions are NOT OK !");} |
||
18557 | bpr | 1294 | tmp_buffer=my_newmem(MAX_BUFFER); |
18634 | schaersvoo | 1295 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,9,%s,[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,eval_parametric(xsize,ysize,fun1,fun2,xmin-10,xmax+10,ymin-10,ymax+10,tmin,tmax,plot_steps,precision,rotationcenter),2*line_width,2*line_width,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 1296 | add_to_buffer(tmp_buffer); |
1297 | } |
||
1298 | else{ |
||
1299 | stroke_color = get_color(infile,0); |
||
1300 | char *fun1 = get_string_argument(infile,1); |
||
1301 | if( strlen(fun1) == 0 ){canvas_error("function is NOT OK !");} |
||
18557 | bpr | 1302 | tmp_buffer=my_newmem(MAX_BUFFER); |
18634 | schaersvoo | 1303 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,9,%s,[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,eval(xsize,ysize,fun1,xmin-10,xmax+10,ymin-10,ymax+10,plot_steps,precision,rotationcenter),line_width,line_width,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 1304 | add_to_buffer(tmp_buffer); |
1305 | } |
||
1306 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
1307 | dragstuff[9] = 1; |
||
1308 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1309 | reset(); |
||
1310 | break; |
||
1311 | case CURVEDARROW: |
||
14038 | schaersvoo | 1312 | /* |
18556 | bpr | 1313 | @ curvedarrow x1,y1,xc,yc,x2,y2,color |
1314 | @ draw a single headed curved arrow from (x1:y1) in direction of (xc:yc) to point (x2:y2)<br> note: the curve will <b>not go through</b> point (xc:yc) |
||
1315 | @ use command <a href='#arrowhead'>arrowhead</a> to set the size of the arrow head. |
||
1316 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
1317 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1318 | @%curvedarrow_drag%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 2%drag xy%curvedarrow -5,0,0,10,5,0,blue |
||
1319 | @%curvedarrow_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%%onclick%curvedarrow -5,0,0,-10,5,0,blue%onclick%curvedarrow -8,0,0,5,8,3,green |
||
11806 | schaersvoo | 1320 | |
14029 | schaersvoo | 1321 | h[0] = arrowhead |
14066 | bpr | 1322 | h[1] = type: 1 = single 2=double arrow |
15111 | schaersvoo | 1323 | function Shape(object_cnt,onclick,direction,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_slider,rotation_center,use_offset) |
14038 | schaersvoo | 1324 | */ |
18552 | bpr | 1325 | for(i=0;i<7;i++){ |
1326 | switch(i){ |
||
1327 | case 0: double_data[0] = get_real(infile,0);break; /* x1 */ |
||
1328 | case 1: double_data[1] = get_real(infile,0);break; /* y1 */ |
||
1329 | case 2: double_data[2] = get_real(infile,0);break; /* xc */ |
||
1330 | case 3: double_data[3] = get_real(infile,0);break; /* yc */ |
||
1331 | case 4: double_data[4] = get_real(infile,0);break; /* y3 */ |
||
1332 | case 5: double_data[5] = get_real(infile,0);break; /* y3 */ |
||
1333 | case 6: stroke_color = get_color(infile,1);/* name or hex color */ |
||
1334 | if(use_rotate == TRUE ){rotate(6,angle,rotationcenter,2);} |
||
1335 | if(use_affine == TRUE ){ transform(6,2);} |
||
1336 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1337 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 1338 | tmp_buffer=my_newmem(MAX_BUFFER); |
1339 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,21,[%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],arrow_head,arrow_head,arrow_head,1,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1340 | add_to_buffer(tmp_buffer); |
1341 | if(onclick != 0){object_cnt++;}/* object_cnt++;*/ |
||
1342 | reset(); |
||
1343 | break; |
||
1344 | } |
||
1345 | } |
||
1346 | dragstuff[21] = 1; |
||
1347 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1348 | break; |
||
1349 | case CURVEDARROW2: |
||
14038 | schaersvoo | 1350 | /* |
18556 | bpr | 1351 | @ curvedarrow2 x1,y1,xc,yc,x2,y2,color |
1352 | @ draw a double headed curved arrow from (x1:y1) in direction of (xc:yc) to point (x2:y2)<br> note: the curve will <b>not go through</b> point (xc:yc) |
||
1353 | @ use command <a href='#arrowhead'>arrowhead</a> to set the size of the arrow head. |
||
1354 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
1355 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1356 | @%curvedarrow_drag%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 2%drag xy%curvedarrow2 -5,0,0,10,5,0,blue |
||
18569 | bpr | 1357 | @%curvedarrow_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%%onclick%curvedarrow2 -5,0,0,-10,5,0,blue%onclick%curvedarrow -8,0,0,5,8,3,green |
14029 | schaersvoo | 1358 | |
1359 | h[0] = arrowhead |
||
14066 | bpr | 1360 | h[1] = type: 1 = single 2=double arrow |
15111 | schaersvoo | 1361 | function Shape(object_cnt,onclick,direction,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_slider,rotation_center,use_offset) |
14038 | schaersvoo | 1362 | */ |
18552 | bpr | 1363 | for(i=0;i<7;i++){ |
1364 | switch(i){ |
||
1365 | case 0: double_data[0] = get_real(infile,0);break; /* x1 */ |
||
1366 | case 1: double_data[1] = get_real(infile,0);break; /* y1 */ |
||
1367 | case 2: double_data[2] = get_real(infile,0);break; /* xc */ |
||
1368 | case 3: double_data[3] = get_real(infile,0);break; /* yc */ |
||
1369 | case 4: double_data[4] = get_real(infile,0);break; /* y3 */ |
||
1370 | case 5: double_data[5] = get_real(infile,0);break; /* y3 */ |
||
1371 | case 6: stroke_color = get_color(infile,1);/* name or hex color */ |
||
1372 | if(use_rotate == TRUE ){rotate(6,angle,rotationcenter,2);} |
||
1373 | if(use_affine == TRUE ){ transform(6,2);} |
||
1374 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1375 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 1376 | tmp_buffer=my_newmem(MAX_BUFFER); |
1377 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,21,[%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],arrow_head,arrow_head,arrow_head,2,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1378 | add_to_buffer(tmp_buffer); |
1379 | if(onclick != 0){object_cnt++;}/* object_cnt++;*/ |
||
1380 | dragstuff[21] = 1; |
||
1381 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1382 | reset(); |
||
1383 | break; |
||
1384 | } |
||
1385 | } |
||
1386 | break; |
||
1387 | case CURVEDARROWS: |
||
14038 | schaersvoo | 1388 | /* |
18556 | bpr | 1389 | @ curvedarrows color,x1,y1,xc,yc,x2,y2,...,x_(n-1),y_(n-1),xc,yc,x_n,y_n |
1390 | @ draw curved arrows from (x1:y1) in direction of (xc:yc) to point (x2:y2), etc<br> note: the curve will <b>not go through</b> point (xc:yc) |
||
1391 | @ use command <a href='#arrowhead'>arrowhead</a> to set the size of the arrow head. |
||
1392 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
1393 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1394 | @%curvedarrows_drag%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 2%drag xy%curvedarrows red,-8,0,0,8,8,0,-5,5,0,-10,6,3 |
||
1395 | @%curvedarrows_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%%onclick%curvedarrows red,-8,0,0,8,8,0,-5,5,0,-10,6,3 |
||
14029 | schaersvoo | 1396 | |
14030 | schaersvoo | 1397 | h[0] = arrowhead |
14066 | bpr | 1398 | h[1] = type: 1 = single 2=double arrow |
15111 | schaersvoo | 1399 | function Shape(object_cnt,onclick,direction,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_slider,rotation_center,use_offset) |
14038 | schaersvoo | 1400 | */ |
18552 | bpr | 1401 | stroke_color = get_color(infile,0);/* name or hex color */ |
1402 | i = 0; |
||
1403 | decimals = find_number_of_digits(precision); |
||
1404 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1405 | while( ! done ){ |
||
1406 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
1407 | double_data[0] = get_real(infile,0); /* x1 */ |
||
1408 | double_data[1] = get_real(infile,0); /* y1 */ |
||
1409 | double_data[2] = get_real(infile,0); /* xc */ |
||
1410 | double_data[3] = get_real(infile,0); /* yc */ |
||
1411 | double_data[4] = get_real(infile,0); /* x3 */ |
||
1412 | double_data[5] = get_real(infile,1); /* y3 */ |
||
18557 | bpr | 1413 | tmp_buffer=my_newmem(MAX_BUFFER); |
1414 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,21,[%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],arrow_head,arrow_head,arrow_head,1,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1415 | add_to_buffer(tmp_buffer); |
1416 | if(onclick != 0){object_cnt++;} |
||
1417 | i = i + 6; |
||
1418 | } |
||
1419 | if(use_rotate == TRUE ){rotate(i-6,angle,rotationcenter,2);} |
||
1420 | if(use_affine == TRUE ){ transform(i-6,2);} |
||
1421 | dragstuff[21] = 1; |
||
1422 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1423 | reset(); |
||
1424 | break; |
||
1425 | case CURVEDARROWS2: |
||
14038 | schaersvoo | 1426 | /* |
18556 | bpr | 1427 | @ curvedarrows2 color,x1,y1,xc,yc,x2,y2,...x_(n-1),y_(n-1),xc,yc,x_n,y_n |
1428 | @ draw double headed curved arrows from (x1:y1) in direction of (xc:yc) to point (x2:y2), etc. <br> note: the curve will <b>not go through</b> point (xc:yc) |
||
1429 | @ use command <a href='#arrowhead'>arrowhead</a> to set the size of the arrow head. |
||
1430 | @ use command <code>linewidth int</code> to adjust thickness of the arrow |
||
1431 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1432 | @%curvedarrows2_drag%size 400,400%xrange -10,10%yrange -10,10%cursor move%linewidth 2%drag xy%curvedarrows2 red,-8,0,0,8,8,0,-5,5,0,-10,6,3 |
||
1433 | @%curvedarrows2_click%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%%onclick%curvedarrow -5,0,0,-10,5,0,blue%onclick%curvedarrows2 red,-8,0,0,8,8,0,-5,5,0,-10,6,3 |
||
14030 | schaersvoo | 1434 | |
1435 | h[0] = arrowhead |
||
14066 | bpr | 1436 | h[1] = type: 1 = single 2=double arrow |
15111 | schaersvoo | 1437 | function Shape(object_cnt,onclick,direction,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_slider,rotation_center,use_offset) |
14038 | schaersvoo | 1438 | */ |
18552 | bpr | 1439 | stroke_color = get_color(infile,0);/* name or hex color */ |
1440 | i = 0; |
||
1441 | decimals = find_number_of_digits(precision); |
||
1442 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1443 | while( ! done ){ |
||
1444 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
1445 | double_data[0] = get_real(infile,0); /* x1 */ |
||
1446 | double_data[1] = get_real(infile,0); /* y1 */ |
||
1447 | double_data[2] = get_real(infile,0); /* xc */ |
||
1448 | double_data[3] = get_real(infile,0); /* yc */ |
||
1449 | double_data[4] = get_real(infile,0); /* x3 */ |
||
1450 | double_data[5] = get_real(infile,1); /* y3 */ |
||
18557 | bpr | 1451 | tmp_buffer=my_newmem(MAX_BUFFER); |
1452 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,21,[%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],arrow_head,arrow_head,arrow_head,2,line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1453 | add_to_buffer(tmp_buffer); |
1454 | if(onclick != 0){object_cnt++;} |
||
1455 | i = i + 6; |
||
1456 | } |
||
1457 | if(use_rotate == TRUE ){rotate(i-6,angle,rotationcenter,2);} |
||
1458 | if(use_affine == TRUE ){ transform(i-6,2);} |
||
1459 | dragstuff[21] = 1; |
||
1460 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1461 | reset(); |
||
1462 | break; |
||
1463 | case DASHED: |
||
1464 | /* |
||
1465 | @ dashed |
||
1466 | @ keyword (no arguments required) |
||
1467 | @ next object will be drawn with a dashed line |
||
1468 | @ change dashing scheme by using command <a href="#dashtype">dashtype</a> |
||
1469 | @%dashed%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%line -5,-5,-5,5,red%dashtype 1,1%dline -4,-5,-4,5,green%dashtype 2,2%dline -3,-5,-3,5,blue%dashtype 3,3%dline 0,-5,0,5,orange%dashtype 4,4%dline 3,-5,3,5,brown |
||
1470 | */ |
||
1471 | use_dashed = TRUE; |
||
1472 | break; |
||
1473 | case DASHTYPE: |
||
1474 | /* |
||
1475 | @ dashtype line_width_px,space_width_px |
||
1476 | @ every indiviual object may have its own dashtype, if needed... |
||
1477 | @ When keyword <a href='#dashed'>dashed</a> is set, the objects will be drawn with this dashtype |
||
1478 | @ default value <code>dashtype 2,2</code> e.g. 2px line and 2px space |
||
1479 | @ HTML5 canvas specification supports more arguments (dashing schemes) ... but not all modern browsers are yet capable |
||
1480 | @%dashtype%size 400,400%xrange -10,10%yrange -10,10%dashtype 1,1%dhline 0,9,red%dashtype 2,2%dhline 0,8,red%dashtype 4,4%dhline 0,7,red%dashtype 6,6%dhline 0,6,red%dashtype 8,8%dhline 0,5,red%dashtype 10,10%dhline 0,4,red%dashtype 1,2%dhline 0,3,red%dashtype 2,4%dhline 0,2,red%dashtype 3,6%dhline 0,1,red%dashtype 4,8%dhline 0,0,red%linewidth 2%dashtype 1,1%dhline 0,-9,red%dashtype 2,2%dhline 0,-8,red%dashtype 4,4%dhline 0,-7,red%dashtype 6,6%dhline 0,-6,red%dashtype 8,8%dhline 0,-5,red%dashtype 10,10%dhline 0,-4,red%dashtype 1,2%dhline 0,-3,red%dashtype 2,4%dhline 0,-2,red%dashtype 4,8%dhline 0,-1,red |
||
1481 | */ |
||
1482 | for(i=0;i<2;i++){ |
||
1483 | switch(i){ |
||
1484 | case 0 : dashtype[0] = (int) line_width*( get_real(infile,0)) ; break; |
||
1485 | case 1 : dashtype[1] = (int) line_width*( get_real(infile,1)) ; break; |
||
1486 | } |
||
1487 | } |
||
1488 | break; |
||
1489 | case DIAMONDFILL: |
||
1490 | /* |
||
1491 | @ diamondfill x0,y0,dx,dy,color |
||
1492 | @ x0,y0 in xrange / yrange |
||
1493 | @ distances dx,dy in pixels |
||
1494 | @ there is also a command <a href="#userdraw">userdraw diamondfill,color</a> |
||
1495 | @%diamondfill%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%circles red,-4,0,6,4,0,6%linewidth 1%diamondfill 0,0,5,8,blue%diamondfill 0,7,8,8,lightgreen |
||
1496 | */ |
||
1497 | js_function[DRAW_DIAMONDFILL] = 1; |
||
1498 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
1499 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1500 | add_js_filltoborder(canvas_type); |
||
1501 | } |
||
1502 | decimals = find_number_of_digits(precision); |
||
1503 | for(i=0;i<5;i++){ |
||
1504 | switch(i){ |
||
1505 | case 0: double_data[0] = get_real(infile,0); break; /* x */ |
||
1506 | case 1: double_data[1] = get_real(infile,0); break; /* y */ |
||
1507 | case 2: int_data[0] = (int) (get_real(infile,0)); break; /* dx pixel */ |
||
1508 | case 3: int_data[1] = (int) (get_real(infile,0)); break; /* dy pixel*/ |
||
1509 | case 4: stroke_color = get_color(infile,1); |
||
1510 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
1511 | if(use_affine == TRUE ){ transform(2,2);} |
||
18573 | bpr | 1512 | /* draw_diamondfill(ctx,x0,y0,dx,dy,linewidth,color,opacity,xsize,ysize) */ |
18557 | bpr | 1513 | tmp_buffer=my_newmem(MAX_BUFFER); |
1514 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_diamondfill(%d,%.*f,%.*f,%d,%d,%d,\"%s\",%.2f,%d,%d);\n",STATIC_CANVAS+fill_cnt,decimals,double_data[0],decimals,double_data[1],int_data[0],int_data[1],line_width,stroke_color,stroke_opacity,xsize,ysize)); |
||
18552 | bpr | 1515 | add_to_buffer(tmp_buffer); |
1516 | fill_cnt++; |
||
1517 | reset(); |
||
1518 | break; |
||
1519 | default:break; |
||
1520 | } |
||
1521 | } |
||
1522 | break; |
||
1523 | case DOTFILL: |
||
1524 | /* |
||
1525 | @ dotfill x0,y0,dx,dy,color |
||
1526 | @ x0,y0 in xrange / yrange |
||
1527 | @ distances dx,dy in pixels |
||
1528 | @ radius of dots is linewidth |
||
1529 | @ there is also a command <a href="#userdraw">userdraw dotfill,color</a> |
||
1530 | @%dotfill%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%circles red,-4,0,6,4,0,6%dotfill 0,0,5,8,blue%dotfill 0,7,8,8,lightgreen |
||
1531 | */ |
||
1532 | js_function[DRAW_DOTFILL] = 1; |
||
1533 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
1534 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1535 | add_js_filltoborder(canvas_type); |
||
1536 | } |
||
1537 | decimals = find_number_of_digits(precision); |
||
1538 | for(i=0;i<5;i++){ |
||
1539 | switch(i){ |
||
1540 | case 0: double_data[0] = get_real(infile,0); break; /* x in px */ |
||
1541 | case 1: double_data[1] = get_real(infile,0); break; /* y in py */ |
||
1542 | case 2: int_data[0] = (int) (get_real(infile,0)); break; /* dx pixel */ |
||
1543 | case 3: int_data[1] = (int) (get_real(infile,0)); break; /* dy pixel*/ |
||
1544 | case 4: stroke_color = get_color(infile,1); |
||
1545 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
1546 | if(use_affine == TRUE ){ transform(2,2);} |
||
1547 | /* draw_dotfill(ctx,x0,y0,dx,dy,radius,color,opacity,xsize,ysize) */ |
||
18557 | bpr | 1548 | tmp_buffer=my_newmem(MAX_BUFFER); |
1549 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_dotfill(%d,%.*f,%.*f,%d,%d,%d,\"%s\",%.2f,%d,%d);\n",FILL_CANVAS+fill_cnt,decimals,double_data[0],decimals,double_data[1],int_data[0],int_data[1],line_width,stroke_color,stroke_opacity,xsize,ysize)); |
||
18552 | bpr | 1550 | add_to_buffer(tmp_buffer); |
1551 | fill_cnt++; |
||
1552 | reset(); |
||
1553 | break; |
||
1554 | default:break; |
||
1555 | } |
||
1556 | } |
||
1557 | break; |
||
1558 | case DRAG: |
||
1559 | /* |
||
18556 | bpr | 1560 | @ drag [x][y][xy] |
1561 | @ the next object will be draggable in x / y / xy direction |
||
1562 | @ the displacement can be read by <code>javascript:read_dragdrop();</code> |
||
1563 | @ the precision (default 2 decimals) in the student reply may be set with command <a href="#precision">precision</a>.<br>Use this 'precision' command before this command 'drag x|y|xy' ! |
||
1564 | @ <a href='#onclick'>onclick</a> and ''drag x|y|xy`` may be combined (for different objects: a single object can either be onclick or drag, not both ) |
||
1565 | @ ''multi_objects`` will be numbered in the given x/y-sequence (example: points red,0,0,1,1,2,2,3,3: point (0:0) is object_number 1) |
||
1566 | @ <b>attention</b>: static objects and ''onclick/drag`` objects of the same type (like point,circle,etc) with the same coordinates (e.g. objects that overlap) will give problems in the ''recognition algorithm``) in this example<br> <code>linewidth 4<br>point 0,0,red<br>drag xy<br>point 0,0,blue</code><br>the red point will not be recognised as draggable ! in the example<br><code>linewidth 4<br>drag xy<br>point 0,0,red<br>drag xy<br>point 0,0,blue</code><br>both points will be recognised |
||
1567 | @ the answer is: drag_or_onclick_object_number : Xorg : Yorg : Xnew : Ynew<br>wherein object_number is the sequence number of the draggable & onclick objects in your script.<br>Only draggable & onclick objects will have an object_number (e.g things like point,crosshair,line,segment,circle,rect,triangle...etc) |
||
1568 | @ use keyword <a href='#snaptogrid'>snaptogrid</a>, <a href='#xsnaptogrid'>xsnaptogrid</a>, <a href='#ysnaptogrid'>ysnaptogrid</a> or command <a href='#snaptopoints'>snaptopoints x1,y1,x2,y2,...</a> to switch from free to discrete movement |
||
1569 | @ in case of external images (commands copy / copyresized) the external image can be set draggable ; always xy. <br>The function javascript;read_canvas() will return the xy-coordinates of all images. |
||
1570 | @%drag_x%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 200,40%drag x%linewidth 2%circles blue,-5,0,3,0,0,2,5,0,4,0,4,3,0,-3,4 |
||
1571 | @%drag_y%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 200,40%drag y%linewidth 2%circles blue,-5,0,3,0,0,2,5,0,4,0,4,3,0,-3,4 |
||
1572 | @%drag_xy%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor lightblue%opacity 200,40%drag xy%linewidth 2%circles blue,-5,0,3,0,0,2,5,0,4,0,4,3,0,-3,4 |
||
18552 | bpr | 1573 | */ |
1574 | temp = get_string(infile,1); |
||
1575 | if(strstr(temp,"xy") != NULL ){ |
||
1576 | drag_type = 0; |
||
1577 | } else { |
||
1578 | if(strstr(temp,"x") != NULL ){ |
||
1579 | drag_type = 1; |
||
1580 | } |
||
1581 | else { drag_type = 2;} |
||
1582 | } |
||
1583 | /* assuming all drag&drop coordinates the same precision: so set only once */ |
||
1584 | if( print_drag_params_only_once == FALSE ){ |
||
1585 | fprintf(js_include_file,"dragdrop_precision = %d;use_dragdrop_reply = true;",precision); |
||
1586 | print_drag_params_only_once = TRUE; |
||
1587 | } |
||
1588 | onclick = 2; |
||
1589 | /* if(use_userdraw == TRUE ){canvas_error("\"drag & drop\" may not be combined with \"userdraw\" or \"pan and zoom\" \n");} */ |
||
1590 | use_dragstuff = 2; |
||
1591 | js_function[INTERACTIVE] = 1; |
||
1592 | break; |
||
1593 | case ELLIPSE: |
||
1594 | /* |
||
1595 | @ ellipse xc,yc,width_x,height_y,color |
||
1596 | @ ellipses with center xc/yc and width/height in x/y-range etc (this differs from flydraw syntax!) |
||
1597 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1598 | @ will shrink / expand on zoom out / zoom in |
||
1599 | @%ellipse%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor orange%opacity 200,40%linewidth 3%drag xy%ellipse 0,0,6,4,green%zoom blue |
||
1600 | */ |
||
1601 | for(i=0;i<5;i++){ |
||
1602 | switch(i){ |
||
1603 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
1604 | case 1:double_data[1] = get_real(infile,0);break; /* y-values */ |
||
1605 | case 2:double_data[2] = get_real(infile,0);break; /* rx -> px */ |
||
1606 | case 3:double_data[3] = get_real(infile,0);break; /* ry -> px */ |
||
1607 | case 4:stroke_color = get_color(infile,1);/* name or hex color */ |
||
1608 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,4);} |
||
1609 | if(use_affine == TRUE ){ transform(2,4);} |
||
1610 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
1611 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 1612 | tmp_buffer=my_newmem(MAX_BUFFER); |
1613 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,3,[%.*f],[%.*f],[%.*f],[%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],decimals,double_data[2],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1614 | add_to_buffer(tmp_buffer); |
1615 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
1616 | dragstuff[3] = 1; |
||
1617 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1618 | reset(); |
||
1619 | break; |
||
1620 | } |
||
1621 | } |
||
1622 | break; |
||
1623 | case ELLIPSES: |
||
1624 | /* |
||
1625 | @ ellipses color,xc1,yc1,width_x1,height_y1,xc2,yc2,width_x2,height_y2,xc3,yc3,width_x3,height_y3,... |
||
1626 | @ ellipses with center and height in x/y-range etc (this differs from flydraw syntax!) |
||
1627 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1628 | @ will shrink / expand on zoom out / zoom in |
||
1629 | @%ellipses%size 400,400%xrange -10,10%yrange -10,10%filled%fillcolor orange%opacity 200,40%linewidth 3%onclick%ellipses red,-3,0,2,4,0,0,4,2,3,0,6,2 |
||
1630 | */ |
||
8224 | bpr | 1631 | |
18552 | bpr | 1632 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
1633 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
18623 | bpr | 1634 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 1635 | i=1; |
1636 | while( ! done ){ /* get next item until EOL*/ |
||
1637 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
1638 | switch (i%4){ |
||
1639 | case 1:double_data[i-1] = get_real(infile,0);break; /* x */ |
||
1640 | case 2:double_data[i-1] = get_real(infile,0);break; /* y */ |
||
1641 | case 3:double_data[i-1] = get_real(infile,0);break; /* rx */ |
||
1642 | case 0:double_data[i-1] = get_real(infile,1);break; /* ry */ |
||
1643 | default: break; |
||
1644 | } |
||
1645 | i++; |
||
1646 | } |
||
1647 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,4);} |
||
1648 | if(use_affine == TRUE ){ transform(i-1,4);} |
||
1649 | decimals = find_number_of_digits(precision); |
||
1650 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18623 | bpr | 1651 | check_string_length(string_length); |
1652 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
1653 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,3,[%.*f],[%.*f],[%.*f],[%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],decimals,double_data[c+2],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 1654 | add_to_buffer(tmp_buffer); |
1655 | if(onclick != 0){object_cnt++;} /* object_cnt++; */ |
||
1656 | } |
||
1657 | reset(); |
||
1658 | dragstuff[3] = 1; |
||
1659 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
1660 | break; |
||
1661 | case FILLALL: |
||
1662 | /* |
||
1663 | @ fillall color,x1,y1,x2,y2...x_n,y_n |
||
18615 | bpr | 1664 | @ fill all the region containing points (x1:y1),(x2:y2)...(x_n:y_n) with color 'color' |
1665 | @ any color (object) in the <a href="#canvastype">canvastype</a> will act as border to the bucket fill |
||
18552 | bpr | 1666 | @ use this command after all boundary objects are declared. |
1667 | @ Use command 'userdraw clickfill,color' for user click driven flood fill. |
||
1668 | @ use command <a href="#canvastype">canvastype </a> to fill another canvas (default should be fine: DRAG_CANVAS = 5) |
||
1669 | @ note: the fill-family of commands are very (client) cpu intensive operations!<br>filling is done pixel by pixel e.g. image size of 400x400 uses 160000 pixels: each pixel contains 4 data (R,G,B,Opacity) = 640000 data.<br>on every data a few operations / comparisons are done...<br>So have pity on your students CPU.. |
||
1670 | @%fillall%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%vlines black,-5,0,-5,0,-4,0,-4,0,3,0,3,0%hlines black,-5,0,-5,0,-5,4,-5,4,-5,-2,-5,-2%circles green,0,0,2,3,3,5,-5,-5,3%opacity 240,50%fillall blue,1,1,8,8,-8,-8 |
||
1671 | */ |
||
1672 | decimals = find_number_of_digits(precision); |
||
1673 | fill_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
1674 | i=0; |
||
1675 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
1676 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1677 | add_js_filltoborder(canvas_type); |
||
1678 | } |
||
1679 | while( ! done ){ /* get next item until EOL*/ |
||
1680 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
1681 | if(i%2 == 0 ){ |
||
1682 | double_data[i] = get_real(infile,0); /* x */ |
||
1683 | } |
||
1684 | else { |
||
1685 | double_data[i] = get_real(infile,1); /* y */ |
||
18557 | bpr | 1686 | tmp_buffer=my_newmem(MAX_BUFFER); |
18609 | bpr | 1687 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "setTimeout(function(){filltoborder(%.*f,%.*f,false,[%s,%d],%d,false,null);},1000);\n",decimals,double_data[i-1],decimals,double_data[i],fill_color,(int) (fill_opacity/0.0039215),FILL_CANVAS+fill_cnt)); |
18552 | bpr | 1688 | add_to_buffer(tmp_buffer); |
1689 | fill_cnt++; |
||
1690 | } |
||
1691 | i++; |
||
1692 | } |
||
1693 | break; |
||
1694 | case FILLED: |
||
1695 | /* |
||
1696 | @ filled |
||
1697 | @ keyword (no arguments required) |
||
1698 | @ the next ''fillable`` object (only the next !) will be filled |
||
1699 | @ use command <a href="#fillcolor">fillcolor color</a> to set fillcolor |
||
1700 | @ use <a href="#fillpattern">fillpattern</a> for non-solid color filling. |
||
1701 | @ use command <code>opacity 0-255,0-255</code> to set stroke and fill-opacity |
||
1702 | @ use command <a href='#fill'>fill x,y,color</a> or <a href="#floodfill">floodfill x,y,color</a> to fill the space around (x;y) with color <br>pixel operation implemented in javascript: use with care ! |
||
1703 | */ |
||
1704 | use_filled = 1; |
||
1705 | break; |
||
1706 | case FILLCOLOR: |
||
1707 | /* |
||
1708 | @ fillcolor colorname or #hex |
||
1709 | @ set the color: mainly used for command 'userdraw obj,stroke_color' |
||
18635 | bpr | 1710 | @ or in forms as polygon, rects and so on (add filled it the form is not already filled, so if you use rect, need to put filled, if you use frect, no need). |
18552 | bpr | 1711 | @ see <a href="#fillpattern">fillpattern</a> for non-solid color filling. |
1712 | */ |
||
18623 | bpr | 1713 | fillcolor = get_color(infile,1); |
18635 | bpr | 1714 | fill_color = fillcolor; |
18552 | bpr | 1715 | break; |
1716 | case FILLPATTERN: |
||
1717 | /* |
||
1718 | @ fillpattern grid | hatch | diamond | dot | image_url |
||
1719 | @ alternative: settile image_url |
||
1720 | @ use a pattern as fillstyle |
||
1721 | @ suitable for all fillable object including the <a href="#userdraw">userdraw objects' family</a> |
||
18627 | bpr | 1722 | @ note: do not use the ''f`` for a fillable object : this is used exclusively for solid color filling. |
18569 | bpr | 1723 | @ the fillcolor is set by the object command, for example:<br><code>size 370,370<br>xrange -5,5<br>yrange -5,5<br>opacity 165,150<br>fillpattern grid<br>circle -6,3,160,blue<br>fillpattern dot<br>circle -3,-3,160,red<br>fillpattern hatch<br>circle 0,3,160,green<br>fillpattern diamond<br>circle 3,-3,160,cyan<br>userdraw dotfill,blue<br>zoom red</code> |
18552 | bpr | 1724 | @ the pattern dimensions are hardcoded (linewidth, radius,dx,dy are fixed) |
1725 | @ the pattern color is set by command <a href='#fillcolor'>fillcolor</a> and <a href='#opacity'>opacity</a> |
||
1726 | @ see <a href="#fillcolor">fillcolor</a> for solid color filling. |
||
18569 | bpr | 1727 | @ when using an image-url, make sure it contains an ''/`` in the filename...''fillpattern $module_dir/gifs/test.jpg`` will fill the next fillable object with this image.|<br>the argument to html5 canvas routine 'createPattern(img,argument)' is set to ''repeat`` e.g. if the image is smaller then the canvas, multiple copies will be used to fill the area ( e.g. ctx.fillStyle() = pattern)<br>for example:<br><code>size 150,150<br>xrange -5,5<br>yrange -5,5<br>drag xy<br>fillpattern gifs/en.gif<br>circle 0,0,100,red<br>fillpattern gifs/nl.gif<br>drag xy<br>circle -3,2,100,green<br>fillpattern gifs/cn.gif<br>drag xy<br>circle 3,2,100,green</code> |
18552 | bpr | 1728 | @ fillpattern is also active for <a href="#userdraw">userdraw object,color</a>...<br>the userdraw family a has also ''clickfill type`` (e.g. an object gets filled between boundaries, when clicked) commands like:<br>'userdraw dotfill,color'<br>'userdraw hatchfill,color' etc |
18569 | bpr | 1729 | @%fillpattern_1%size 400,400%xrange -5,5%yrange -5,5%opacity 165,150%fillpattern grid%circle -6,3,160,blue%fillpattern dot%circle -3,-3,160,red%fillpattern hatch%circle 0,3,160,green%fillpattern diamond%circle 3,-3,160,cyan%zoom red |
18552 | bpr | 1730 | @%fillpattern_2%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%fillcolor green%fillpattern hatch%#fillpattern dot,diamond,grid,imageurl%userdraw circle,red |
1731 | */ |
||
1732 | temp = get_string(infile,1); |
||
1733 | use_filled = 0; |
||
1734 | js_function[DRAW_FILL_PATTERN] = 1; |
||
1735 | if( strstr(temp,"grid") != 0 ){ use_filled = 2;} |
||
1736 | else{ |
||
1737 | if( strstr(temp,"hatch") != 0 ){ use_filled = 3;} |
||
1738 | else{ |
||
1739 | if( strstr(temp,"diamond") != 0 ){ use_filled = 4;} |
||
1740 | else{ |
||
1741 | if( strstr(temp,"dot") != 0 ){ use_filled = 5;} |
||
1742 | else{ |
||
1743 | if( strstr(temp,"/") != 0 ){ /* get_image_from_url() needs to be called after function definition...*/ |
||
1744 | use_filled = 6;js_function[JS_LOAD_IMAGE] = 1; |
||
18557 | bpr | 1745 | tmp_buffer=my_newmem(MAX_BUFFER); |
1746 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "get_image_from_url(\"%s\");",temp)); |
||
18552 | bpr | 1747 | add_to_buffer(tmp_buffer); |
1748 | } |
||
1749 | } |
||
1750 | } |
||
1751 | } |
||
1752 | } |
||
1753 | if( use_filled == 0 ){canvas_error("fillpattern unknown or typo...choose grid,hatch,diamond of dot...");} |
||
1754 | break; |
||
1755 | case FILLTOBORDER: |
||
1756 | /* |
||
1757 | @ filltoborder x,y,bordercolor,color |
||
1758 | @ fill the region of point (x:y) with color 'color' |
||
18615 | bpr | 1759 | @ any other color than bordercolor will not act as border to the bucket fill |
1760 | @ the filling is done in the connex component whih contains (x,y) of the set of points which are in a color different of bordercolor |
||
18552 | bpr | 1761 | @ use this command after all boundary objects are declared. |
18615 | bpr | 1762 | @ it can be useful to increase strokeopacity or linewidth |
18552 | bpr | 1763 | @ use command <a href="#canvastype">canvastype </a> to fill another canvas (default should be fine: DRAG_CANVAS = 5) |
1764 | @ note: filltoborder is a very (client) cpu intensive operation!<br>filling is done pixel by pixel e.g. image size of 400x400 uses 160000 pixels: each pixel contains 4 data (R,G,B,Opacity) = 640000 data.<br>on every data a few operations / comparisons are done...<br>So have pity on your students CPU.. |
||
1765 | @ maybe used together with command <a href="#userdraw">userdraw clickfill,color</a> |
||
18615 | bpr | 1766 | @%filltoborder%size 400,400%xrange -10,10%yrange -10,10%canvastype 100%linewidth 2%precision 1000%jsplot blue,5*sin(x)%opacity 200,50%filltoborder 6,6,blue,green%filltoborder 6,-6,blue,red |
18552 | bpr | 1767 | */ |
1768 | for(i=0 ;i < 4 ; i++){ |
||
1769 | switch(i){ |
||
1770 | case 0:double_data[0] = get_real(infile,0);break; |
||
1771 | case 1:double_data[1] = get_real(infile,0);break; |
||
1772 | case 2:bgcolor = get_color(infile,0);break; |
||
1773 | case 3:fill_color = get_color(infile,1); |
||
18569 | bpr | 1774 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
1775 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1776 | add_js_filltoborder(canvas_type); |
||
1777 | } |
||
1778 | decimals = find_number_of_digits(precision); |
||
18552 | bpr | 1779 | /* we need to set a timeout: the canvas is not yet draw in memory? when floodfill is called directly... */ |
18569 | bpr | 1780 | tmp_buffer=my_newmem(MAX_BUFFER); |
18629 | bpr | 1781 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "setTimeout(function(){filltoborder(%.*f,%.*f,[%s,%d],[%s,%d],%d,false,null)},1000);\n",decimals,double_data[0],decimals,double_data[1],bgcolor,(int) (fill_opacity/0.0039215),fill_color,(int) (fill_opacity/0.0039215),FILL_CANVAS+fill_cnt)); |
18569 | bpr | 1782 | add_to_buffer(tmp_buffer); |
1783 | fill_cnt++; |
||
1784 | reset(); |
||
1785 | break; |
||
18552 | bpr | 1786 | default:break; |
1787 | } |
||
1788 | } |
||
1789 | break; |
||
1790 | case FLOODFILL: |
||
1791 | /* |
||
1792 | @ floodfill x,y,color |
||
1793 | @ alternative: fill |
||
1794 | @ fill the region of point (x:y) with color 'color' |
||
1795 | @ any other color or size of picture (borders of picture) will act as border to the bucket fill |
||
1796 | @ use this command after all boundary objects are declared. |
||
1797 | @ Use command <code>userdraw clickfill,color</code> for user click driven flood fill. |
||
1798 | @ use command <a href="#canvastype">canvastype </a> to fill another canvas (default should be fine: DRAG_CANVAS = 5) |
||
1799 | @ note: floodfill is a very (client) cpu intensive operation!<br>filling is done pixel by pixel e.g. image size of 400x400 uses 160000 pixels: each pixel contains 4 data (R,G,B,Opacity) = 640000 data.<br>on every data a few operations / comparisons are done...<br>So have pity on your students CPU.. |
||
1800 | @%floodfill%size 400,400%xrange -10,10%yrange -10,10%canvastype 100%linewidth 2%precision 1000%jsplot blue,5*sin(x)%opacity 200,50%floodfill 6,6,blue%floodfill 6,-6,red |
||
1801 | */ |
||
1802 | for(i=0 ;i < 4 ; i++){ |
||
1803 | switch(i){ |
||
1804 | case 0:double_data[0] = get_real(infile,0);break; |
||
1805 | case 1:double_data[1] = get_real(infile,0);break; |
||
1806 | case 2:fill_color = get_color(infile,1); |
||
1807 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
1808 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1809 | add_js_filltoborder(canvas_type); |
||
1810 | } |
||
1811 | decimals = find_number_of_digits(precision); |
||
1812 | /* we need to set a timeout: the canvas is not yet draw in memory? when floodfill is called directly... */ |
||
18557 | bpr | 1813 | tmp_buffer=my_newmem(MAX_BUFFER); |
18609 | bpr | 1814 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "setTimeout(function(){filltoborder(%.*f,%.*f,false,[%s,%d],%d,false,null);},1000);\n",decimals,double_data[0],decimals,double_data[1],fill_color,(int) (fill_opacity/0.0039215),FILL_CANVAS+fill_cnt)); |
18552 | bpr | 1815 | add_to_buffer(tmp_buffer); |
1816 | fill_cnt++; |
||
1817 | break; |
||
1818 | default:break; |
||
1819 | } |
||
1820 | } |
||
1821 | reset(); |
||
1822 | break; |
||
1823 | case FONTCOLOR: |
||
1824 | /* |
||
18556 | bpr | 1825 | @ fontcolor color |
1826 | @ color: hexcolor or colorname |
||
1827 | @ default: black |
||
1828 | @ use command <a href="#fontfamily">fontfamily</a> to deviate from default font type |
||
1829 | @%fontcolor%size 400,400%xrange -10,10%yrange -10,10%fontcolor red%#note: use command fontfamily to change size and shape%axis%axisnumbering%grid 2,2,grey,2,2,4,grey |
||
18552 | bpr | 1830 | */ |
1831 | font_color = get_color(infile,1); |
||
1832 | break; |
||
1833 | case FONTFAMILY: |
||
1834 | /* |
||
18556 | bpr | 1835 | @ fontfamily font_description |
1836 | @ set the font family; for browsers that support it |
||
1837 | @ font_description: Arial, Courier, Helvetica etc |
||
1838 | @ in case commands <code>string color,x,y,the string</code>, <code>stringup color,x,y,rotation,the string</code>, ''fontfamily`` can be something like:<code>fontfamily italic 34pt Arial</code>. Use correct syntax: ''font style``, ''font size pt``, ''fontfamily`` |
||
1839 | @%fontfamily%size 400,400%xrange -10,10%yrange -10,10 %fontfamily Bold 10pt Arial%string blue,-9,9,10 pt Arial%fontfamily Italic 20pt Arial%string blue,0,9,20 pt Arial%fontfamily Bold 10pt Helvetica%string blue,-9,5,10 pt Helvetica%fontfamily Italic 20pt Helvetica%string blue,0,5,20 pt Helvetica %fontfamily Bold 10pt Courier%string blue,-9,0,10 pt Courier%fontfamily Italic 20pt Courier%string blue,0,0,20 pt Courier%fontfamily Bold 10pt Fixed%string blue,-9,-5,10 pt Fixed%fontfamily Italic 20pt Fixed%string blue,0,-5,20 pt Fixed %fontfamily Bold 10pt Times%string blue,-9,-9,10 pt Times%fontfamily Italic 20pt Times%string blue,0,-9,20 pt Times |
||
12110 | schaersvoo | 1840 | |
18552 | bpr | 1841 | */ |
1842 | font_family = get_string(infile,1); |
||
1843 | break; |
||
1844 | case FONTSIZE: |
||
1845 | /* |
||
18556 | bpr | 1846 | @ fontsize font_size |
1847 | @ default value 12 |
||
1848 | @ note: for some macros (like ''grid | legend | xaxistext | xlabel`` etc) sometimes command <a href="#fontfamily">fontfamily</a> can be used for some specific font-setting<br>this is however not always very straight forward... so just try and see what happens |
||
18552 | bpr | 1849 | */ |
1850 | font_size = (int) (get_real(infile,1)); |
||
1851 | break; |
||
1852 | case FUNCTION_LABEL: |
||
1853 | /* |
||
18556 | bpr | 1854 | @ functionlabel label_1:label_2:label_3... |
1855 | @ alternative: functionlabels |
||
1856 | @ default value ''f(x)=:g(x)=:h(x)=:i(x)=:j(x)=:k(x)=:m(x)=:n(x)=`` |
||
1857 | @ no mathml allowed (just ascii string) |
||
1858 | @ use command <a href='#fontsize'>fontsize int</a> to adjust the size |
||
1859 | @ use command <a href='#strokecolor'>strokecolor colorname</a> to adjust the labels (individually, if needed) |
||
1860 | @ if needed, use before every command <a href='#userinput'>userinput function | inputfield | textarea</a> |
||
1861 | @ no limit in amount of inputfields for userbased function plotting |
||
1862 | @%function_label%size 400,400%xrange -5,5%yrange -5,5%precision 0%axis%axisnumbering%opacity 100,190%grid 1,1,grey,2,2,5,black%linewidth 3%linewidth 1%precision 1000%functionlabels F(x)=:H(x)=:Yield(x)=%strokecolor green%userinput function%strokecolor red%userinput function%strokecolor blue%userinput function |
||
18552 | bpr | 1863 | */ |
1864 | temp = get_string_argument(infile,1); |
||
1865 | function_label = list2js_array(temp,":"); |
||
1866 | break; |
||
1867 | case GRID:/* xmajor,ymajor,gridcolor [,xminor,yminor,tick length (px), axis/tickscolor]*/ |
||
1868 | /* |
||
18556 | bpr | 1869 | @ grid step_x,step_y,gridcolor |
1870 | @ if keywords <a href="#axis">axis</a> or <a href="#axisnumbering">axisnumbering</a> are set, use: <code>grid step_x,step_y,major_color,minor_x,minor_y,tics height in px,axis_color</code> minor x step = step_x / minor_x |
||
1871 | @ in that case, use command <a href="#fontcolor">fontcolor</a>, <a href="#fontsize">fontsize</a> and / or <a href="#fontfamily">fontfamily</a> to adjust font; defaults: black,12,Arial |
||
1872 | @ if xmin > 0 and/or ymin > 0 and zooming / panning is not active: be aware that the x/y-axis numbering and x/y major/minor tic marks will not be visual as they are placed under the x-axis and left to the y-axis (in Quadrant II and IV) |
||
1873 | @ can <b>not</b> be set <a href="#onclick">onclick</a> or <a href="#drag">drag xy</a> |
||
1874 | @ use commands <a href="#xlabel">xlabel some_string</a> and/or <a href="#ylabel">ylabel some_string</a> to label axis; use command ''fontsize`` to adjust size: the font family is non-configurable 'italic your_fontsize px Arial' ! |
||
1875 | @ see commands <a href="#xaxis">xaxis or xaxistext</a>, <a href="#yaxis">yaxis or yaxistext</a> to set tailormade values on axis (the used font is set by command <a href="#fontfamily">fontfamily</a>; default '12px Arial') |
||
1876 | @ see command <a href="#legend">legend</a> to set a legend for the graph; use command <a href="#fontsize">fontsize</a> to adjust size (the font family is non-configurable 'bold your_fontsize px Arial') |
||
1877 | @%grid%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%zoom red |
||
1878 | @%grid_axis%size 400,400%xrange -10,10%yrange -10,10%axis%grid 1,1,grey,2,2,6,black%zoom red |
||
1879 | @%grid_axis_axisnumbering%size 400,400%xrange -10,10%yrange -10,10%fontfamily Italic 14px Courier%axis%axisnumbering%precision 0%grid 1,1,grey,2,2,6,black%zoom red |
||
18552 | bpr | 1880 | */ |
1881 | if( js_function[DRAW_YLOGSCALE] == 1 ){canvas_error("only one grid type is allowed...");} |
||
1882 | js_function[DRAW_GRID] = 1; |
||
1883 | for(i=0;i<4;i++){ |
||
1884 | switch(i){ |
||
1885 | case 0:double_data[0] = get_real(infile,0);break;/* xmajor */ |
||
1886 | case 1:double_data[1] = get_real(infile,0);break;/* ymajor */ |
||
1887 | case 2: |
||
1888 | if( use_axis == TRUE ){ |
||
1889 | stroke_color = get_color(infile,0); |
||
1890 | done = FALSE; |
||
1891 | int_data[0] = (int) (get_real(infile,0));/* xminor */ |
||
1892 | int_data[1] = (int) (get_real(infile,0));/* yminor */ |
||
1893 | int_data[2] = (int) (get_real(infile,0));/* tic_length */ |
||
1894 | fill_color = get_color(infile,1); /* used as axis_color*/ |
||
1895 | } |
||
1896 | else { |
||
1897 | int_data[0] = 1; |
||
1898 | int_data[1] = 1; |
||
1899 | stroke_color = get_color(infile,1); |
||
1900 | fill_color = stroke_color; |
||
1901 | } |
||
1902 | if( double_data[0] <= 0 || double_data[1] <= 0 || int_data[0] <= 0 || int_data[1] <= 0 ){canvas_error("major or minor ticks must be positive !");} |
||
1903 | /* set snap_x snap_y values in pixels */ |
||
1904 | fprintf(js_include_file,"snap_x = %f;snap_y = %f;",double_data[0] / int_data[0],double_data[1] / int_data[1]); |
||
1905 | fprintf(js_include_file,"\n/* add grid */function redraw_grid(){draw_grid%d(%d,%d,%.2f,%.*f,%.*f,%d,%d,%d,%d,\"%s\",\"%s\",%d,\"%s\",%d,%d,%d,%d,%d,\"%s\",%.2f);return;};",canvas_root_id,GRID_CANVAS,precision,stroke_opacity,decimals,double_data[0],decimals,double_data[1],int_data[0],int_data[1],int_data[2],line_width,stroke_color,fill_color,font_size,font_family,use_axis,use_axis_numbering,use_dashed,dashtype[0],dashtype[1],font_color,fill_opacity); |
||
18557 | bpr | 1906 | tmp_buffer=my_newmem(MAX_BUFFER); |
1907 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "redraw_grid();\n")); |
||
18552 | bpr | 1908 | add_to_buffer(tmp_buffer); |
1909 | break; |
||
1910 | } |
||
1911 | } |
||
1912 | reset(); |
||
1913 | break; |
||
1914 | case GRIDFILL: |
||
1915 | /* |
||
1916 | @ gridfill x0,y0,dx,dy,color |
||
1917 | @ x0,y0 in xrange / yrange |
||
1918 | @ distances dx,dy in pixels |
||
1919 | @ there is also a command <a href="#userdraw">userdraw gridfill,color</a> |
||
1920 | @%gridfill%size 400,400%xrange -10,10%yrange -10,10%canvastype 100%linewidth 2%precision 1000%jsplot blue,5*sin(x)%opacity 200,50%gridfill 6,6,10,10,blue%gridfill 6,-6,6,6,red |
||
11806 | schaersvoo | 1921 | |
18552 | bpr | 1922 | */ |
1923 | js_function[DRAW_GRIDFILL] = 1; |
||
1924 | decimals = find_number_of_digits(precision); |
||
1925 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
1926 | js_function[DRAW_FILLTOBORDER] = 1; |
||
1927 | add_js_filltoborder(canvas_type); |
||
1928 | } |
||
1929 | for(i=0;i<5;i++){ |
||
1930 | switch(i){ |
||
1931 | case 0: double_data[0] = get_real(infile,0); break; /* x */ |
||
1932 | case 1: double_data[1] = get_real(infile,0); break; /* y */ |
||
1933 | case 2: int_data[0] = (int) (get_real(infile,0)); break; /* dx pixel */ |
||
1934 | case 3: int_data[1] = (int) (get_real(infile,0)); break; /* dy pixel*/ |
||
1935 | case 4: stroke_color = get_color(infile,1); |
||
18557 | bpr | 1936 | |
1937 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
1938 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_gridfill(%d,%.*f,%.*f,%d,%d,%d,\"%s\",%.2f,%d,%d);\n",STATIC_CANVAS+fill_cnt,decimals,double_data[0],decimals,double_data[1],int_data[0],int_data[1],line_width,stroke_color,stroke_opacity,xsize,ysize)); |
||
18552 | bpr | 1939 | add_to_buffer(tmp_buffer); |
1940 | fill_cnt++; |
||
1941 | reset(); |
||
1942 | break; |
||
1943 | default:break; |
||
1944 | } |
||
1945 | } |
||
1946 | break; |
||
1947 | case GROUP: |
||
1948 | /* |
||
18556 | bpr | 1949 | @ group |
1950 | @ keyword |
||
1951 | @ work in 'progress' |
||
1952 | @ all objects(*) after the command and until <a href="#kill">kill group</a> or <a href="#killslider">killslider</a> may be moved together with mouse moverments<br> (*) for now all real canvas objects and latex / xml ; but no images (work in progress) |
||
1953 | @ may be combined with slider driven movements or drag & drop |
||
1954 | @%group%%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 100%linewidth 4%rotationcenter 0,0%slider -2*pi,2*pi,300,40,angle active,rotate%snaptogrid%ftriangle 0,-4,-2,-2,4,--5,blue%fillcolor red%fcircle -4.4,4.4,40,blue%kill slider%slider -20,20,300,40,x active,x-slide%ftriangle -2,0,0,4,2,0,green%fcircle 4.4,4.5,40,red%kill slider%slider -20,20,300,40,y active,y-slide%fcircle 4,-4,40,green%linewidth 4%fcircle -4,-4,40,orange%kill slider%group%fcircle -4.4,4.5,10,blue%fcircle -5.4,4.5,10,blue%fcircle -6.4,4.5,10,blue%fcircle -4.4,8,16,green%fcircle -5.4,8,16,green%fcircle -6.4,8,16,green%mouse red,22%zoom red |
||
18552 | bpr | 1955 | */ |
1956 | use_slider++; |
||
1957 | add_slider(2); |
||
1958 | no_reset = TRUE; |
||
1959 | int c = 0; |
||
1960 | for(i=last_slider;i<=use_slider;i++){ int_data[c] = i; c++; } |
||
1961 | my_sliders = data2js_array(int_data,use_slider - last_slider+1); |
||
1962 | if( precision == 0 ){precision = 100;} |
||
1963 | onclick = 5; |
||
1964 | use_dragstuff = 2; |
||
1965 | drag_type = 0; |
||
1966 | js_function[INTERACTIVE] = 1; |
||
1967 | fprintf(js_include_file,"var slider%d;dragdrop_precision = %d;use_dragdrop_reply = true;",use_slider,precision); |
||
18557 | bpr | 1968 | tmp_buffer=my_newmem(MAX_BUFFER); |
1969 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "slider%d = new move_group(%d);\n",use_slider,use_slider)); |
||
18552 | bpr | 1970 | add_to_buffer(tmp_buffer); |
1971 | break; |
||
1972 | case HALFLINE: |
||
1973 | /* |
||
1974 | @ demiline x1,y1,x2,y2,color |
||
1975 | @ alternative: halfline |
||
1976 | @ draws a halfline starting in (x1:y1) and through (x2:y2) in color 'color' (colorname or hex) |
||
1977 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
1978 | @%halfline%size 400,400%xrange -10,10%yrange -10,10%halfline -5,5,0,0,red%halfline -5,-5,0,0,blue |
||
1979 | */ |
||
1980 | for(i=0; i<13;i++){double_data[i]=0;} |
||
1981 | for(i=0;i<5;i++){ |
||
1982 | switch(i){ |
||
1983 | case 0: double_data[0]= get_real(infile,0);break; /* x-values */ |
||
1984 | case 1: double_data[1]= get_real(infile,0);break; /* y-values */ |
||
1985 | case 2: double_data[10]= get_real(infile,0);break; /* x-values */ |
||
1986 | case 3: double_data[11]= get_real(infile,0);break; /* y-values */ |
||
1987 | case 4: stroke_color=get_color(infile,1);/* name or hex color */ |
||
1988 | if(double_data[0] == double_data[10]){ /* vertical halfline */ |
||
1989 | if(double_data[1] < double_data[11]){ |
||
1990 | double_data[3] = ymax + 1000; |
||
1991 | } |
||
1992 | else { |
||
1993 | double_data[3] = ymin - 1000; |
||
1994 | } |
||
1995 | double_data[2] = double_data[0]; |
||
1996 | } else { /* horizontal halfline*/ |
||
1997 | if( double_data[1] == double_data[11] ){ |
||
1998 | if( double_data[0] < double_data[10] ){ |
||
1999 | double_data[2] = xmax + 1000; /* halfline to the right */ |
||
2000 | } |
||
2001 | else { |
||
2002 | double_data[2] = xmin - 1000; /* halfline to the left */ |
||
2003 | } |
||
2004 | double_data[3] = double_data[1]; |
||
2005 | } |
||
2006 | else { |
||
2007 | /* any other halfline */ |
||
2008 | /* slope */ |
||
2009 | double_data[12] = (double_data[11] - double_data[1])/(double_data[10] - double_data[0]); |
||
2010 | /* const */ |
||
2011 | double_data[13] = double_data[1] - double_data[12]*double_data[0]; |
||
2012 | if( double_data[0] < double_data[10] ){ |
||
2013 | double_data[2] = double_data[2] + 1000; |
||
2014 | } |
||
2015 | else { |
||
2016 | double_data[2] = double_data[2] - 1000; |
||
2017 | } |
||
2018 | double_data[3] = double_data[12]*double_data[2] + double_data[13]; |
||
2019 | } |
||
2020 | } |
||
2021 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2022 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
2023 | if(use_affine == TRUE ){ transform(4,2);} |
||
18557 | bpr | 2024 | tmp_buffer=my_newmem(MAX_BUFFER); |
2025 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,18,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2026 | add_to_buffer(tmp_buffer); |
2027 | if(onclick != 0){object_cnt++;} |
||
2028 | /* object_cnt++; */ |
||
2029 | reset(); |
||
2030 | break; |
||
2031 | } |
||
2032 | } |
||
2033 | dragstuff[18] = 1; |
||
2034 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2035 | break; |
||
2036 | case HALFLINES: |
||
2037 | /* |
||
2038 | @ demilines color,x1,y1,x2,y2,.... |
||
2039 | @ alternative: halflines |
||
2040 | @ draws halflines starting in (x1:y1) and through (x2:y2) in color 'color' (colorname or hex) etc |
||
2041 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> indiviually |
||
2042 | @%halflines%size 400,400%xrange -10,10%yrange -10,10%halflines red,-5,5,0,0,-5,-5,0,0 |
||
2043 | */ |
||
2044 | stroke_color=get_color(infile,0); |
||
2045 | fill_color = stroke_color; |
||
2046 | i=0; |
||
2047 | while( ! done ){ /* get next item until EOL*/ |
||
2048 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
2049 | if(i%2 == 0 ){ |
||
2050 | double_data[i] = get_real(infile,0); /* x */ |
||
2051 | } else { |
||
2052 | double_data[i] = get_real(infile,1); /* y */ |
||
2053 | } |
||
2054 | i++; |
||
2055 | } |
||
2056 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2057 | decimals = find_number_of_digits(precision); |
||
2058 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
2059 | if( double_data[c] == double_data[c+2] ){ /* vertical line*/ |
||
2060 | if(double_data[c+1] < double_data[c+3]){ /* upright halfline */ |
||
2061 | double_data[c+3] = ymax + 1000; |
||
2062 | } |
||
2063 | else { |
||
2064 | double_data[c+3] = ymin - 1000;/* descending halfline */ |
||
2065 | } |
||
2066 | } |
||
2067 | else { |
||
2068 | if( double_data[c+1] == double_data[c+3] ){ /* horizontal line */ |
||
2069 | if(double_data[c] < double_data[c+2] ){ /* halfline to the right */ |
||
2070 | double_data[c+2] = xmax+100; |
||
2071 | } |
||
2072 | else { |
||
2073 | double_data[c+2] = xmin-1000; /* halfline to the right */ |
||
2074 | } |
||
2075 | } |
||
2076 | else { |
||
2077 | /* m */ |
||
2078 | double m = (double_data[c+3] - double_data[c+1]) /(double_data[c+2] - double_data[c]); |
||
2079 | /* q */ |
||
2080 | double q = double_data[c+1] - ((double_data[c+3] - double_data[c+1]) /(double_data[c+2] - double_data[c]))*double_data[c]; |
||
2081 | if(double_data[c] < double_data[c+2]){ /* to the right */ |
||
2082 | double_data[c+2] = xmax+1000; /* 1000 is needed for dragging...otherwise it is just segment */ |
||
2083 | double_data[c+3] = (m)*(double_data[c+2])+(q); |
||
2084 | } |
||
2085 | else { /* to the left */ |
||
2086 | double_data[c+2] = xmin - 1000; |
||
2087 | double_data[c+3] = (m)*(double_data[c+2])+(q); |
||
2088 | } |
||
2089 | } |
||
2090 | } |
||
2091 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
2092 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
18557 | bpr | 2093 | tmp_buffer=my_newmem(MAX_BUFFER); |
2094 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,18,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2095 | add_to_buffer(tmp_buffer); |
2096 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
2097 | } |
||
2098 | reset(); |
||
2099 | dragstuff[18] = 1; |
||
2100 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2101 | break; |
||
2102 | case HATCHFILL: |
||
2103 | /* |
||
2104 | @ hatchfill x0,y0,dx,dy,color |
||
2105 | @ x0,y0 in xrange / yrange |
||
2106 | @ distances dx,dy in pixels |
||
2107 | @ there is also a command <a href="#userdraw">userdraw hatchfill,color</a> |
||
2108 | @%hatchfill%size 400,400%xrange -10,10%yrange -10,10%canvastype 100%linewidth 2%precision 1000%jsplot blue,5*sin(x)%opacity 200,50%hatchfill 6,6,10,10,blue%hatchfill 6,-6,6,6,red |
||
2109 | */ |
||
2110 | js_function[DRAW_HATCHFILL] = 1; |
||
2111 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
2112 | js_function[DRAW_FILLTOBORDER] = 1; |
||
2113 | add_js_filltoborder(canvas_type); |
||
2114 | } |
||
2115 | decimals = find_number_of_digits(precision); |
||
2116 | for(i=0;i<5;i++){ |
||
2117 | switch(i){ |
||
2118 | case 0: double_data[0] = get_real(infile,0); break; /* x */ |
||
2119 | case 1: double_data[1] = get_real(infile,0); break; /* y */ |
||
2120 | case 2: int_data[0] = (int) (get_real(infile,0)); break; /* dx pixel */ |
||
2121 | case 3: int_data[1] = (int) (get_real(infile,0)); break; /* dy pixel*/ |
||
2122 | case 4: stroke_color = get_color(infile,1); |
||
2123 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
2124 | if(use_affine == TRUE ){ transform(2,2);} |
||
2125 | /* draw_hatchfill(ctx,x0,y0,dx,dy,linewidth,color,opacity,xsize,ysize) */ |
||
18557 | bpr | 2126 | tmp_buffer=my_newmem(MAX_BUFFER); |
2127 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_hatchfill(%d,%.*f,%.*f,%d,%d,%d,\"%s\",%.2f,%d,%d);\n",STATIC_CANVAS+fill_cnt,decimals,double_data[0],decimals,double_data[1],int_data[0],int_data[1],line_width,stroke_color,stroke_opacity,xsize,ysize)); |
||
18552 | bpr | 2128 | add_to_buffer(tmp_buffer); |
2129 | fill_cnt++; |
||
2130 | reset(); |
||
2131 | break; |
||
2132 | default:break; |
||
2133 | } |
||
2134 | } |
||
2135 | break; |
||
2136 | case HLINE: |
||
2137 | /* |
||
2138 | @ hline x,y,color |
||
2139 | @ alternative: horizontalline |
||
2140 | @ draw a horizontal line through point (x:y) in color 'color' |
||
2141 | @ or use command <a href='#curve'>curve color,formula</a> to draw the line (uses more points to draw the line; is however better draggable) |
||
2142 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
2143 | @%hline%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%hline 0,0,red%dhline 0,5,blue |
||
2144 | */ |
||
2145 | for(i=0;i<3;i++) { |
||
2146 | switch(i){ |
||
2147 | case 0: double_data[0] = get_real(infile,0);break; /* x-values */ |
||
2148 | case 1: double_data[1] = get_real(infile,0);break; /* y-values */ |
||
2149 | case 2: stroke_color = get_color(infile,1);/* name or hex color */ |
||
2150 | double_data[3] = double_data[1]; |
||
2151 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
2152 | if(use_affine == TRUE ){ transform(2,2);} |
||
2153 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2154 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 2155 | tmp_buffer=my_newmem(MAX_BUFFER); |
2156 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,100*xmin,decimals,100*xmax,decimals,double_data[1],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2157 | add_to_buffer(tmp_buffer); |
2158 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
2159 | dragstuff[4] = 1; |
||
2160 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2161 | reset(); |
||
2162 | break; |
||
2163 | } |
||
2164 | } |
||
2165 | break; |
||
2166 | case HLINES: |
||
2167 | /* |
||
2168 | @ hlines color,x1,y1,x2,y2,... |
||
2169 | @ alternative: horizontallines |
||
2170 | @ draw horizontal lines through points (x1:y1)...(xn:yn) in color 'color' |
||
2171 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
||
2172 | @%hlines%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%hlines red,0,0,0,5,0,-5 |
||
2173 | */ |
||
2174 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
2175 | fill_color = stroke_color; |
||
2176 | i=0; |
||
2177 | while( ! done ){ /* get next item until EOL*/ |
||
2178 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
2179 | if(i%2 == 0 ){ |
||
2180 | double_data[i] = get_real(infile,0); /* x */ |
||
2181 | } |
||
2182 | else { |
||
2183 | double_data[i] = get_real(infile,1); /* y */ |
||
2184 | } |
||
2185 | i++; |
||
2186 | } |
||
2187 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
2188 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
2189 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
11806 | schaersvoo | 2190 | |
18552 | bpr | 2191 | decimals = find_number_of_digits(precision); |
2192 | for(c = 0 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 2193 | tmp_buffer=my_newmem(MAX_BUFFER); |
18607 | bpr | 2194 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,100*xmin,decimals,100*xmax,decimals,double_data[c+1],decimals,double_data[c+1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 2195 | add_to_buffer(tmp_buffer); |
2196 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
2197 | } |
||
2198 | reset(); |
||
2199 | dragstuff[4] = 1; |
||
2200 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2201 | break; |
||
2202 | case HTTP: |
||
2203 | /* |
||
18556 | bpr | 2204 | @ http x1,y1,x2,y2,http://some_adress.com |
2205 | @ an active html-page will be displayed in an "iframe" rectangle left top (x1:y1), right bottom (x2:y2) |
||
2206 | @ do not use interactivity (or mouse) if the mouse needs to be active in the iframe |
||
2207 | @ can <b>not</b> be ''set onclick`` or ''drag xy`` |
||
2208 | @%http%size 400,400%xrange -10,10%yrange -10,10%http 0,10,10,0,http://wims.unice.fr%opacity 200,50%drag xy%fcircle 0,0,100,green |
||
18552 | bpr | 2209 | */ |
2210 | js_function[DRAW_HTTP] = 1; |
||
2211 | for(i=0;i<5;i++){ |
||
2212 | switch(i){ |
||
2213 | case 0: int_data[0]=x2px(get_real(infile,0));break; /* x in x/y-range coord system -> pixel width */ |
||
2214 | case 1: int_data[1]=y2px(get_real(infile,0));break; /* y in x/y-range coord system -> pixel height */ |
||
2215 | case 2: int_data[2]=x2px(get_real(infile,0)) - int_data[0];break; /* width in x/y-range coord system -> pixel width */ |
||
2216 | case 3: int_data[3]=y2px(get_real(infile,0)) - int_data[1];break; /* height in x/y-range coord system -> pixel height */ |
||
2217 | case 4: decimals = find_number_of_digits(precision); |
||
2218 | temp = get_string(infile,1); |
||
2219 | if(strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","'");} |
||
18557 | bpr | 2220 | tmp_buffer = my_newmem(string_length+2); |
2221 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_http(%d,%d,%d,%d,%d,\"%s\");\n",canvas_root_id,int_data[0],int_data[1],int_data[2],int_data[3],temp)); |
||
18552 | bpr | 2222 | add_to_buffer(tmp_buffer); |
2223 | break; |
||
2224 | } |
||
2225 | } |
||
2226 | reset(); |
||
2227 | break; |
||
2228 | case HTML: |
||
2229 | /* |
||
18556 | bpr | 2230 | @ html x1,y1,html_string |
2231 | @ all tags are allowed, html code using inputfields could be read using your own javascript code. Do not use ids like 'canvas_input0' etc. |
||
2232 | @ can be set <a href='#onclick'>onclick</a> and <a href='#drag'>drag&drop</a> |
||
2233 | @ command <a href='#affine'>affine</a> will produce CSS3 matrix transformations |
||
2234 | @ command <a href='#rotate'>rotate</a> will rotate the object |
||
2235 | @ use keyword <a href='#centered'>centered</a> to center the html object on (x1:y1) |
||
2236 | @ note: using drag&drop for all external P,SPAN,DIV,IMG,SVG-images onto a canvasdraw element, use ''onclick=javascript:place_image_on_canvas(this.id)`` |
||
2237 | @ note: sub & sup are supported in command family <a href='#string'>string</a>, e.g. real internal canvas objects ! |
||
2238 | @%html-text%size 500,500%xrange -10,10%yrange -10,10%drag xy%centered%fillcolor lightblue%html 2,2,<h1 style='color:red'>DRAG ME</h1> %opacity 200,50%drag xy%fcircle 0,0,100,green |
||
2239 | @%html-image-slider%size 500,500%xrange -10,10%yrange -10,10%fontsize 42%rotationcenter 0,0%centered%html 0,0,<img src="http://85.148.206.56/gifs/can1.gif">%slider 0,pi,400,40,angle active degree, %centered%html 0,0,<img src="http://85.148.206.56/gifs/can2.gif"> |
||
18552 | bpr | 2240 | */ |
2241 | js_function[DRAW_XML] = 1; |
||
2242 | for(i=0;i<5;i++){ |
||
2243 | switch(i){ |
||
2244 | case 0: double_data[0] = get_real(infile,0);break; |
||
2245 | case 1: double_data[1] = get_real(infile,0);break; |
||
2246 | case 4: decimals = find_number_of_digits(precision); |
||
2247 | if(use_affine == TRUE ){ transform(2,2);}/* needs double_data[] */ |
||
2248 | if( use_offset != 0 || drag_type != -1 ){int_data[2] = 1;}else{int_data[2] = 0;} /* only centered or not-centered */ |
||
2249 | int_data[0] = x2px(double_data[0]);/* needs px */ |
||
2250 | int_data[1] = y2px(double_data[1]); |
||
2251 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2252 | if( use_slider != -1 && drag_type != -1){ onclick = 5; } |
||
2253 | temp = get_string(infile,1); |
||
2254 | if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","\\\""); } |
||
2255 | if( strstr(temp,"<img ")!= 0){URL="image";}else{URL="html";} |
||
18557 | bpr | 2256 | tmp_buffer=my_newmem(MAX_BUFFER); |
2257 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var draw_xml%d = {id:%d,type:'%s',x:[%d],y:[%d],mathml:\"%s\",drag_type:%d,onclick:%d,object_cnt:%d,stroke_color:\"%s\",stroke_opacity:%.2f,fill_color:\"%s\",fill_opacity:%.2f,use_center:%d,use_snap:%d,angle:%f,fontfamily:\"%s\",transform:%s,use_affine:%d,offset:[0,0],use_slider:%s,rotation_center:%s,once:true};slidergroup[%d] = null;draw_xml(draw_xml%d);\n",drawxml_cnt,drawxml_cnt,URL,int_data[0],int_data[1],temp,drag_type,onclick,object_cnt,stroke_color,stroke_opacity,fill_color,fill_opacity,int_data[2],use_snap,angle,font_family,doubledata2js_array(affine_matrix,6,decimals),use_affine,my_sliders,rotation_center,object_cnt,drawxml_cnt)); |
||
18552 | bpr | 2258 | add_to_buffer(tmp_buffer); |
2259 | if(onclick != 0 ){object_cnt++;} |
||
2260 | drawxml_cnt++;/* keeps track on imported img,div,p,span,mathml,svg */ |
||
2261 | break; |
||
2262 | default:break; |
||
2263 | } |
||
2264 | } |
||
2265 | reset(); |
||
2266 | break; |
||
2267 | case IMAGEFILL: |
||
2268 | /* |
||
2269 | @ imagefill x,y,scaling to xsize × ysize?,image_url |
||
2270 | @ The next suitable <b>filled object</b> will be filled with "image_url" tiled |
||
2271 | @ scaling to xsize × ysize ? ... 1 = yes 0 = no |
||
2272 | @ After pattern filling, the fill-color should be reset ! |
||
2273 | @ wims getins / image from class directory: imagefill 80,80,my_image.gif |
||
2274 | @ normal url: imagefill 80,80,0,$module_dir/gifs/my_image.gif |
||
2275 | @ normal url: imagefill 80,80,1,http://adres/a/b/c/my_image.jpg |
||
2276 | @ if dx,dy is larger than the image, the whole image will be background to the next object. |
||
2277 | @%imagefill_tile%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%circles blue,0,0,5,3,2,5%imagefill 1.5,1.5,0,gifs/en.gif%imagefill -5,5,0,gifs/logo/wimsedu.png |
||
2278 | @%imagefill_scale%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%circles blue,0,0,5,3,2,5%imagefill 1.5,1.5,1,gifs/en.gif%imagefill -5,5,1,gifs/logo/wimsedu.png |
||
2279 | */ |
||
2280 | js_function[DRAW_IMAGEFILL] = 1; |
||
2281 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
2282 | js_function[DRAW_FILLTOBORDER] = 1; |
||
2283 | add_js_filltoborder(canvas_type); |
||
2284 | } |
||
2285 | for(i=0 ;i < 4 ; i++){ |
||
2286 | switch(i){ |
||
2287 | case 0:int_data[0] = (int) (get_real(infile,0));break; |
||
2288 | case 1:int_data[1] = (int) (get_real(infile,0));break; |
||
2289 | case 2:int_data[2] = (int) (get_real(infile,0));break; /* 0 | 1 */ |
||
2290 | case 3: URL = get_string_argument(infile,1); |
||
18557 | bpr | 2291 | tmp_buffer=my_newmem(MAX_BUFFER); |
2292 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_imagefill(%d,%d,%d,\"%s\",%d,%d,%d,%d);\n",STATIC_CANVAS+fill_cnt,int_data[0],int_data[1],URL,xsize,ysize,use_userdraw,int_data[2])); |
||
18552 | bpr | 2293 | add_to_buffer(tmp_buffer); |
2294 | fill_cnt++; |
||
2295 | break; |
||
2296 | } |
||
2297 | } |
||
2298 | reset(); |
||
2299 | break; |
||
2300 | case IMAGEPALETTE: |
||
2301 | /* |
||
18556 | bpr | 2302 | @ imagepalette image1,image2,image3,... |
2303 | @ if used before and together with command <a href='#multidraw'>multidraw images,..,..., etc</a> the image will be presented in a small table in the ''control panel``. |
||
2304 | @%imagepalette%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%copy 0,0,-1,-1,-1,-1,gifs/images/skull_and_crossbones50.png%fontcolor green%fontfamily Bold 42pt Arial%imagepalette gifs/ca.gif,gifs/en.gif,gifs/nl.gif,gifs/fr.gif,gifs/cn.gif,gifs/de.gif,gifs/kh.gif,gifs/it.gif%multiuserinput 0,0,1%css color:blue;%multisnaptogrid 1,1,1%multilinewidth 0,4,0%# attention: use unicode text input without the slash %# \u222D ---> u222D at least will sometimes work%# otherwise cut&past unicode symbols into inputfield...%multilabel TEXT,REACTION ARROW,FLAGS,STOP DRAWING%multidraw text,arrow,images |
||
18552 | bpr | 2305 | */ |
2306 | temp = get_string(infile,1); |
||
2307 | temp = str_replace(temp,",","\",\""); |
||
2308 | if( use_tooltip == 1 ){canvas_error("command 'imagepalette' is incompatible with command 'intooltip tip_text',as they use the same div-element ");} |
||
2309 | fprintf(js_include_file,"\nvar current_id;var imagepalette = [\" %s \"];\n",temp); |
||
2310 | break; |
||
2311 | case INPUT: |
||
2312 | /* |
||
18556 | bpr | 2313 | @ input x,y,size,editable,value |
2314 | @ to set inputfield "readonly", use editable = 0 |
||
2315 | @ if no preset 'value' is needed...use a 'space' as last item argument |
||
2316 | @ only active inputfields (editable = 1) will be read with read_canvas(); |
||
2317 | @ if ''$status=done`` (e.g. in answer.phtml) the inputfield will be cleared and set readonly<br>override this by keyword <a href="#status">status</a> |
||
2318 | @ may be further controlled by <a href="#css">css</a> |
||
2319 | @ if mathml inputfields are present and / or some userdraw is performed, these data will <b>not</b> be send as well (javascript:read_canvas();) |
||
2320 | @ use keyword <a href='#xoffset'>xoffset | centered</a> if the inputfield should be centered on (x:y)<br> default is the left top corner is (x:y) |
||
2321 | @ if the student must place an inputfield(s) somewhere on the canvas, use command <a href="#userdraw">userdraw input,color</a> or make use of a command like <a href="#userdraw">userdraw text,color</a> |
||
2322 | @%input%size 400,400%xrange -10,10%yrange -10,10%linewidth 6%point 1,2,red%input 1,2,5,1, ?%point -5,5,red%input -5,5,5,1, ?%point 6,-5,red%input 6,-5,5,1, ?%point -5,-8,red%input -5,-8,5,1, ? |
||
18552 | bpr | 2323 | */ |
2324 | js_function[DRAW_INPUTS] = 1; |
||
2325 | for(i = 0 ; i<5;i++){ |
||
2326 | switch(i){ |
||
2327 | case 0: int_data[0]=x2px(get_real(infile,0));break;/* x in px */ |
||
2328 | case 1: int_data[1]=y2px(get_real(infile,0));break;/* y in px */ |
||
2329 | case 2: int_data[2]=abs( (int)(get_real(infile,0)));break; /* size */ |
||
2330 | case 3: if( get_real(infile,1) >0){int_data[3] = 1;}else{int_data[3] = 0;};break; /* readonly */ |
||
2331 | case 4: temp = get_string(infile,3); |
||
18557 | bpr | 2332 | tmp_buffer=my_newmem(MAX_BUFFER); |
2333 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_static_inputs(%d,%d,%d,%d,%d,%d,\"%s\",\"%s\",%d);\n",canvas_root_id,input_cnt,int_data[0],int_data[1],int_data[2],int_data[3],css_class,temp,use_offset)); |
||
18552 | bpr | 2334 | add_to_buffer(tmp_buffer); |
2335 | input_cnt++;break; |
||
2336 | default: break; |
||
2337 | } |
||
2338 | } |
||
2339 | if(reply_format == 0 ){reply_format = 15;} |
||
2340 | reset(); |
||
2341 | break; |
||
2342 | case INTOOLTIP: |
||
18556 | bpr | 2343 | /* |
2344 | @ intooltip link_text |
||
2345 | @ link_text is a single line (span-element) |
||
2346 | @ link_text may also be an image URL ''http://some_server/images/my_image.png`` or ''$module_dir/gifs/my_image.jpg`` |
||
2347 | @ link_text may contain HTML markup |
||
2348 | @ the canvas will be displayed in a tooltip on ''link_text`` |
||
2349 | @ the canvas is default transparent: use command <a href="#bgcolor">bgcolor color</a> to adjust background-color, the link text will also be shown with this 'bgcolor'. |
||
2350 | @ many ''userinput stuff`` will use the tooltip_placeholder_div element...only one is defined in the wims-page<br>and are therefore these commands are mutually exclusive.<br>keep this in mind... |
||
2351 | @%intooltip%size 400,400%xrange -10,10%yrange -10,10%fontfamily Bold 42pt Courier%string black,0,0,Hello World%intooltip <span style="background-color:black;color:white;font-style:bold;font-size:48pt;">CLICK <br>HERE</span> |
||
2352 | */ |
||
18552 | bpr | 2353 | if(use_input_xy != FALSE ){canvas_error("intooltip can not be combined with userinput_xy or other commands using the tooltip-div...see documentation");} |
2354 | if( use_tooltip == 1 ){ canvas_error("command 'intooltip' cannot be combined with command 'popup'...");} |
||
2355 | tooltip_text = get_string(infile,1); |
||
2356 | if(strstr(tooltip_text,"\"") != 0 ){ tooltip_text = str_replace(tooltip_text,"\"","'"); } |
||
2357 | use_tooltip = 1; |
||
2358 | break; |
||
2359 | case JSCURVE: |
||
2360 | /* |
||
18556 | bpr | 2361 | @ jscurve color,formula1(x),formula2(x),formula3(x),... |
2362 | @ alternative: jsplot |
||
2363 | @ your function will be plotted by the javascript engine of the client browser |
||
2364 | @ if <a href='trange'>trange</a> is defined, the two functions will be plotted parametric<br><b>note</b>: use <i>x</i> as variable...and not <i>t</i>. Use keyword <a href='#animate'>animate</a> to animate a point on the curve |
||
2365 | @ use only basic math in your curve: <code>sqrt,^,asin,acos,atan,log,pi,abs,sin,cos,tan,e</code> |
||
2366 | @ use parenthesis and rawmath: use 2*x instead of 2x ; use 2^(sin(x))...etc etc (use error console to debug any errors...) |
||
2367 | @ <b>attention</b>: last ''precision`` command in the canvasdraw script determines the calculation precision of the javascript curve plot ! |
||
2368 | @ no validity check is done by wims. |
||
2369 | @ zooming & panning are implemented:<br>use command ''zoom color`` for mouse driven zooming<br>or use keyword 'setlimits' for inputfields setting xmin/xmax, ymin/ymax |
||
2370 | @ zooming & panning is better than for curves produced by command <a href="#curve">curve color,formula</a> because for avery change in x/y-range the curve is recalculated in javascript |
||
2371 | @ zooming & panning in case of userbased functionplot: reclick the OK button to re-plot curve onto the resized grid |
||
2372 | @ use keyword <a href='animate'>animate</a> for animating a point on the curve |
||
2373 | @ use command ''trace_jscurve formula(x)`` for tracing |
||
2374 | @ use command ''jsmath formula(x)`` for calculating and displaying indiviual points on the curve |
||
2375 | @ can <b>not</b> be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> (yet) |
||
2376 | @ commands plotjump / plotstep are not active for ''jscurve`` |
||
2377 | @ every command jscurve will produce a new canvas (canvastype 111,112,113...) for this one curve. |
||
18572 | bpr | 2378 | @ plotting multiple js-curves on the same canvas (for example if you want to use 'userdraw clickfill,color' on <a href="#canvastype">canvastype</a> number 111, use:<br> <code>jscurve red,fun1(x),fun2(x)...fun_n(x)</code>, you must specify individual multistrokecolors & multistrokeopacity & multilinewidth for these multiple js-curves to use different colors. Otherwise all curves will be the same color... Use commands like: <a href="#multistrokecolors">multistrokecolors</a>, <a href="#multilinewidth">multilinewidth</a>, <a href="#multidash">multidash</a>, <a href="#multistrokeopacity">multistroke</a>, <b>color</b> given for the command <code>jscurve color,formulas(x)</code> will not be used in that case... but the color argument must still be given in any case (otherwise syntax error...) |
18556 | bpr | 2379 | @%jscurve%size 400,400%xrange -10,10%yrange -10,10%multistrokecolors red,green,blue,orange%multilinewidth 1,2,3%multistrokeopacity 0.5,0.8,1.0%jscurve red,sin(x),1/sin(x),sin(x^2) |
18552 | bpr | 2380 | */ |
2381 | jsplot_cnt++;/* -1 --> 0 */ |
||
2382 | stroke_color = get_color(infile,0); |
||
2383 | js_function[JS_MATH] = 1; |
||
2384 | js_function[JS_PLOT] = 1; |
||
2385 | if( tmin != 0 && tmax !=0){use_parametric = TRUE;} |
||
2386 | temp = get_string(infile,1); |
||
2387 | temp = str_replace(temp,",","\",\""); |
||
18557 | bpr | 2388 | tmp_buffer=my_newmem(MAX_BUFFER); |
2389 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var js_plot%d = function(){jsplot(%d,[\"%s\"],[%d],[\"%s\"],[%.2f],[%d],%d,%d,[%f,%f],%d,%d,%d,0);};js_plot%d();",jsplot_cnt,JSPLOT_CANVAS+jsplot_cnt,temp,line_width,stroke_color,stroke_opacity,use_dashed,dashtype[0],dashtype[1],tmin,tmax,plot_steps,use_parametric,use_animate,jsplot_cnt)); |
||
18552 | bpr | 2390 | add_to_buffer(tmp_buffer); |
2391 | fprintf(js_include_file,"if(typeof(all_jsplots) !== 'number'){var all_jsplots;};all_jsplots = %d;",jsplot_cnt); |
||
11806 | schaersvoo | 2392 | |
18552 | bpr | 2393 | /* we need to create multiple canvasses, so we may zoom and pan ?? */ |
2394 | break; |
||
2395 | case JSMATH: |
||
2396 | /* |
||
18556 | bpr | 2397 | @ jsmath some_math_function |
2398 | @ will calculate an y-value from a userinput x-value and draws a crosshair on these coordinates. |
||
2399 | @ default labels ''x`` and ''y``; the commands ''xlabel some_x_axis_name`` and ''ylabel some_y_axis_name`` will set the label for the input fields |
||
2400 | @ use command 'css some_css' for styling the display fields. Use command 'fontsize int' to size the labels ''x`` and ''y`` |
||
2401 | @ the client browser will convert your math function to javascript math.<br>use parenthesis and rawmath: use 2*x instead of 2x etc etc<br>no check is done on the validity of your function and/or syntax<br>use error console to debug any errors... |
||
2402 | @ be aware that the formula's of the plotted function(s) can be found in the page javascript source |
||
2403 | @%jsmath%size 400,400%xrange -10,10%yrange -10,10%jsplot blue,sin(x^2)%jsmath sin(x^2) |
||
18552 | bpr | 2404 | */ |
2405 | js_function[DRAW_CROSSHAIRS] = 1; |
||
2406 | js_function[JS_MATH] = 1; |
||
2407 | add_calc_y(get_string(infile,1),font_size,css_class); |
||
2408 | break; |
||
2409 | case KILL: |
||
2410 | /* |
||
2411 | @ kill arguments |
||
2412 | @ arguments may be: affine linear translation rotation slider offset reset |
||
2413 | @ for documentation see: killaffine,killlinear,killtranslation... |
||
2414 | @ multiple arguments are allowed (although not checked for validity...) |
||
2415 | */ |
||
2416 | temp = get_string(infile,1); |
||
2417 | if(strstr(temp,"affine") != 0 ){use_affine = FALSE;affine_matrix[0] = 1.0;affine_matrix[1] = 0.0;affine_matrix[2] = 0.0;affine_matrix[3] = 1.0;affine_matrix[4] = 0.0;affine_matrix[5] = 0.0;} |
||
2418 | if(strstr(temp,"linear") != 0 ){affine_matrix[0] = 1.0;affine_matrix[1] = 0.0;affine_matrix[2] = 0.0;affine_matrix[3] = 1.0;} |
||
2419 | if(strstr(temp,"translation") != 0 || strstr(temp,"translate") != 0 ){affine_matrix[4] = 0.0;affine_matrix[5] = 0.0;} |
||
2420 | if(strstr(temp,"rotation") != 0 || strstr(temp,"rotate") != 0 ){use_rotate = FALSE;angle = 0.0;rotation_center="null";} |
||
2421 | if(strstr(temp,"slider") != 0 ){slider_type = "0";my_sliders = "[-1]";last_slider = use_slider+1;} |
||
2422 | if(strstr(temp,"group") != 0 ){onclick = 0;drag_type = -1;slider_type = "0";my_sliders = "[-1]";last_slider = use_slider+1;use_slider = -1;reset();} |
||
2423 | if(strstr(temp,"reset") != 0 ){if(no_reset == FALSE){no_reset = TRUE;}else{no_reset = FALSE;reset();}} |
||
2424 | if(strstr(temp,"offset") != 0 ){use_offset = 0;} |
||
2425 | break; |
||
2426 | case KILLAFFINE: |
||
2427 | /* |
||
2428 | @ killaffine |
||
2429 | @ keyword: resets the transformation matrix to 1,0,0,1,0,0 |
||
2430 | @ note: any active linear transformation will also be reset: tx=0, ty=0 |
||
2431 | */ |
||
2432 | use_affine = FALSE; |
||
2433 | affine_matrix[0] = 1.0; |
||
2434 | affine_matrix[1] = 0.0; |
||
2435 | affine_matrix[2] = 0.0; |
||
2436 | affine_matrix[3] = 1.0; |
||
2437 | affine_matrix[4] = 0.0; |
||
2438 | affine_matrix[5] = 0.0; |
||
2439 | break; |
||
2440 | case KILLLINEAR: |
||
2441 | /* |
||
2442 | @ killlinear |
||
2443 | @ keyword: resets the transformation matrix to 1,0,0,1,tx,ty |
||
2444 | @ note:any active transformation or rotation will not be killed (tx,ty remain active) |
||
2445 | */ |
||
2446 | affine_matrix[0] = 1.0; |
||
2447 | affine_matrix[1] = 0.0; |
||
2448 | affine_matrix[2] = 0.0; |
||
2449 | affine_matrix[3] = 1.0; |
||
2450 | break; |
||
2451 | case KILLROTATE: |
||
2452 | /* |
||
18556 | bpr | 2453 | @ killrotate |
2454 | @ will set the rotation angle to 0. |
||
18572 | bpr | 2455 | @ will also reset the command <a href="#rotationcenter">rotationcenter</a> to the first (x;y) of the next rotatable/slidable object(s) <br>eg a following rotate command will have the first object point as rotation center |
18556 | bpr | 2456 | @ if not set, the rotation center will remain unchanged |
2457 | @ note:any active transformation or linear will not be killed (e.g an active transformation matrix remains active) |
||
2458 | @%killrotate%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%rotationcenter 0,0%# slider is active for all following objects until 'killslider'%slider -10,10,300,40,angle degree,Rotate%drag xy%# after dragging the object must be clicked to re-activate the slider%linewidth 4%arrow 0,0,6,0,9,blue%%# reset rotation center to the first (x,y) of the next object/arrow...%killrotate%drag xy%# after dragging the object must be clicked to re-activate the slider%arrow 0,0,6,1,9,red |
||
18552 | bpr | 2459 | */ |
2460 | use_rotate = FALSE; |
||
2461 | angle = 0.0; |
||
2462 | rotation_center="null"; |
||
2463 | break; |
||
2464 | case KILLSLIDER: |
||
2465 | /* |
||
18556 | bpr | 2466 | @ killslider |
2467 | @ keyword (no arguments required) |
||
2468 | @ ends grouping of object under a previously defined slider |
||
18552 | bpr | 2469 | */ |
2470 | slider_type = "0"; |
||
2471 | my_sliders = "[-1]"; |
||
2472 | last_slider = use_slider+1; |
||
2473 | break; |
||
2474 | case KILLTRANSLATION: |
||
2475 | /* |
||
18556 | bpr | 2476 | @ killtranslation |
2477 | @ alternative: killtranslate |
||
2478 | @ note: a active linear or affine transformation will not be 100% reset...only tx=0,ty=0 |
||
2479 | @ resets the translation matrix a,b,c,d,tx,ty to a,b,c,d,0,0 |
||
18552 | bpr | 2480 | */ |
2481 | affine_matrix[4] = 0.0; |
||
2482 | affine_matrix[5] = 0.0; |
||
2483 | break; |
||
2484 | case LATEX: |
||
2485 | /* |
||
18556 | bpr | 2486 | @ latex x,y,tex string |
2487 | @ alternative: math |
||
18572 | bpr | 2488 | @ note: <b>for a single greek letter</b> ,please be smart and use a command like <a href='#string'>string</a> along with <b>unicode</b> !! <br>possibly together with command <a href="#xyoffset">xoffset, yoffset or xyoffset</a><br> See <a target='new' href='https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode'>https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode</a><br> See <a target='new' href='https://en.wikipedia.org/wiki/Greek_script_in_Unicode'>https://en.wikipedia.org/wiki/Greek_script_in_Unicode</a> |
18556 | bpr | 2489 | @ you may also use command <a href="#mathml">mathml</a> for xml strings generated with wims commmand ''mathmlmath`` (will not work on KaTeX enabled WIMS) |
2490 | @ transformation commands <a href='#affine'>affine</a>, <a href='#translation'>translation</a> and <a href='#rotate'>rotate</a> are supported.(onclick and drag will work) |
||
2491 | @ can be set onclick: <code>javascript:read_dragdrop();</code> will return click numbers of mathml-objects<br>if 4 clickable object are drawn, the reply could be 1,0,1,0 ... meaning clicked on the first and third object |
||
2492 | @ can be set draggable:<code>javascript:read_dragdrop();</code> will return all coordinates in the same order as the canvas script: unmoved object will have their original coordinates... |
||
2493 | @ can be moved/rotated with command <a href='#slider'>slider</a> |
||
2494 | @ snaptogrid is supported |
||
18627 | bpr | 2495 | @ when clicked, the color of the 'div background' of the 'mathobject' will be determined by the <a href="#fillcolor">fillcolor</a> and <a href="#opacity">opacity</a> settings |
18556 | bpr | 2496 | @ userdraw may be combined with 'latex' ; the js-function 'read_canvas()' will contain the coordinates of the drawing. |
2497 | @ userdraw may be combined; the read_canvas() will contain the drawing. |
||
2498 | @ draggable or onclick 'external images' from command <a href='#copyresized'>copy or copyresized</a> and all objects from commands <a href='#html'>html</a> or <a href='#obabel'>obabel</a> can be combined with drag and/or onclick mathml |
||
2499 | @ other drag objects (circles/rects etc) are supported, but read_dragdrop() will probably be difficult to interpret... |
||
2500 | @ if inputfields are incorporated in mathml (with id's: id='mathml0',id='mathml1',...id='mathml_n')<br>the user_input values will be read by <code>javascript:read_mathml();</code>. <b>attention</b>: if after this mathml-input object other user-interactions are included, these will read mathml too using "read_canvas();" |
||
2501 | @ If other inputfields (command input / command textarea) or userdraw are performed, the function read_canvas() will not read mathml. Use some generic function to read it.... |
||
2502 | @ use keyword <a href='#centered'>centered</a> to center the katex div object on (x1:y1) <br>this may not work as expected for MathJaX [TO BE TESTED] |
||
2503 | @ note: if you want to include external TeX via drag&drop onto a canvasdraw element, use \\mmlid{integer} in the tex-command:''!insmath \\mmlid{1}\\frac{1}{\pi}``<br> (if your wims_mathml does not support it...use <a href="http://85.148.206.56/wims/download/Mathml.tar.gz">this version...</a>) |
||
2504 | @ note: the same is true for all external P,SPAN,DIV,IMG,SVG-images via drag&drop onto a canvasdraw element, use ''onclick=javascript:place_image_on_canvas(this.id)`` |
||
2505 | @%latex_drag%size 400,400%xrange -10,10%yrange -10,10%grid 2,2,grey%strokecolor red%drag xy%centered%latex -6,5,\\frac{1}{2}+ \\frac{\\pi}{2}%strokecolor blue%drag xy%centered%latex -3,5,\\frac{1}{3}+ \\frac{\\pi}{3}%strokecolor green%drag xy%centered%latex 0,5,\\frac{1}{4}+ \\frac{\\pi}{4}%strokecolor orange%drag xy%fontfamily 26px Times%centered%latex 3,5,\\frac{1}{5}+ \\frac{\\pi}{6} |
||
2506 | @%latex%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 3%vline 0,0,green%hline 0,0,green%fontfamily 16px Arial%fillcolor orange%strokecolor blue%linewidth 2%slider 0,4*pi,400,40,angle degree active, %centered%latex 0,0,\\frac{12345}{23456} \\times \\frac{12345}{23456}%translate 4,4%centered%rotate 180%drag xy%html 0,0,<table><tr><th>HTML TABLE</th></tr><tr><th><a href="https://wimsedu.info/">WIMS EDU </a> </th></tr><tr><td><img src="gifs/en.gif"></tr><tr><td><img src="gifs/nl.gif"></tr><tr><td><img src="gifs/fr.gif"></tr><tr><td><img src="gifs/cn.gif"></tr><tr><td><img src="gifs/it.gif"></tr></table>%userdraw arrow2,red |
||
18552 | bpr | 2507 | */ |
2508 | js_function[DRAW_XML] = 1; |
||
2509 | for(i=0;i<3;i++){ |
||
2510 | switch(i){ |
||
2511 | case 0: double_data[0]=get_real(infile,0);break; /* x in x/y-range coord system -> pixel width */ |
||
2512 | case 1: double_data[1]=get_real(infile,0);break; /* y in x/y-range coord system -> pixel height */ |
||
2513 | case 2: decimals = find_number_of_digits(precision); |
||
2514 | temp = get_string(infile,1); |
||
2515 | if(use_affine == TRUE ){ transform(2,2);}/* slider will use css-rotate transformation */ |
||
2516 | if( use_offset != 0 || drag_type != -1 ){int_data[2] = 1;}else{int_data[2] = 0;} /* only centered or not-centered */ |
||
2517 | int_data[0] = x2px(double_data[0]); |
||
2518 | int_data[1] = y2px(double_data[1]); |
||
2519 | if( use_slider != -1 && onclick == 0 ){ onclick = 5;} |
||
2520 | if( use_slider != -1 && drag_type != -1){ onclick = 5; } |
||
15757 | schaersvoo | 2521 | #ifdef KATEX_INSTALLED |
18552 | bpr | 2522 | if( strstr(temp,"\\") != 0 ){ temp = str_replace(temp,"\\","\\\\"); } |
2523 | if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","'"); } |
||
18557 | bpr | 2524 | tmp_buffer=my_newmem(MAX_BUFFER); |
2525 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var draw_xml%d = {id:%d,type:'katex',x:[%d],y:[%d],mathml:\"%s\",drag_type:%d,onclick:%d,object_cnt:%d,stroke_color:\"%s\",stroke_opacity:%.2f,fill_color:\"%s\",fill_opacity:%.2f,use_center:%d,use_snap:%d,angle:%f,fontfamily:\"%s\",transform:%s,use_affine:%d,offset:[0,0],use_slider:%s,rotation_center:%s,once:true};draw_xml(draw_xml%d);\n",drawxml_cnt,drawxml_cnt,int_data[0],int_data[1],temp,drag_type,onclick,object_cnt,stroke_color,stroke_opacity,fill_color,fill_opacity,int_data[2],use_snap,angle,font_family,doubledata2js_array(affine_matrix,6,decimals),use_affine,my_sliders,rotation_center,drawxml_cnt)); |
||
15757 | schaersvoo | 2526 | #else |
18552 | bpr | 2527 | temp = getMML(temp);/* generate MathML for Firefox or MathJaX */ |
2528 | if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","'"); } |
||
18557 | bpr | 2529 | tmp_buffer=my_newmem(MAX_BUFFER); |
2530 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var draw_xml%d = {id:%d,type:'mathml',x:[%d],y:[%d],mathml:\"%s\",drag_type:%d,onclick:%d,object_cnt:%d,stroke_color:\"%s\",stroke_opacity:%.2f,fill_color:\"%s\",fill_opacity:%.2f,use_center:%d,use_snap:%d,angle:%f,fontfamily:\"%s\",transform:%s,use_affine:%d,offset:[0,0],use_slider:%s,rotation_center:%s,once:true};draw_xml(draw_xml%d);\n",drawxml_cnt,drawxml_cnt,int_data[0],int_data[1],temp,drag_type,onclick,object_cnt,stroke_color,stroke_opacity,fill_color,fill_opacity,int_data[2],use_snap,angle,font_family,doubledata2js_array(affine_matrix,6,decimals),use_affine,my_sliders,rotation_center,drawxml_cnt)); |
||
15757 | schaersvoo | 2531 | #endif |
18552 | bpr | 2532 | add_to_buffer(tmp_buffer); |
2533 | if(onclick != 0 ){object_cnt++;} |
||
2534 | drawxml_cnt++;/* keeps track on imported img,div,p,span,mathml,svg */ |
||
2535 | break; |
||
2536 | default:break; |
||
2537 | } |
||
2538 | } |
||
2539 | reset(); |
||
2540 | break; |
||
2541 | case LATTICE: |
||
2542 | /* |
||
18556 | bpr | 2543 | @ lattice x0,y0,xv1,yv1,xv2,yv2,n1,n2,color |
2544 | @ can <b>not</b> be set ''onclick`` or ''drag xy`` |
||
2545 | @%lattice%size 400,400%xrange -10,10%yrange -10,10%fillcolor red%linewidth 2%lattice -10,-10,0,1,1,1,10,10,red%fillcolor blue%lattice 10,-10,0,1,-1,1,10,10,blue |
||
18552 | bpr | 2546 | */ |
2547 | js_function[DRAW_LATTICE] = 1; |
||
2548 | for( i = 0; i<9; i++){ |
||
2549 | switch(i){ |
||
2550 | case 0: int_data[0] = x2px(get_real(infile,0));break; /* x0-values -> x-pixels*/ |
||
2551 | case 1: int_data[1] = y2px(get_real(infile,0));break; /* y0-values -> y-pixels*/ |
||
2552 | case 2: int_data[2] = (int) (get_real(infile,0));break; /* x1-values -> x-pixels*/ |
||
2553 | case 3: int_data[3] = (int) -1*(get_real(infile,0));break; /* y1-values -> y-pixels*/ |
||
2554 | case 4: int_data[4] = (int) (get_real(infile,0));break; /* x2-values -> x-pixels*/ |
||
2555 | case 5: int_data[5] = (int) -1*(get_real(infile,0));break; /* y2-values -> y-pixels*/ |
||
2556 | case 6: int_data[6] = (int) (get_real(infile,0));break; /* n1-values */ |
||
2557 | case 7: int_data[7] = (int) (get_real(infile,0));break; /* n2-values */ |
||
2558 | case 8: stroke_color=get_color(infile,1); |
||
2559 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 2560 | tmp_buffer=my_newmem(MAX_BUFFER); |
2561 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_lattice(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,\"%s\",%.2f,\"%s\",%.2f,%d,%.2f,%d); ",STATIC_CANVAS,line_width,int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],int_data[5],int_data[6],int_data[7],fill_color,fill_opacity,stroke_color,stroke_opacity,use_rotate,angle,use_filled)); |
||
18552 | bpr | 2562 | add_to_buffer(tmp_buffer);break; |
2563 | default:break; |
||
2564 | } |
||
2565 | } |
||
2566 | reset(); |
||
2567 | break; |
||
2568 | case LINEAR: |
||
2569 | /* |
||
18556 | bpr | 2570 | @ linear a,b,c,d |
2571 | @ defines a transformation matrix for subsequent objects |
||
2572 | @ use keyword <a href='#killlinear'>killlinear</a> to end the transformation...the next objects will be drawn in the original x/y-range |
||
2573 | @ a: Scales the drawings horizontally |
||
2574 | @ b: Skews the drawings horizontally |
||
2575 | @ c: Skews the drawings vertically |
||
2576 | @ d: Scales the drawings vertically |
||
2577 | @ the data precision may be set by preceding command ''precision int`` |
||
2578 | @ note: any active translation (tx,ty) is not changed |
||
2579 | @%linear%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%fcircle 5,5,40,blue%linear 0.2,0,0,0.2%fcircle 5,5,40,green |
||
18552 | bpr | 2580 | */ |
2581 | for(i = 0 ; i<4;i++){ |
||
2582 | switch(i){ |
||
2583 | case 0: affine_matrix[0] = get_real(infile,0);break; |
||
2584 | case 1: affine_matrix[1] = get_real(infile,0);break; |
||
2585 | case 2: affine_matrix[2] = get_real(infile,0);break; |
||
2586 | case 3: affine_matrix[3] = get_real(infile,1); |
||
2587 | affine_matrix[4] = 0;affine_matrix[5] = 0; |
||
2588 | use_affine = TRUE; |
||
2589 | break; |
||
2590 | default: break; |
||
2591 | } |
||
2592 | } |
||
2593 | reset(); |
||
2594 | break; |
||
2595 | case LINE: |
||
2596 | /* |
||
2597 | @ line x1,y1,x2,y2,color |
||
2598 | @ draw a line through points (x1:y1)--(x2:y2) in color ''color`` |
||
2599 | @ or use command ''curve color,formula`` to draw the line (uses more points to draw the line; is however better draggable) |
||
2600 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
2601 | @%line%size 400,400%xrange -10,10%yrange -10,10%line 0,1,2,-1,green |
||
2602 | */ |
||
2603 | for(i=0;i<5;i++){ |
||
2604 | switch(i){ |
||
2605 | case 0: double_data[10]= get_real(infile,0);break; /* x-values */ |
||
2606 | case 1: double_data[11]= get_real(infile,0);break; /* y-values */ |
||
2607 | case 2: double_data[12]= get_real(infile,0);break; /* x-values */ |
||
2608 | case 3: double_data[13]= get_real(infile,0);break; /* y-values */ |
||
2609 | case 4: stroke_color=get_color(infile,1);/* name or hex color */ |
||
2610 | if( double_data[10] == double_data[12] ){ /* vertical line*/ |
||
2611 | double_data[1] = xmin; |
||
2612 | double_data[3] = ymax; |
||
2613 | double_data[0] = double_data[10]; |
||
2614 | double_data[2] = double_data[10]; |
||
2615 | } |
||
2616 | else{ |
||
2617 | if( double_data[11] == double_data[13] ){ /* horizontal line */ |
||
2618 | double_data[1] = double_data[11]; |
||
2619 | double_data[3] = double_data[11]; |
||
2620 | double_data[0] = ymin; |
||
2621 | double_data[2] = xmax; |
||
2622 | } |
||
2623 | else { |
||
2624 | /* m */ |
||
2625 | double_data[5] = (double_data[13] - double_data[11]) /(double_data[12] - double_data[10]); |
||
2626 | /* q */ |
||
2627 | double_data[6] = double_data[11] - ((double_data[13] - double_data[11]) /(double_data[12] - double_data[10]))*double_data[10]; |
||
2628 | /*xmin,m*xmin+q,xmax,m*xmax+q*/ |
||
2629 | double_data[1] = (double_data[5])*(xmin)+(double_data[6]); |
||
2630 | double_data[3] = (double_data[5])*(xmax)+(double_data[6]); |
||
2631 | double_data[0] = xmin; |
||
2632 | double_data[2] = xmax; |
||
2633 | } |
||
2634 | } |
||
2635 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
2636 | if(use_affine == TRUE ){ transform(4,2);} |
||
2637 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2638 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 2639 | tmp_buffer=my_newmem(MAX_BUFFER); |
2640 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2641 | add_to_buffer(tmp_buffer); |
2642 | if(onclick != 0){object_cnt++;} |
||
2643 | /* object_cnt++;*/ |
||
2644 | reset(); |
||
2645 | break; |
||
2646 | } |
||
2647 | } |
||
2648 | dragstuff[4] = 1; |
||
2649 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2650 | break; |
||
2651 | case LINES: |
||
2652 | /* |
||
2653 | @ lines color,x1,y1,x2,y2...x_n-1,y_n-1,x_n,y_n |
||
2654 | @ draw multiple lines through points (x1:y1)--(x2:y2) ...(x_n-1:y_n-1)--(x_n:y_n) in color 'color' |
||
2655 | @ or use multiple commands ''curve color,formula`` or ''jscurve color,formule`` to draw the line <br>(uses more points to draw the line; is however better draggable) |
||
2656 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
2657 | @%lines%size 400,400%xrange -10,10%yrange -10,10%lines green,0,1,1,3,0,0,1,3,0,0,-2,1 |
||
2658 | */ |
||
2659 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
2660 | fill_color = stroke_color; |
||
2661 | i=0; |
||
2662 | while( ! done ){ /* get next item until EOL*/ |
||
2663 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
2664 | if(i%2 == 0 ){ |
||
2665 | double_data[i] = get_real(infile,0); /* x */ |
||
2666 | } |
||
2667 | else { |
||
2668 | double_data[i] = get_real(infile,1); /* y */ |
||
2669 | } |
||
2670 | i++; |
||
2671 | } |
||
2672 | decimals = find_number_of_digits(precision); |
||
2673 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2674 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
2675 | if(double_data[c] == double_data[c+2] ){ /* vertical line*/ |
||
2676 | double_data[c+1] = xmin; |
||
2677 | double_data[c+3] = ymax; |
||
2678 | double_data[c+2] = double_data[c]; |
||
2679 | } |
||
2680 | else { |
||
2681 | if( double_data[c+1] == double_data[c+3] ){ /* horizontal line */ |
||
2682 | double_data[c+3] = double_data[c+1]; |
||
2683 | double_data[c] = ymin; |
||
2684 | double_data[c+2] = xmax; |
||
2685 | } |
||
2686 | else { |
||
2687 | /* m */ |
||
2688 | double m = (double_data[c+3] - double_data[c+1]) /(double_data[c+2] - double_data[c]); |
||
2689 | /* q */ |
||
2690 | double q = double_data[c+1] - ((double_data[c+3] - double_data[c+1]) /(double_data[c+2] - double_data[c]))*double_data[c]; |
||
2691 | /*xmin,m*xmin+q,xmax,m*xmax+q*/ |
||
2692 | double_data[c+1] = (m)*(xmin)+(q); |
||
2693 | double_data[c+3] = (m)*(xmax)+(q); |
||
2694 | double_data[c] = xmin; |
||
2695 | double_data[c+2] = xmax; |
||
2696 | } |
||
2697 | } |
||
2698 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
2699 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
18557 | bpr | 2700 | tmp_buffer=my_newmem(MAX_BUFFER); |
2701 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2702 | add_to_buffer(tmp_buffer); |
2703 | if(onclick != 0){object_cnt++;} |
||
2704 | /* object_cnt++; */ |
||
2705 | } |
||
2706 | dragstuff[4] = 1; |
||
2707 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2708 | reset(); |
||
2709 | break; |
||
2710 | case LINEWIDTH: |
||
2711 | /* |
||
2712 | @ linewidth int |
||
2713 | @ default 1 |
||
2714 | @%linewidth%size 400,400%xrange -10,10%yrange -10,10%linewidth 1%line -5,-5,-5,5,red%linewidth 2%line -4,-5,-4,5,green%linewidth 3%line -3,-5,-3,5,blue%linewidth 4%line -2,-5,-2,5,orange%linewidth 1%line -1,-5,-1,5,brown%linewidth 5%line 1,-5,1,5,cyan%linewidth 6%line 3,-5,3,5,purple%linewidth 7%line 5,-5,5,5,black |
||
2715 | */ |
||
2716 | line_width = (int) (get_real(infile,1)); |
||
2717 | break; |
||
2718 | case LEVELCURVE: |
||
2719 | /* |
||
2720 | @ levelcurve color,expression in x/y,l1,l2,... |
||
2721 | @ draws very primitive level curves for expression, with levels l1,l2,l3,...,l_n |
||
2722 | @ the quality is <b>not to be compared</b> with the Flydraw levelcurve. <br>(choose flydraw if you want quality...) |
||
2723 | @ every individual level curve may be set 'onclick / drag xy' <br>e.g. every single level curve (l1,l2,l3...l_n) has a unique identifier |
||
2724 | @ note: the arrays for holding the javascript data are limited in size |
||
2725 | @ note: reduce image size if javascript data arrays get overloaded<br>(command 'plotsteps int' will not control the data size of the plot...) |
||
2726 | @%levelcurve%size 400,400%xrange -10,10%yrange -10,10%levelcurve red,x*y,1,2,3,4 |
||
2727 | */ |
||
2728 | fill_color = get_color(infile,0); |
||
2729 | char *fun1 = get_string_argument(infile,0); |
||
2730 | if( strlen(fun1) == 0 ){canvas_error("function is NOT OK !");} |
||
2731 | i = 0; |
||
2732 | done = FALSE; |
||
2733 | while( !done ){ |
||
2734 | double_data[i] = get_real(infile,1); |
||
2735 | i++; |
||
2736 | } |
||
2737 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2738 | for(c = 0 ; c < i; c++){ |
||
18557 | bpr | 2739 | tmp_buffer=my_newmem(MAX_BUFFER); |
2740 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,16,%s,[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,eval_levelcurve(xsize,ysize,fun1,xmin,xmax,ymin,ymax,plot_steps,precision,double_data[c]),line_width,line_width,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 2741 | add_to_buffer(tmp_buffer); |
2742 | if(onclick != 0){object_cnt++;} |
||
2743 | /* object_cnt++; */ |
||
2744 | } |
||
2745 | dragstuff[16] = 1; |
||
2746 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
2747 | reset(); |
||
2748 | break; |
||
2749 | case LEGEND: |
||
2750 | /* |
||
2751 | @ legend string1:string2:string3....string_n |
||
2752 | @ will be used to create a legend for a graph |
||
2753 | @ also see command <a href='#piechart'>piechart</a> |
||
2754 | @ will use the same colors per default as used in the graphs; use command <a href='#legendcolors'>legendcolors</a> to override the default |
||
2755 | @ use command <a href="#fontsize">fontsize</a> to adjust. (command ''fontfamily`` is not active for command ''legend``) |
||
2756 | @%legend%size 400,400%xrange -10,10%yrange -10,10%bgcolor white%fontsize 16%legend legend 1:legend 2:legend 3:legend 4:this is legend 5:legend 6:another legend abc%legendcolors red:green:blue%grid 1,1,white%# note: command "grid" is mandatory%# just set grid invisible if not wanted |
||
2757 | */ |
||
2758 | temp = get_string(infile,1); |
||
2759 | if( strstr( temp,":") != 0 ){ temp = str_replace(temp,":","\",\""); } |
||
2760 | legend_cnt++; /* attention: starts with -1: it will be used in piechart etc */ |
||
2761 | fprintf(js_include_file,"var legend%d = [\"%s\"];",legend_cnt,temp); |
||
2762 | break; |
||
2763 | case LEGENDCOLORS: |
||
2764 | /* |
||
2765 | @ legendcolors color1:color2:color3:...:color_n |
||
2766 | @ will be used to color a legend: use this command after the legend command ! e.g. <code>legend test1:test2:test3<br>legendcolors blue:red:orange</code>. |
||
2767 | @ make sure the number of colors match the number of legend items |
||
18627 | bpr | 2768 | @ command ''legend`` in case of ''piechart`` and ''barchart`` will use these colors per default (no need to specify ''legendcolors``) |
18552 | bpr | 2769 | @%legendcolors%size 400,400%xrange -10,10%yrange -10,10%fontsize 18%legend legend 1:legend 2:legend 3%legendcolors red:green:blue%grid 1,1,grey |
2770 | */ |
||
2771 | if(legend_cnt == -1){canvas_error("use command \"legend\" before command \"legendcolors\" ! ");} |
||
2772 | temp = get_string(infile,1); |
||
2773 | if( strstr( temp,":") != 0 ){ temp = str_replace(temp,":","\",\""); } |
||
2774 | fprintf(js_include_file,"var legendcolors%d = [\"%s\"];",legend_cnt,temp); |
||
2775 | break; |
||
2776 | case LINEGRAPH: /* scheme: var linegraph_0 = [ 'stroke_color','line_width','use_dashed', 'dashtype0','dashtype1','x1','y1',...,'x_n','y_n'];*/ |
||
2777 | /* |
||
2778 | @ linegraph x1:y1:x2:y2...x_n:y_n |
||
2779 | @ will plot your data in a graph |
||
2780 | @ may <b>only</b> to be used together with command <a href='#grid'>grid</a> |
||
2781 | @ can be used together with freestyle x-axis/y-axis texts: see commands <a href='#xaxis'>xaxis</a>,<a href='#xaxisup'>xaxisup</a> and <a href='#yaxis'>yaxis</a> |
||
2782 | @ use command <a href='#legend'>legend</a> to provide an optional legend in right-top-corner |
||
2783 | @ also see command <a href='#piechart'>piechart</a> |
||
2784 | @ multiple linegraphs may be used in a single plot |
||
2785 | @ note: your arguments are not checked by canvasdraw: use your javascript console in case of trouble... |
||
2786 | @ <ul><li>use command <a href='#strokecolor'>strokecolor</a> before a command ''linegraph`` to set the color of this graph</li><li>use command <a href='#linewidth'>linewidth</a> before command ''linegraph`` to set linewidth of this graph</li><li>use keyword <a href='#dashed'>dashed</a> before command ''linegraph`` to set dashing of the graph</li><li>if dashing is set, use command <a href='#dashtype'>dashtype</a> before command ''linegraph`` to set the type of dashing of the (individual) graph</li></ul> |
||
2787 | @%linegraph%size 400,400%xrange -10,10%yrange -10,10%strokecolor red%linegraph -10:1:-5:-1:3:3:10:-5%strokecolor blue%linegraph -10:-1:-5:1:3:-3:10:5%dashed%strokecolor green%linegraph -10:2:-5:-2:3:4:10:2%grid 1,1,grey |
||
2788 | */ |
||
2789 | temp = get_string(infile,1); |
||
2790 | if( strstr( temp,":") != 0 ){ temp = str_replace(temp,":","\",\""); } |
||
2791 | fprintf(js_include_file,"var linegraph_%d = [\"%s\",\"%d\",\"%d\",\"%d\",\"%d\",\"%s\"];",linegraph_cnt,stroke_color,line_width,use_dashed,dashtype[0],dashtype[1],temp); |
||
2792 | linegraph_cnt++; |
||
2793 | reset(); |
||
2794 | break; |
||
2795 | case MATHML: |
||
2796 | /* |
||
2797 | @ mathml x1,y1,mathml_string |
||
2798 | @ this command is special for GECKO browsers, and it makes use of Native Mathml |
||
2799 | @ For general use with all browsers, use command <a href='#latex'>latex</a> |
||
2800 | @ can be set <a href='onclick'>onclick</a> and <a href='drag'>drag&drop</a> <br>Note: dragging is fairly primitive dragging of the div-element, and is not done using the <em>dragstuff library</em> |
||
2801 | @ command <a href='#affine'>affine</a> will produce CSS3 matrix transformations |
||
2802 | @ command <a href='#rotate'>rotate</a> will rotate the object |
||
2803 | @ the mathml object is centered at (x1:y1) |
||
2804 | @ the ''mathml_string`` can be produced using WIMS commands like ''texmath`` followed by ''mathmlmath``... or write correct TeX and use only ''mathmlmath`` |
||
2805 | @ mathml will be displayed in a rectangle left top (x1:y1) |
||
2806 | @ can be set onclick <code>javascript:read_dragdrop();</code> will return click numbers of mathml-objects; if 4 clickable object are drawn, the reply could be 1,0,1,0 ... meaning clicked on the first and third object |
||
2807 | @ can be set draggable: <code>javascript:read_dragdrop()</code> will return all coordinates in same order as the canvas script: unmoved objects will have their original coordinates... |
||
2808 | @ snaptogrid is supported...snaptopoints will work, but use with care... due to the primitive dragging. Technically: the dragstuff library is not used... the mathml is embedded in a new div element and not in the html5-canvas. |
||
2809 | @ when clicked, the mathml object will be drawn in red color; the div background color will be determined by the <a href="#fillcolor">fillcolor</a> and <a href="#opacity">opacity</a> settings. |
||
2810 | @ userdraw may be combined with 'mathml' ; the read_canvas() will contain the drawing. |
||
2811 | @ draggable or onclick 'external images' from command <a href='#copyresized'>copy or copyresized</a> can be combined with drag and/or onclick mathml |
||
2812 | @ other drag objects (circles/rects etc) are supported, but read_dragdrop() will probably be difficult to interpret... |
||
2813 | @ if inputfields are incorporated in mathml (with id's: id='mathml0',id='mathml1',...id='mathml_n')<br>the user_input values will be read by javascript:read_mathml();<br><b>attention</b>: if after this mathml-input object other user-interactions are included, these will read mathml too using "read_canvas();" |
||
2814 | @ If other inputfields (command input / command textarea) or userdraw is performed, the function read_canvas() will not read mathml. Use some generic function to read it.... |
||
2815 | @ use keyword <a href='#centered'>centered</a> to center the mathml/xml object on (x1:y1) |
||
2816 | @%mathml_onclick%size 400,400%xrange -10,10%yrange -10,10%onclick%strokecolor red%mathml -5,5,<span style="font-size:1em;"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mstyle id="wims_mathml366290"><mrow><mo stretchy="true">[</mo><mtable rowspacing="0.5ex" columnalign=" left " columnlines=" none " rowlines=" none " ><mtr><mtd><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mstyle displaystyle="true"><mfrac><mn>1</mn><mn>2</mn></mfrac></mstyle><mo>⋅</mo><msup><mi>x</mi> <mn>2</mn></msup></mtd></mtr> <mtr><mtd><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msqrt><mstyle displaystyle="true"><mfrac><mn>1</mn><mrow><msup><mi>x</mi> <mn>2</mn></msup></mrow></mfrac></mstyle></msqrt></mtd></mtr></mtable><mo stretchy="true">]</mo></mrow></mstyle></math></span>%onclick%strokecolor blue%mathml 5,5,<span style="font-size:1em;"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mstyle id="wims_mathml580175" ><mrow><mo stretchy="true">[</mo><mtable rowspacing="0.5ex" columnalign=" left " columnlines=" none " rowlines="none"><mtr><mtd><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mstyle displaystyle="true"><mfrac><mn>1</mn><mrow><mi>sin</mi><mrow><mo stretchy="true">(</mo><msup><mi>x</mi> <mn>2</mn></msup><mo stretchy="true">)</mo></mrow></mrow></mfrac></mstyle></mtd></mtr> <mtr><mtd><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msqrt><mrow><mi>sin</mi><mrow><mo stretchy="true">(</mo><msup><mi>x</mi> <mn>2</mn></msup><mo stretchy="true">)</mo></mrow></mrow></msqrt></mtd></mtr></mtable><mo stretchy="true">]</mo></mrow></mstyle></math></span> |
||
2817 | @%mathml_drag%size 400,400%xrange -10,10%yrange -10,10%drag xy%strokecolor red%mathml -5,5,<span style="font-size:1em;"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mstyle id="wims_mathml366290"><mrow><mo stretchy="true">[</mo><mtable rowspacing="0.5ex" columnalign=" left " columnlines=" none " rowlines=" none "><mtr><mtd><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mstyle displaystyle="true"><mfrac><mn>1</mn><mn>2</mn></mfrac></mstyle><mo>⋅</mo><msup><mi>x</mi> <mn>2</mn></msup></mtd></mtr> <mtr><mtd><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msqrt><mstyle displaystyle="true"><mfrac><mn>1</mn><mrow><msup><mi>x</mi> <mn>2</mn></msup></mrow></mfrac></mstyle></msqrt></mtd></mtr></mtable><mo stretchy="true">]</mo></mrow></mstyle></math></span>%drag xy%strokecolor blue%mathml 5,5,<span style="font-size:1em;"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mstyle id="wims_mathml580175" ><mrow><mo stretchy="true">[</mo><mtable rowspacing="0.5ex" columnalign=" left " columnlines=" none " rowlines=" none "><mtr><mtd><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mstyle displaystyle="true"><mfrac><mn>1</mn><mrow><mi>sin</mi><mrow><mo stretchy="true">(</mo><msup><mi>x</mi> <mn>2</mn></msup><mo stretchy="true">)</mo></mrow></mrow></mfrac></mstyle></mtd></mtr> <mtr><mtd><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msqrt><mrow><mi>sin</mi><mrow><mo stretchy="true">(</mo><msup><mi>x</mi> <mn>2</mn></msup><mo stretchy="true">)</mo></mrow></mrow></msqrt></mtd></mtr></mtable><mo stretchy="true">]</mo></mrow></mstyle></math></span>%#click left top corner...then drag... |
||
2818 | */ |
||
2819 | js_function[DRAW_XML] = 1; |
||
2820 | for(i=0;i<3;i++){ |
||
2821 | switch(i){ |
||
2822 | case 0: double_data[0]=get_real(infile,0);break; /* x in x/y-range coord system -> pixel width */ |
||
2823 | case 1: double_data[1]=get_real(infile,0);break; /* y in x/y-range coord system -> pixel height */ |
||
2824 | case 2: decimals = find_number_of_digits(precision); |
||
2825 | if(use_affine == TRUE ){ transform(2,2);}/* needs double_data[] */ |
||
2826 | if( use_offset != 0 || drag_type != -1 ){int_data[2] = 1;}else{int_data[2] = 0;} /* only centered or not-centered */ |
||
2827 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
2828 | int_data[0] = x2px(double_data[0]);/* needs px */ |
||
2829 | int_data[1] = y2px(double_data[1]); |
||
2830 | if( use_slider != -1 && onclick == 0 ){ onclick = 3;}/* no drag&onclick but slideable */ |
||
2831 | if( use_slider != -1 && drag_type != -1){ onclick = 5; } |
||
2832 | temp = get_string(infile,1); |
||
2833 | if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","'"); } |
||
18557 | bpr | 2834 | tmp_buffer=my_newmem(MAX_BUFFER); |
2835 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var draw_xml%d = {id:%d,type:'mathml',x:[%d],y:[%d],mathml:\"%s\",drag_type:%d,onclick:%d,object_cnt:%d,stroke_color:\"%s\",stroke_opacity:%.2f,fill_color:\"%s\",fill_opacity:%.2f,use_center:%d,use_snap:%d,angle:%f,fontfamily:\"%s\",transform:%s,use_affine:%d,offset:[0,0],use_slider:%d,rotation_center:%s,once:true};draw_xml(draw_xml%d);slidergroup[%d] = null;\n",drawxml_cnt,drawxml_cnt,int_data[0],int_data[1],temp,drag_type,onclick,object_cnt,stroke_color,stroke_opacity,fill_color,fill_opacity,int_data[2],use_snap,angle,font_family,doubledata2js_array(affine_matrix,6,decimals),use_affine,use_slider,rotation_center,drawxml_cnt,object_cnt)); |
||
18552 | bpr | 2836 | add_to_buffer(tmp_buffer); |
2837 | if(onclick != 0 ){object_cnt++;} |
||
2838 | drawxml_cnt++;/* keeps track on imported img,div,p,span,mathml,svg */ |
||
2839 | /* |
||
2840 | in case inputs are present, trigger adding the read_mathml() |
||
2841 | if no other reply_format is defined |
||
2842 | note: all other reply types will include a reading of elements with id='mathml'+p) |
||
2843 | */ |
||
2844 | if(strstr(temp,"mathml0") != NULL){ if(reply_format == 0 ){reply_format = 16;}} /* no other reply type is defined */ |
||
2845 | break; |
||
2846 | default:break; |
||
2847 | } |
||
2848 | } |
||
2849 | reset(); |
||
2850 | break; |
||
2851 | case MOUSE: |
||
2852 | /* |
||
18556 | bpr | 2853 | @ mouse color,fontsize |
2854 | @ will display the cursor (x:y) coordinates in ''color`` and ''fontsize`` using default fontfamily Arial |
||
2855 | @ note: use command ''mouse`` at the end of your script code (the same is true for command ''zoom``) |
||
2856 | @%mouse%size 400,400%xrange -10,10%yrange -10,10%mouse red,22 |
||
18552 | bpr | 2857 | */ |
2858 | stroke_color = get_color(infile,0); |
||
2859 | font_size = (int) (get_real(infile,1)); |
||
2860 | tmp_buffer = my_newmem(26); |
||
2861 | snprintf(tmp_buffer,26,"use_mouse_coordinates();\n");add_to_buffer(tmp_buffer); |
||
2862 | add_js_mouse(MOUSE_CANVAS,precision,stroke_color,font_size,stroke_opacity,2); |
||
2863 | js_function[INTERACTIVE] = 1; |
||
2864 | break; |
||
2865 | case MOUSE_DEGREE: |
||
2866 | /* |
||
18556 | bpr | 2867 | @ mouse_degree color,fontsize |
2868 | @ will display the angle in degrees between x-axis, (0:0) and the cursor (x:y) in 'color' and 'font size'<br> using a fontfamily Arial |
||
2869 | @ The angle is positive in QI and QIII and the angle value is negative in QII and QIV |
||
2870 | @ note: use command 'mouse' at the end of your script code (the same is true for command 'zoom') |
||
2871 | @%mouse_degree%size 400,400%xrange -10,10%yrange -10,10%userdraw arc,blue%precision 100000%mouse_degree red,22 |
||
18552 | bpr | 2872 | */ |
2873 | stroke_color = get_color(infile,0); |
||
2874 | font_size = (int) (get_real(infile,1)); |
||
2875 | tmp_buffer = my_newmem(26); |
||
2876 | snprintf(tmp_buffer,26,"use_mouse_coordinates();\n");add_to_buffer(tmp_buffer); |
||
2877 | add_js_mouse(MOUSE_CANVAS,precision,stroke_color,font_size,stroke_opacity,3); |
||
2878 | js_function[JS_FIND_ANGLE] = 1; |
||
2879 | js_function[INTERACTIVE] = 1; |
||
2880 | break; |
||
2881 | case MOUSE_DISPLAY: |
||
2882 | /* |
||
18556 | bpr | 2883 | @ display TYPE,color,fontsize |
2884 | @ TYPE may be x | y | xy | degree | radian | radius |
||
2885 | @ will display the mouse cursor coordinates as x-only,y-only,(x:y), the radius of a circle (this only in case 'userdraw circle(s),color') or the angle in degrees or radians for commands <code>userdraw arc,color</code> or protractor, ruler (if set dynamic). |
||
2886 | @ use commands ''xunit`` and / or ''yunit`` to add the units to the mouse values. The ''degree | radian`` will always have the appropriate symbol). |
||
2887 | @ just like commands ''mouse``, ''mousex``, ''mousey``, ''mouse_degree``... only other name |
||
2888 | @%display_x%size 400,400%xrange -10,10%yrange -10,10%xunit \\u212B%display x,red,22 |
||
2889 | @%display_y%size 400,400%xrange -10,10%yrange -10,10%yunit seconds%display y,red,22 |
||
2890 | @%display_xy%size 400,400%xrange -10,10%yrange -10,10%xunit centimetre%yunit seconds%display xy,red,22%userdraw segments,blue |
||
2891 | @%display_deg%size 400,400%xrange -10,10%yrange -10,10%display degree,red,22%fillcolor orange%opacity 200,50%userdraw arc,blue |
||
2892 | @%display_rad%size 400,400%xrange -10,10%yrange -10,10%display radian,red,22%fillcolor orange%opacity 200,50%userdraw arc,blue |
||
2893 | @%display_radius%size 400,400%xrange -10,10%yrange -10,10%xunit cm%xunit \\u212b%display radius,red,22%userdraw circle,blue |
||
18552 | bpr | 2894 | */ |
2895 | temp = get_string_argument(infile,0); |
||
2896 | if( strstr(temp,"xy") != NULL ){ |
||
2897 | int_data[0] = 2; |
||
2898 | } else { |
||
2899 | if( strstr(temp,"y") != NULL ){ |
||
2900 | int_data[0] = 1; |
||
2901 | }else{ |
||
2902 | if( strstr(temp,"x") != NULL ){ |
||
2903 | int_data[0] = 0; |
||
2904 | }else{ |
||
2905 | if(strstr(temp,"degree") != NULL){ |
||
2906 | int_data[0] = 3; |
||
2907 | js_function[JS_FIND_ANGLE] = 1; |
||
2908 | }else{ |
||
2909 | if(strstr(temp,"radian") != NULL){ |
||
2910 | int_data[0] = 4; |
||
2911 | js_function[JS_FIND_ANGLE] = 1; |
||
2912 | }else{ |
||
2913 | if(strstr(temp,"radius") != NULL){ |
||
2914 | int_data[0] = 5; |
||
2915 | }else{ |
||
2916 | int_data[0] = 2; |
||
2917 | } |
||
2918 | } |
||
2919 | } |
||
2920 | } |
||
2921 | } |
||
2922 | } |
||
2923 | stroke_color = get_color(infile,0); |
||
2924 | font_size = (int) (get_real(infile,1)); |
||
2925 | tmp_buffer = my_newmem(26); |
||
2926 | snprintf(tmp_buffer,26,"use_mouse_coordinates();\n");add_to_buffer(tmp_buffer); |
||
2927 | add_js_mouse(MOUSE_CANVAS,precision,stroke_color,font_size,stroke_opacity,int_data[0]); |
||
2928 | js_function[INTERACTIVE] = 1; |
||
2929 | break; |
||
2930 | case MOUSE_PRECISION: |
||
2931 | /* |
||
18556 | bpr | 2932 | @ precision int |
2933 | @ 1 = no decimals ; 10 = 1 decimal ; 100 = 2 decimals etc |
||
2934 | @ may be used / changed before every object |
||
2935 | @ In case of user interaction (like ''userdraw`` or ''multidraw``), this value will be used to determine the amount of decimals in the reply / answer |
||
2936 | @%precision%size 400,400%xrange -10,10%yrange -10,10%precision 1%userdraw segment,red |
||
18552 | bpr | 2937 | */ |
2938 | precision = (int) (get_real(infile,1)); |
||
2939 | if(precision < 1 ){precision = 1;}; |
||
2940 | break; |
||
2941 | case MOUSEX: |
||
2942 | /* |
||
18556 | bpr | 2943 | @ mousex color,fontsize |
2944 | @ will display the cursor x-coordinate in ''color`` and ''font size`` using the fontfamily Arial. |
||
2945 | @ note: use command ''mouse`` at the end of your script code (the same is true for command ''zoom``). |
||
18552 | bpr | 2946 | */ |
2947 | stroke_color = get_color(infile,0); |
||
2948 | font_size = (int) (get_real(infile,1)); |
||
2949 | tmp_buffer = my_newmem(26); |
||
2950 | snprintf(tmp_buffer,26,"use_mouse_coordinates();\n");add_to_buffer(tmp_buffer); |
||
2951 | add_js_mouse(MOUSE_CANVAS,precision,stroke_color,font_size,stroke_opacity,0); |
||
2952 | js_function[INTERACTIVE] = 1; |
||
2953 | break; |
||
2954 | case MOUSEY: |
||
2955 | /* |
||
18556 | bpr | 2956 | @ mousey color,fontsize |
2957 | @ will display the cursor y-coordinate in ''color`` and ''font size`` using default fontfamily Arial. |
||
2958 | @ note: use command ''mouse`` at the end of your script code (the same is true for command ''zoom``). |
||
8386 | schaersvoo | 2959 | |
18552 | bpr | 2960 | */ |
2961 | stroke_color = get_color(infile,0); |
||
2962 | font_size = (int) (get_real(infile,1)); |
||
2963 | tmp_buffer = my_newmem(26); |
||
2964 | snprintf(tmp_buffer,26,"use_mouse_coordinates();\n");add_to_buffer(tmp_buffer); |
||
2965 | add_js_mouse(MOUSE_CANVAS,precision,stroke_color,font_size,stroke_opacity,1); |
||
2966 | js_function[INTERACTIVE] = 1; |
||
2967 | break; |
||
2968 | case MULTIDASH: |
||
2969 | /* |
||
18556 | bpr | 2970 | @ multidash 0,1,1 |
2971 | @ meaning draw objects no. 2 (circle) and 3 (segments), in the list of command like <code>multifill points,circle,segments</code>, are dashed |
||
2972 | @ use before command <a href='#multidraw'>multidraw</a> |
||
2973 | @ if not set all objects will be set ''not dashed``... unless a generic keyword ''dashed`` was given before command ''multidraw`` |
||
2974 | @ the dash-type is not -yet- adjustable <br>(e.g. command <code>dashtype line_px,space_px</code> will give no control over multidraw objects) |
||
2975 | @ wims will <b>not</b> check if the number of 0 or 1's matches the amount of draw primitives... |
||
2976 | @ always use the same sequence as is used for ''multidraw`` |
||
18552 | bpr | 2977 | */ |
2978 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
2979 | temp = get_string(infile,1); |
||
2980 | temp = str_replace(temp,",","\",\""); |
||
2981 | fprintf(js_include_file,"var multidash = [\"%s\"];",temp); |
||
2982 | reset();/* if command 'dashed' was given...reset to not-dashed */ |
||
2983 | break; |
||
2984 | case MULTIDRAW: |
||
2985 | /* |
||
18556 | bpr | 2986 | @ multidraw obj_type_1,obj_type_2...obj_type_11 |
2987 | @ for simple single object user drawings you could also use command <a href="#userdraw">userdraw</a> |
||
18572 | bpr | 2988 | @ implemented obj_types:<ul><li>point | points</li><li>circle | circles</li><li>line | lines</li><li>segment | segments</li><li>arrow | arrows (use command 'arrowhead int' for size (default value 8 pixels))</li><li>curvedarrow | curvedarrows</li><li>rect | rects</li><li>closedpoly<br><b>only one</b> closedpolygon may be drawn.The number of ''corner points`` is not preset (e.g. not limited, freestyle), the polygon is closed when clicking on the first point again..(+/- 10px)</li><li>triangle | triangles</li><li>parallelogram | parallelograms</li><li>poly[3-9] | polys[3-9] draw 3...9 point polygone(s): polys3 is of course triangles</li><li>images</li><li>crosshair | crosshairs</li><li>function <br>for more function user input fields, use it multiple times<br>for 4 inputfields use : multidraw function,function,function,function</li></ul> |
18556 | bpr | 2989 | @ additionally objects may be user labelled, using obj_type ''text``...<br>in this case allways a text input field and if <a href='#multiuserinput'> multiuserinput=1 </a> also (x:y) inputfields will be added to the page.<br>use commands ''fontfamily`` and ''fontcolor`` to adjust (command ''multistrokeopacity`` may be set to adjust text opacity)<br>note: text is always centered on the mouse-click or user-input coordinates !<br>note: no keyboard listeners are used |
2990 | @ it makes no sense using something like ''multidraw point,points`` ... <br>something like "multidraw polys4,polys7" will only result in drawing a ''4 point polygone`` and not a ''7 point polygone``: this is a design flaw and not a feature... |
||
2991 | @ note: mouselisteners are only active if "$status != done " (eg only drawing in an active/non-finished exercise) <br> to overrule use command/keyword "status" (no arguments required) |
||
2992 | @ buttons for changing the obj_type (and in case of ''multiuserinput``, some inputfields and buttons) <br>will be present in the reserved div ''tooltip_div`` and can be styled using command 'css some_css' |
||
2993 | @ the button label will be default the ''object primitive name`` (like ''point``, ''circles``).<br>If you want a different label (e.g. an other language), use command ''multilabel``<br>for example in dutch: <br><code>multilabel cirkel,lijnstuk,punten,STOP<br>multidraw circle,segment,points</code><br>(see command <a href='#multilabel'>multilabel</a> for more details) |
||
2994 | @ a right mouse button click will remove the last drawn object of the selected drawing type. All other type of objects are not removed |
||
2995 | @ multidraw is incompatible with command ''tooltip`` (the reserved div_area is used for the multidraw control buttons) |
||
2996 | @ all ''multidraw`` drawings will scale on zooming.<br>this in contrast to the command <a href="#userdraw">userdraw</a>. |
||
2997 | @ wims will <b>not</b> check the amount or validity of your command arguments ! <br>( use javascript console to debug any typo's ) |
||
18572 | bpr | 2998 | @ a local function <code>read_canvas%d</code> will read all userbased drawings.<br>The output is always a 16 lines string with fixed sequence.<br>line 1 = points_x+";"+points_y+"\\n"<br>line 2 = circles_x+";"+circles_y+";"+multi_radius+"\\n"<br>line 3 = segments_x+";"+segments_y+"\\n"<br>line 4 = arrows_x+";"+arrows_y+"\\n"<br>line 5 = lines_x+";"+lines_y+"\\n"<br>line 6 = triangles_x+";"+triangles_y+"\\n"<br>line 7 = polys[3-9]_x+";"+polys[3-9]_y+"\\n"<br>line 8 = rects_x +";"+rects_y+"\\n"<br>line 9 = closedpoly_x+";"+closedpoly_y+"\\n"<br>line 10 = parallelogram_x+";"+parallelogram_y"\\n"<br>line 11 = text_x+";"+text_y+";"+text"\\n"<br>line 12 = image_x+";"+image_y+";"+image_id<br>line 13 = curvedarrows_x +";"+ curvedarrows_y +"\\n"<br>line 14 = curvedarrows2_x +";"+ curvedarrows2_y +"\\n"<br>line 15 = crosshairs_x +";"+ crosshairs_y +"\\n"<br>line 16 = userdraw_x +";"+userdraw_y + "\\n" note: this is for single ''userdraw object,color`` and ''replyformat 29``<br>line 17 = userdraw_x +";"+userdraw_y +";"+userdraw_radius + "\\n" note: this is for single ''userdraw object,color`` and ''replyformat 29``<br>The x/y-data are in x/y-coordinate system and display precision may be set by a previous command ''precision 0 | 10 | 100 | 1000...``<br>In case of circles the radius is -for the time being- rounded to pixels<br><b>use the wims "direct exec" tool to see the format of the reply</b> |
18556 | bpr | 2999 | @ It is best to prepare / format the student reply in clientside javascript.<br>However in ''wims`` language you could use something like this<br>for example you are interested in the polys5 drawings of a pupil (the pupil may draw multiple poly5 objects...)<br>note: the reply for 2 poly5's is: x11,x12,x13,x14,x15,x21,x22,x23,x24,x25 ; y11,y12,y13,y14,y15,y21,y22,y23,y24,y25<br>rep = !line 7 of reply <br>rep = !translate ';' to '\\n' in $rep <br>pts = 5 # 5 points for polygon <br>x_rep = !line 1 of $rep <br>y_rep = !line 2 of $rep <br>tot = !itemcnt $x_rep <br>num_poly = $[$tot/$pts] <br>idx = 0 <br>!for p=1 to $num_poly <br> !for s=1 to $pts <br> !increase idx <br> X = !item $idx of $x_rep <br> Y = !item $idx of $y_rep <br> # do some checking <br> !next s <br>!next p <br> |
3000 | @ <b>attention</b>: for command argument ''closedpoly``, only one polygone can be drawn. The last point (e.g. the point clicked near the first point) of the array is removed. |
||
3001 | @ technical: all 10 ''draw primitives`` + ''text`` will have their own -transparent- PNG bitmap canvas. <br>So for example there can be a points_canvas entirely separated from a line_canvas.<br>This to avoid the need for a complete redraw when something is drawn to the canvas...(eg only the object_type_canvas is redrawn), this in contrast too many very slow do-it-all HTML5 canvas javascript libraries.<br>The mouselisteners are attached to the canvas-div element. |
||
3002 | @ a special object type is ''images``.<br>if used together with <a href='#imagepalette'>imagepalette</a> a image table will be integrated in the 'control section' of multidraw (set <code>multiuserinput 1</code> for ''images``) if not used with <a href='#imagepalette'>imagepalette</a>, provide the images or div's (<img> tag with bitmap or SVG or anything in a div element) somewhere on the html exercise page, with an onclick handler like:<br><code><img src='gifs/images/dog.svg' onclick='javascript:place_image_on_canvas(this.id);' id="ext_image_1" /><br><img src='gifs/fish.png' onclick='javascript:place_image_on_canvas(this.id);' id="another" /></code><br>etc ... when activating the multidraw ''image`` button, the images can be selected<br> (left mouse button/onclick) and placed on the canvas...left mouse click.<br>using div's will enable you -amongst other content- to add math typesetting from the exercise page onto the canvas. |
||
18572 | bpr | 3003 | @ When you are not content with the default ''multidraw control panel``, you can create your own interface, using a few javascript functions to call the drawprimitives, delete things and ''stop drawing`` in case you also want to drag&drop stuff...</br>To activate this feature, use <a href='#multilabel'>multilabel NOCONTROLS</a><br>The object types are internally represented by the following numbers (making typos will render your exercise null and void)<br>point = 0<br>points =1<br>circle = 2<br>circles = 3<br>line = 4<br>lines = 5<br>segment = 6<br>segments = 7<br>arrow = 8<br>arrows = 9<br>triangle = 10<br>triangles = 11<br>closedspoly = 12<br>text = 13<br>rect = 14<br>rects = 15<br>poly[3-9] = 16<br>polys[3-9] = 17<br>parallelogram = 18<br>parallelograms = 19<br>images = 20<br>curvedarrow = 21<br>curvedarrows = 22<br>curvedarrow2 = 23<br>curvedarrows2 = 24<br>crosshair = 25<br>crosshairs = 26 <br>controls for example:<br><code><input type='button' onclick='javascript:userdraw_primitive=null' value='STOP DRAWING' /><br><input type='button' onclick='javascript:userdraw_primitive=24;multidraw_object_cnt = 0;' value='start drawing curvedarrows2' /> <br><input type='button' onclick='javascript:var fun=eval("clear_draw_area"+canvas_scripts[0]);fun(24,0);' value='REMOVE LAST CURVEDARROW ' /> </code><br> If using multiple canvas scripts in a single page, loop through the canvas_scripts[n] <br>note: if using NOCONTROLS and just a single draw primitive (for example, just: 'multidraw circles'), the object may be drawn directly. (analogue to 'userdraw circles,color')<br>And since a right mouse button click will always remove the last drawn object of the current object type, there is no need for a special "remove button" |
18556 | bpr | 3004 | @%multidraw_function%size 400,400%xrange -10,10%yrange -10,10%fontfamily Italic 22px Helvetica%axis%axisnumbering%precision 0%grid 2,2,grey,1,1,5,black%multicolors red,green,blue%fontcolor orange%multilinewidth 1,2,3%multidraw text,function,function,function,line |
3005 | @%multidraw%size 400,400%xrange -10,10%yrange -10,10%multidash 1,0%multilinewidth 1,2%multistrokecolors red,blue%multisnaptogrid 1,1%multilabel LINES,CIRCLES,STOP DRAWING%multidraw lines,circles |
||
3006 | @%multidraw_images%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%drag xy%# use special function to read the drag coordinates%copy 0,0,-1,-1,-1,-1,gifs/images/skull_and_crossbones50.png%fontcolor green%fontfamily Bold 42pt Arial%imagepalette gifs/ca.gif,gifs/en.gif,gifs/nl.gif,gifs/fr.gif,gifs/cn.gif,gifs/de.gif,gifs/kh.gif,gifs/it.gif%multiuserinput 0,0,1%css color:blue;%multisnaptogrid 1,1,1%multilinewidth 0,4,0%# attention: use unicode text input without the slash %# \u222D ---> u222D at least will sometimes work%# otherwise cut&past unicode symbols into inputfield...%multilabel TEXT,REACTION ARROW,FLAGS,STOP DRAWING%multidraw text,arrow,images |
||
3007 | @%multidraw_demo%size 800,800%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%css color:blue;%fontfamily Italic 42pt Arial%precision 1%opacity 200,50%snaptogrid%linewidth 3%filled%multistrokecolors red,green,blue,orange,yellow,purple,black,cyan,red,green,blue,orange,green,purple,black,cyan%multifillcolors red,green,blue,orange,yellow,purple,black,cyan,red,green,blue,orange,brown,purple%imagepalette gifs/ca.gif,gifs/en.gif,gifs/nl.gif,gifs/fr.gif,gifs/cn.gif,gifs/de.gif,gifs/kh.gif,gifs/it.gif%multidraw closedpoly,segments,rect,parallelogram,triangles,poly5,points,lines,arrows,circles,text,curvedarrows,curvedarrows2,images |
||
3008 | @%multidraw_NOCONTROLS%size 400,400%xrange -10,10%yrange -10,10%grid 2,2,grey%linewidth 3%strokecolor green%fillcolor blue%filled%opacity 255,60%multilabel NOCONTROLS%multidraw circles%# RIGHT MOUSE CLICK REMOVES LAST OBJECT |
||
18552 | bpr | 3009 | */ |
3010 | js_function[INTERACTIVE] = 1; |
||
3011 | if(js_function[JS_ZOOM] == 1){use_zoom = 1;} /* use noisy zoom_code, when command zoom is given before command 'multidraw' */ |
||
3012 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3013 | if( use_userdraw == 1 ){canvas_error("Only one userdraw primitive may be used in command 'userdraw' use command 'multidraw' for this...");} |
||
3014 | use_userdraw = 2; |
||
3015 | temp = get_string(infile,1); |
||
3016 | fprintf(js_include_file,"\ |
||
3017 | var MMP = %d;\ |
||
3018 | if( typeof(multisnaptogrid) == 'undefined' && multisnaptogrid == null){var multisnaptogrid = new Array(MMP);for(var i=0;i<MMP;i++){multisnaptogrid[i] = %d;};};\ |
||
3019 | if( typeof(multistrokecolors) === 'undefined' && multistrokecolors == null){ var multistrokecolors = new Array(MMP);for(var i=0;i<MMP;i++){multistrokecolors[i] = '%s';};};\ |
||
3020 | if( typeof(multifillcolors) === 'undefined' && multifillcolors == null ){var multifillcolors = new Array(MMP);for(var i=0;i<MMP;i++){multifillcolors[i] = '%s';};};\ |
||
3021 | if( typeof(multistrokeopacity) === 'undefined' && multistrokeopacity == null){var multistrokeopacity = new Array(MMP);for(var i=0;i<MMP;i++){multistrokeopacity[i] = %.2f;};};\ |
||
3022 | if( typeof(multifillopacity) === 'undefined' && multifillopacity == null){var multifillopacity = new Array(MMP);for(var i=0;i<MMP;i++){multifillopacity[i] = %.2f;};};\ |
||
3023 | if( typeof(multilinewidth) === 'undefined' && multilinewidth == null){var multilinewidth = new Array(MMP);for(var i=0;i<MMP;i++){multilinewidth[i] = %d;};};\ |
||
3024 | if( typeof(multifill) === 'undefined' && multifill == null){var multifill = new Array(MMP);for(var i=0;i<MMP;i++){multifill[i] = %d;};};\ |
||
3025 | if( typeof(multidash) === 'undefined' && multidash == null){var multidash = new Array(MMP);for(var i=0;i<MMP;i++){multidash[i] = %d;};};\ |
||
3026 | if( typeof(multilabel) === 'undefined' && multilabel == null){var multilabel = [\"%s\",\"stop drawing\"];};\ |
||
3027 | if( typeof(multiuserinput) === 'undefined' && multiuserinput == null){var multiuserinput = new Array(MMP);for(var i=0;i<MMP;i++){multiuserinput[i] = '0';};};\ |
||
3028 | var arrow_head = %d;var multifont_color = '%s';var multifont_family = '%s';var forbidden_zone = [xsize+2,ysize+2];", |
||
3029 | MAX_MULTI_PRIMITIVES, |
||
3030 | use_snap, |
||
3031 | stroke_color, |
||
3032 | fill_color, |
||
3033 | stroke_opacity, |
||
3034 | fill_opacity, |
||
3035 | line_width, |
||
3036 | use_filled, |
||
3037 | use_dashed, |
||
3038 | str_replace(temp,",","\",\""), |
||
3039 | arrow_head,font_color,font_family); |
||
3040 | add_js_multidraw(temp,css_class,use_offset,int_data[MAX_MULTI_PRIMITIVES+1],crosshair_size,use_zoom); |
||
3041 | /* no_controls == int_data[MAX_MULTI_PRIMITIVES+1] */ |
||
3042 | reply_precision = precision; |
||
3043 | if(strstr(temp,"text") != NULL){ |
||
3044 | js_function[JS_SAFE_EVAL] = 1; |
||
3045 | js_function[DRAW_SUBSUP] = 1; |
||
3046 | } |
||
3047 | if(strstr(temp,"function") != NULL){ |
||
3048 | int pp, funs = count_substring(temp, "function"); |
||
3049 | js_function[JS_SAFE_EVAL] = 1; |
||
3050 | js_function[JS_RAWMATH] = 1; |
||
3051 | js_function[DRAW_JSFUNCTION] = 1; |
||
3052 | js_function[JS_MATH] = 1; |
||
3053 | js_function[JS_PLOT] = 1; |
||
3054 | for(pp = 0 ; pp< funs ;pp++){ |
||
3055 | add_input_jsfunction(css_class,function_label,input_cnt,stroke_color,stroke_opacity,line_width,use_dashed,dashtype[0],dashtype[1],font_size); |
||
3056 | input_cnt++; |
||
3057 | jsplot_cnt++; |
||
3058 | } |
||
3059 | fprintf(js_include_file,"if(typeof(all_jsplots) !== 'number'){var all_jsplots;};all_jsplots = %d;function redraw_userdraw(){redraw_jsplot();return;};",jsplot_cnt); |
||
3060 | } |
||
3061 | /* the canvasses range from 1000 ... 1008 */ |
||
3062 | if( reply_format == 0){reply_format = 29;} |
||
3063 | reset();/* if command 'filled' / 'dashed' was given...reset all */ |
||
3064 | break; |
||
3065 | case MULTILABEL: |
||
3066 | /* |
||
18556 | bpr | 3067 | @ multilabel button_label_1,button_label_2,...,button_label_8,'stop drawing text' |
3068 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3069 | @ if not set all labels (e.g. the value of input type 'button') will be set by the english names for the draw_primitives (like 'point','circle'...) |
||
3070 | @ the ''stop drawing`` button text <b>must</b> be the last item on the ''multilabel`` -list <br>for example:<br><code>multilabel punten,lijnen,Stop met Tekenen<br>multidraw points,lines</code> |
||
3071 | @ all buttons can be ''styled`` by using command <code>css</code><br><b>note:</b>If you want to add some CSS style to the buttons...<br>the id's of the ''draw buttons`` are their english command argument<br>(e.g. id="canvasdraw_points" for the draw points button).<br>the id of the ''stop drawing`` button is "canvasdraw_stop_drawing".<br>the id of the "OK" button is ''canvasdraw_ok_button`` |
||
3072 | @ wims will not check the amount or validity of your input |
||
3073 | @ always use the same sequence as is used for ''multidraw`` |
||
3074 | @ if you don't want the controls, and want to write your own interface, set <code>multilabel NOCONTROLS</code> |
||
18552 | bpr | 3075 | */ |
3076 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3077 | temp = get_string(infile,1); |
||
3078 | if( strcasestr(temp,"NOCONTROLS") ){ |
||
3079 | int_data[MAX_MULTI_PRIMITIVES+1] = 1; /*int_data[25] = 1 --> 'no_controls = 1' in canvasmacro.c */ |
||
3080 | fprintf(js_include_file,"var multilabel = null;"); |
||
3081 | } |
||
3082 | else { |
||
3083 | int_data[MAX_MULTI_PRIMITIVES+1] = 0; /* so DO use control buttons etc */ |
||
3084 | temp = str_replace(temp,",","\",\""); |
||
3085 | fprintf(js_include_file,"var multilabel = [\"%s\"];",temp); |
||
3086 | } |
||
3087 | break; |
||
3088 | case MULTILINEWIDTH: |
||
3089 | /* |
||
18556 | bpr | 3090 | @ multilinewidth linewidth_1,linewidth_2,...,linewidth_8 |
3091 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3092 | @ if not set all line widths will be set by a previous command ''linewidth int`` |
||
3093 | @ use these up to 7 different line widths for the draw primitives used by command <code>multidraw obj_type_1,obj_type_2...obj_type_7</code> |
||
3094 | @ wims will <b>not</b> check if the number of 0 or 1's matches the amount of draw primitives... |
||
3095 | @ always use the same sequence as is used for ''multidraw`` |
||
18552 | bpr | 3096 | */ |
3097 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3098 | temp = get_string(infile,1); |
||
3099 | temp = str_replace(temp,",","\",\""); |
||
3100 | fprintf(js_include_file,"var multilinewidth = [\"%s\"];",temp); |
||
3101 | break; |
||
3102 | case MULTIFILL: |
||
3103 | /* |
||
18556 | bpr | 3104 | @ multifill 0,0,1,0,1,0,0 |
3105 | @ meaning draw objects no. 3 and 5, in the list of command ''multifill``, are filled (if the object is fillable...and not a line,segment,arrow or point...) |
||
3106 | @ using a fillpattern: multifill 0,1,2,5,3,4<br>meaning: first object is not filled...second object is solid color filled...2=grid | 3=hatch | 4=diamond | 5=dot |
||
3107 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3108 | @ if not set all objects -except point|points- will be set ''not filled``... unless a command <code>filled</code> was given before command <code>multifill</code> |
||
3109 | @ only suitable for draw_primitives like ''circle | circles``, ''triangle | triangles``, ''rect | rects``, ''poly[3-9] | polys[3-9]`` and ''polygon`` |
||
3110 | @ wims will <b>not</b> check if the number of 0 or 1's matches the amount of draw primitives... |
||
3111 | @ always use the same sequence as is used for ''multidraw`` |
||
18552 | bpr | 3112 | */ |
3113 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3114 | i=0; |
||
3115 | while( ! done ){ /* get next item until EOL*/ |
||
3116 | if(i > MAX_MULTI_PRIMITIVES){canvas_error("too many multidraw primitives...read the documentation...");} |
||
3117 | int_data[i] = (int)(get_real(infile,1)); /* 0,1,2,3,4,5 */ |
||
3118 | if(int_data[i] < 0 || int_data[i] > 5 ){canvas_error("the only possible multifill arguments are: 0,1,2,3,4,5 ");} |
||
3119 | if(int_data[i] > 1 ){use_filled = 2;js_function[DRAW_FILL_PATTERN] = 1;}/* switch to trigger pattern filling */ |
||
3120 | i++; |
||
3121 | } |
||
3122 | fprintf(js_include_file,"var multifill = %s ;",data2js_array(int_data,i-1)); |
||
3123 | break; |
||
3124 | case MULTIFILLCOLORS: |
||
3125 | /* |
||
18556 | bpr | 3126 | @ multifillcolors color_name_1,color_name_2,...,color_name_8 |
3127 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3128 | @ if not set all fillcolors (for circle | triangle | poly[3-9] | closedpoly ) will be ''stroke_color``, ''fill_opacity`` |
||
3129 | @ use these up to 6 colors for the draw primitives used by command <code>multidraw obj_type_1,obj_type_2...obj_type_n</code> |
||
18627 | bpr | 3130 | @ wims will <b>not</b> check if the number of colors matches the amount of draw primitives... |
18556 | bpr | 3131 | @ always use the same sequence as is used for ''multidraw`` |
18627 | bpr | 3132 | @ can also be used with command <a href='#userdraw'>userdraw clickfill,color</a> when more than one fillcolor is wanted.<br>in that case use for example <a href='#replyformat'>replyformat 10</a> ... reply=x1:y1:color1,x2:y2:color2...<br>the colors will restart at the first color, when there are more fill-clicks than multi-fill-colors<br>if more control over the used colors is wanted, see command <a href='#colorpalette'>colorpalette color1,color2...</a> |
18552 | bpr | 3133 | */ |
3134 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3135 | fprintf(js_include_file,"var multifillcolors = ["); |
||
3136 | while( ! done ){ |
||
3137 | temp = get_color(infile,1); |
||
3138 | fprintf(js_include_file,"\"%s\",",temp); |
||
3139 | } |
||
3140 | fprintf(js_include_file,"\"0,0,0\"];");/* add black to avoid trouble with dangling comma... */ |
||
3141 | break; |
||
3142 | case MULTIFILLOPACITY: |
||
3143 | /* |
||
18556 | bpr | 3144 | @ multifillopacity fill_opacity_1,fill_opacity_2,...,fill_opacity_8 |
3145 | @ float values 0 - 1 or integer values 0 - 255 |
||
3146 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3147 | @ if not set all fill opacity_ will be set by previous command <code>opacity int,int</code> and keyword ''filled`` |
||
3148 | @ use these up to 7 different stroke opacities for the draw primitives used by command <code>multidraw obj_type_1,obj_type_2...obj_type_y</code> |
||
3149 | @ wims will not check the amount or validity of your input |
||
3150 | @ always use the same sequence as is used for ''multidraw`` |
||
18552 | bpr | 3151 | */ |
3152 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3153 | temp = get_string(infile,1); |
||
3154 | temp = str_replace(temp,",","\",\""); |
||
3155 | fprintf(js_include_file,"var multifillopacity = [\"%s\"];",temp); |
||
3156 | break; |
||
3157 | case MULTISNAPTOGRID: |
||
3158 | /* |
||
18556 | bpr | 3159 | @ multisnaptogrid 0,1,1 |
3160 | @ alternative: multisnap |
||
3161 | @ meaning draw objects no. 2 (circle) and 3 (segments), in the list of command like <code>multifill points,circle,segments</code>, will snap to the xy-grid (default 1 in x/y-coordinate system: see command <a href='#snaptogrid'>snaptogrid</a>) |
||
3162 | @ freehand drawing...specify precision for reply: all objects snap to grid <code>multisnaptogrid 1,1,1,...</code> |
||
3163 | @ only the xy-values snap_to_grid: all objects snap to grid <code>multisnaptogrid 1,1,1,...</code> |
||
3164 | @ only the x-values snap_to_grid: all objects snap to x-grid <code>multisnaptogrid 2,2,2,...</code> |
||
3165 | @ only the y-values snap_to_grid: all objects snap to y-grid <code>multisnaptogrid 3,3,3,...</code> |
||
3166 | @ if <a href='#snaptopoints'>snaptopoints</a> is defined: all objects snap to points <code>multisnaptogrid 4,4,4,...</code> <br><b>make sure to define the points to snap on...</b> use command <a href='#snaptopoints'>snaptopoints</a> |
||
3167 | @ <code>multisnaptogrid 0,1,2,3,4<br>multidraw text,arrow,line,circle,image</code><br>''text`` is free hand, ''arrow`` is snap to grid, ''line`` is snap to x-grid, ''circle`` is snap to y-grid, ''image`` is snap to points defined by command <a href='#snaptopoints'>snaptopoints</a> |
||
3168 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3169 | @ attention: if not set all objects will be set ''no snap``... unless a generic command ''snaptogrid`` was given before command ''multidraw`` |
||
3170 | @ commands <a href='#xsnaptogrid'>xsnaptogrid</a>, <a href='#ysnaptogrid'>ysnaptogrid</a>, <a href='#snaptofunction'>snaptofunction</a> are <b>not</b> supported amd only functional for command <a href='#userdraw'>userdraw</a> |
||
3171 | @ always use the same sequence as is used for ''multidraw`` |
||
3172 | @ wims will <b>not</b> check if the number of 0 or 1's matches the amount of draw primitives... |
||
18552 | bpr | 3173 | */ |
3174 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3175 | temp = get_string(infile,1); |
||
3176 | fprintf(js_include_file,"var multisnaptogrid = [%s];",temp); |
||
3177 | reset();/* if command 'dashed' was given...reset to not-dashed */ |
||
3178 | break; |
||
3179 | case MULTISTROKECOLORS: |
||
3180 | /* |
||
18556 | bpr | 3181 | @ multistrokecolors color_name_1,color_name_2,...,color_name_8 |
3182 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3183 | @ if not set all colors will be ''stroke_color``, ''stroke_opacity`` |
||
3184 | @ use these up to 6 colors for the draw primitives used by command <code>multidraw obj_type_1,obj_type_2...obj_type_7</code> |
||
18627 | bpr | 3185 | @ wims will <b>not</b> check if the number of colors matches the amount of draw primitives... |
18556 | bpr | 3186 | @ always use the same sequence as is used for ''multidraw`` |
18552 | bpr | 3187 | */ |
3188 | if( use_tooltip == 1 ){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3189 | fprintf(js_include_file,"var multistrokecolors = ["); |
||
3190 | while( ! done ){ |
||
3191 | temp = get_color(infile,1); |
||
3192 | fprintf(js_include_file,"\"%s\",",temp); |
||
3193 | } |
||
3194 | fprintf(js_include_file,"\"0,0,0\"];");/* add black to avoid trouble with dangling comma... */ |
||
3195 | break; |
||
3196 | case MULTISTROKEOPACITY: |
||
3197 | /* |
||
18556 | bpr | 3198 | @ multistrokeopacity stroke_opacity_1,stroke_opacity_2,...,stroke_opacity_7 |
3199 | @ float values 0 - 1 or integer values 0 - 255 |
||
3200 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3201 | @ if not set all stroke opacity_ will be set by previous command <code>opacity int,int</code> |
||
3202 | @ use these up to 7 different stroke opacities for the draw primitives used by command <code>multidraw obj_type_1,obj_type_2...obj_type_7</code> |
||
3203 | @ wims will not check the amount or validity of your input |
||
3204 | @ always use the same sequence as is used for ''multidraw`` |
||
18552 | bpr | 3205 | */ |
3206 | if( use_tooltip == 1){canvas_error("command 'multidraw' is incompatible with command 'intooltip tip_text'");} |
||
3207 | temp = get_string(infile,1); |
||
3208 | temp = str_replace(temp,",","\",\""); |
||
3209 | fprintf(js_include_file,"var multistrokeopacity = [\"%s\"];",temp); |
||
3210 | break; |
||
3211 | case MULTIUSERINPUT: |
||
3212 | /* |
||
3213 | @ multiuserinput 0,1,1,0 |
||
3214 | @ alternative: multiinput |
||
18572 | bpr | 3215 | @ meaning, when the command ''multidraw`` is used <code>multidraw circles,points,lines,triangles</code><br>objects ''points`` and ''lines`` may additionally be ''drawn`` by direct input (inputfields)<br>all other objects must be drawn with a mouse |
18552 | bpr | 3216 | @ in case of circle | circles a third inputfield for Radius (R) is added. The radius must be in the x/y coordinate system (x-range) and <b>not</b> in pixels...students don't think in pixels.<br>note: R-values will not snap-to-grid |
3217 | @ in case of line(s) | segment(s) | arrow(s) the user should write <b>x1:y1</b> in the first inputfield and <b>x2:y2</b> in the second.<br>These ''hints`` are pre-filled into the input field.<br>Other coordinate delimiters are '';`` and '',`` e.g. <b>x1;y1</b> or <b>x1,y1</b>.<br>An error message (alert box) will popup when things are not correctly... |
||
3218 | @ in case of a triangle | poly3, three inputfields are provided. |
||
3219 | @ in case of ''text`` and ''multiuserinput=1, 3`` inputfields will be shown: ''x,y,text`` |
||
3220 | @ in case of ''text`` and ''multiuserinput=0, 1`` inputfield will be shown: text ... a mouse click will place the text on the canvas. |
||
3221 | @ may be styled using command <a href="#css">css</a> |
||
3222 | @ an additional button ''stop drawing`` may be used to combine userbased drawings with ''drag∧drop`` or ''onclick`` elements |
||
3223 | @ when exercise if finished (status=done) the buttons will not be shown.<br>To override this default behaviour use command / keyword ''status`` |
||
3224 | @ use before command <a href='#multidraw'>multidraw</a> |
||
3225 | @ always use the same sequence as is used for ''multidraw`` |
||
3226 | */ |
||
3227 | /* simple rawmath and input check */ |
||
3228 | js_function[JS_SAFE_EVAL] = 1; |
||
3229 | temp = get_string(infile,1); |
||
3230 | temp = str_replace(temp,",","\",\""); |
||
3231 | fprintf(js_include_file,"var multiuserinput = [\"%s\"];",temp); |
||
3232 | break; |
||
3233 | case NORESET: |
||
3234 | /* |
||
3235 | @ noreset |
||
3236 | @ alternative: killreset |
||
3237 | @ keyword |
||
3238 | @ may come in handy if canvas script code is generated using loops |
||
3239 | @ if used the following properties will remain to be valid<br><ul><li>filled</li><li>dash settings</li><li>onclick or drag settings</li><li>centering or offset</li></ul> |
||
3240 | @ if used again, these properies will be reset to the default values and normal behaviour is continued (e.g. the above properties will be reset after 'use' on a canvas object) |
||
3241 | @ etc etc |
||
3242 | @ commands <a href='#slider'>slider</a>, <a href='#linear'>linear</a>, <a href='#rotate'>rotate</a>, <a href='#translate'>translate</a>, <a href='#affine'>affine</a> are always active until the 'kill' commands are given: <br><a href='#killlinear'>killlinear</a>, <a href='#killrotate'>killrotate</a>, <a href='#killtranslate'>killtranslate</a> and <a href='#killaffine'>killaffine</a> |
||
3243 | @ commands like 'opacity', 'linewidth', 'fontsize', 'fontfamily' are only changed when redefined again |
||
3244 | @%noreset%size 400,400%xrange -10,10%yrange -10,10%noreset%drag xy%linewidth 4%filled%rect -4,4,-2,2,blue%triangle -3,-3,0,0,1,-5,green%circle 0,0,50,orange%noreset%rect 2,4,4,2,blue |
||
3245 | @%noreset_oefgraduation%size 800,100%xrange 0,11%yrange -1,1%hline 0,0,black%parallel 0,0,0,0.5,1,0,11,blue%noreset%onclick%centered%text black,1,0.6,large,20%text black,2,0.6,large,30%text black,3,0.6,large,40%text black,4,0.6,large,50%text black,5,0.6,large,60%text black,6,0.6,large,70%text black,7,0.6,large,80%text black,8,0.6,large,90%text black,9,0.6,large,100%text black,10,0.6,large,110 |
||
3246 | */ |
||
3247 | if(no_reset == FALSE){no_reset = TRUE;}else{no_reset = FALSE;reset();} |
||
3248 | break; |
||
3249 | case NOXAXIS: |
||
3250 | /* |
||
3251 | @ noxaxis |
||
3252 | @ keyword |
||
3253 | @ if set, the automatic x-axis numbering will be ignored |
||
3254 | @ use command <a href="#axis">axis</a> to have a visual x/y-axis lines (see command <a href="#grid">grid</a>) |
||
3255 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
3256 | */ |
||
3257 | fprintf(js_include_file,"x_strings = {};x_strings_up = [];\n"); |
||
3258 | use_axis_numbering = -1; |
||
3259 | break; |
||
3260 | case NOYAXIS: |
||
3261 | /* |
||
3262 | @ noyaxis |
||
3263 | @ keyword |
||
3264 | @ if set, the automatic y-axis numbering will be ignored |
||
3265 | @ use command <a href="#axis">axis</a> to have a visual x/y-axis lines (see command <a href="#grid">grid</a>) |
||
3266 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
3267 | */ |
||
3268 | fprintf(js_include_file,"y_strings = {};\n"); |
||
3269 | break; |
||
3270 | case NUMBERLINE: |
||
3271 | /* |
||
3272 | @ numberline x0,x1,xmajor,xminor,y0,y1 |
||
3273 | @ numberline is using xrange/yrange system for all dimensions |
||
3274 | @ multiple numberlines are allowed ; combinations with command <a href='#grid'>grid</a> is allowed; multiple commands <a href='#xaxis'>xaxis numbering</a> are allowed |
||
3275 | @ x0 is start x-value in xrange |
||
3276 | @ x1 is end x-value in xrange |
||
3277 | @ xmajor is step for major division |
||
3278 | @ xminor is divisor of xmajor; using small (30% of major tick) tick marks: this behaviour is ''hardcoded`` |
||
3279 | @ is xminor is an even divisor, an extra tickmark (60% of major tick) is added to the numberline: this behaviour is ''hardcoded`` |
||
3280 | @ y0 is bottom of numberline; y1 endpoint of major tics |
||
3281 | @ use command <a href="#linewidth">linewidth</a> to control appearance |
||
3282 | @ use <a href="#strokecolor">strokecolor</a> and <a href="#opacity">opacity</a> to controle measure line |
||
3283 | @ for all ticks linewidth and color / opacity are identical. |
||
3284 | @ if command <a href="#xaxis">xaxis</a> or <a href="#xaxisup">xaxisup</a> is not defined, the labeling will be on major ticks: x0...x1 |
||
3285 | @ use <a href="#fontfamily">fontfamily</a> and <a href="#fontcolor">fontcolor</a> to control fonts settings |
||
3286 | @ may be used together with <a href="#userdraw">userdraw</a>, <a href="#multidraw">multidraw</a> and <a href="#drag">user drag</a> command family for the extra object drawn onto the numberline |
||
3287 | @ <a href="#snaptogrid">snaptogrid, snaptopoints etc</a> and <a href="#zoom">zooming and panning</a> is supported |
||
3288 | @ onclick and dragging of the numberline are not -yet- supported |
||
3289 | @ note: in case of multiple numberlines, make sure the numberline without special x-axis numbering (e.g. ranging from xmin to xmax) comes first ! |
||
3290 | @%numberline%size 400,400%xrange -10,10%yrange -10,10%precision 1%strokecolor black%numberline -8,8,1,6,-4,-3.5%strokecolor red%xaxis -4:AA:-2:BB:2:CC:4:DD%numberline -8,8,1,2,4,4.5%strokecolor green%xaxisup -4:AAA:-2:BBB:2:CCC:4:DDD%numberline -8,8,1,3,2,2.5%strokecolor blue%xaxis -4:AAAA:-2:BBBB:2:CCCC:4:DDDD%numberline -8,8,1,4,0,0.5%strokecolor brown%xaxis -4:AAAAA:-2:BBBBB:2:CCCCC:4:DDDDD%numberline -8,8,1,5,-2,-1.5%zoom red |
||
3291 | */ |
||
3292 | js_function[DRAW_NUMBERLINE] = 1; |
||
3293 | for(i=0;i<6;i++){ |
||
3294 | switch(i){ |
||
3295 | case 0: double_data[0] = get_real(infile,0);break;/* xmin */ |
||
3296 | case 1: double_data[1] = get_real(infile,0);break;/* xmax */ |
||
3297 | case 2: double_data[2] = get_real(infile,0);break;/* xmajor */ |
||
3298 | case 3: double_data[3] = get_real(infile,0);break;/* xminor */ |
||
3299 | case 4: double_data[4] = get_real(infile,0);break;/* ymin */ |
||
3300 | case 5: double_data[5] = get_real(infile,1);/* ymax */ |
||
3301 | /* |
||
3302 | var draw_numberline%d = function(canvas_type,xmin,xmax,xmajor,xminor,ymin,ymax,linewidth,strokecolor,strokeopacity,fontfamily,fontcolor); |
||
3303 | */ |
||
3304 | fprintf(js_include_file,"snap_x = %f;snap_y = %f;",double_data[2] / double_data[3],double_data[5] - double_data[4] ); |
||
18557 | bpr | 3305 | tmp_buffer=my_newmem(MAX_BUFFER); |
3306 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "\ndraw_numberline(%d,%d,%f,%f,%f,%f,%f,%f,%d,\"%s\",%f,\"%s\",\"%s\",%d); ",NUMBERLINE_CANVAS+numberline_cnt,use_axis_numbering,double_data[0],double_data[1],double_data[2],double_data[3],double_data[4],double_data[5],line_width,stroke_color,stroke_opacity,font_family,font_color,precision)); |
||
18552 | bpr | 3307 | add_to_buffer(tmp_buffer); |
3308 | numberline_cnt++; |
||
3309 | break; |
||
3310 | default:break; |
||
3311 | } |
||
3312 | } |
||
3313 | reset(); |
||
3314 | break; |
||
3315 | case OBABEL: |
||
3316 | /* |
||
3317 | @ obabel x,y,type input,molecule smiles-code or file location, extra arguments,extra arguments,... |
||
3318 | @ will call the ''obabel`` program, if installed. |
||
3319 | @ output will be an svg file |
||
3320 | @ see documentation of obabel for special keys |
||
3321 | @ command <a href='#affine'>affine</a> will produce CSS3 matrix transformations |
||
3322 | @ command <a href='#rotate'>rotate</a> will rotate the object |
||
3323 | @ can be set onclick: <code>javascript:read_dragdrop();</code> will return click numbers of mathml-objects<br>if 4 clickable object are drawn, the reply could be 1,0,1,0 ... meaning clicked on the first and third object |
||
3324 | @ can be set draggable: <code>javascript:read_dragdrop();</code> will return all coordinates in the same order as the canvas script: unmoved object will have their original coordinates... |
||
3325 | @ snaptogrid is supported...snaptopoints will work, but use with care...due to the primitive dragging<br>technically: the dragstuff library is not used...the mathml is embedded in a new div element and not in the html5-canvas |
||
3326 | @ external files may be loaded if they are present on the server or in the modules <br>for example:<br> obabel 0,0,mol,$module_dir/caffeine.mol,-P100,-xb none |
||
3327 | @%obabel_smi%size 400,400%xrange -10,10%yrange -10,10%fillcolor green%drag xy%centered%obabel 0,0,smi,-:c1cFccc1cc,-xb none,-xB blue,-xi,-xt,-xa,-xX,-xP180,-h |
||
3328 | */ |
||
3329 | js_function[DRAW_XML] = 1; |
||
3330 | for(i=0;i<4;i++){ |
||
3331 | switch(i){ |
||
3332 | case 0: double_data[0]=get_real(infile,0);break; /* x in x/y-range coord system -> pixel width */ |
||
3333 | case 1: double_data[1]=get_real(infile,0);break; /* y in x/y-range coord system -> pixel height */ |
||
3334 | case 2: URL = get_string_argument(infile,0);break; |
||
3335 | case 3: |
||
3336 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3337 | temp = getSVGMOL(URL,get_string(infile,1)); |
||
3338 | decimals = find_number_of_digits(precision); |
||
3339 | if(use_affine == TRUE ){ transform(2,2);} |
||
3340 | if( use_offset != 0 || drag_type != -1 ){int_data[2] = 1;}else{int_data[2] = 0;} /* only centered or not-centered */ |
||
3341 | int_data[0] = x2px(double_data[0]); |
||
3342 | int_data[1] = y2px(double_data[1]); |
||
3343 | if( use_slider != -1 && onclick == 0 ){ onclick = 3;}/* no drag&onclick but slideable */ |
||
3344 | if( use_slider != -1 && drag_type > 0 ){ onclick = 5;}/* slider+drag*/ |
||
3345 | if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\"","'"); } |
||
18557 | bpr | 3346 | tmp_buffer=my_newmem(MAX_BUFFER); |
3347 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "var draw_xml%d = {id:%d,type:'svg',x:[%d],y:[%d],mathml:\"%s\",drag_type:%d,onclick:%d,object_cnt:%d,stroke_color:\"%s\",stroke_opacity:%.2f,fill_color:\"%s\",fill_opacity:%.2f,use_center:%d,use_snap:%d,angle:%f,fontfamily:\"%s\",transform:%s,use_affine:%d,offset:[0,0],use_slider:%s,rotation_center:%s,once:true};slidergroup[%d] = null;draw_xml(draw_xml%d);\n",drawxml_cnt,drawxml_cnt,int_data[0],int_data[1],temp,drag_type,onclick,object_cnt,stroke_color,stroke_opacity,fill_color,fill_opacity,int_data[2],use_snap,angle,font_family,doubledata2js_array(affine_matrix,6,decimals),use_affine,my_sliders,rotation_center,object_cnt,drawxml_cnt)); |
||
18552 | bpr | 3348 | add_to_buffer(tmp_buffer); |
3349 | if(onclick != 0 ){object_cnt++;} |
||
3350 | drawxml_cnt++;/* keeps track on imported img,div,p,span,mathml,svg */ |
||
3351 | break; |
||
3352 | default:break; |
||
3353 | } |
||
3354 | } |
||
3355 | reset(); |
||
3356 | break; |
||
3357 | case OPACITY: |
||
3358 | /* |
||
3359 | @ opacity [0-255],[0-255] |
||
3360 | @ opacity [0.0 - 1.0],[0.0 - 1.0] |
||
3361 | @ alternative: transparent |
||
3362 | @ first item is stroke opacity, second is fill opacity |
||
3363 | @%opacity%size 400,400%xrange -10,10%yrange -10,10%opacity 255,0%fcircle -10,0,100,blue%opacity 250,50%fcircle -5,0,100,blue%opacity 200,100%fcircle 0,0,100,blue%opacity 150,150%fcircle 5,0,100,blue%opacity 100,200%fcircle 10,0,100,blue |
||
3364 | */ |
||
3365 | for(i = 0 ; i<2;i++){ |
||
3366 | switch(i){ |
||
3367 | case 0: double_data[0]= get_real(infile,0);break; |
||
3368 | case 1: double_data[1]= get_real(infile,1);break; |
||
3369 | default: break; |
||
3370 | } |
||
3371 | } |
||
3372 | if( double_data[0] > 255 || double_data[1] > 255 || double_data[0] < 0 || double_data[1] < 0 ){ canvas_error("opacity [0 - 255], [0 - 255] ");}/* typo or non-RGB ? */ |
||
18608 | bpr | 3373 | if( double_data[0] > 1 ){ stroke_opacity = (double) (0.0039215*double_data[0]); }else{ stroke_opacity = double_data[0];} /* 0.0 - 1.0 */ |
3374 | if( double_data[1] > 1 ){ fill_opacity = (double) (0.0039215*double_data[1]); }else{ fill_opacity = double_data[1];} /* 0.0 - 1.0 */ |
||
18552 | bpr | 3375 | break; |
18608 | bpr | 3376 | case STROKEOPACITY: |
3377 | /* |
||
3378 | @ strokeopacity [0-255] |
||
3379 | @ strokeopacity [0.0 - 1.0] |
||
3380 | @%strokeopacity%size 400,400%xrange -10,10%yrange -10,10%fillopacity 120%strokeopacity 255%circle -10,0,100,blue%strokeopacity 100%circle -5,0,100,blue%strokeopacity 50%circle 0,0,100,blue |
||
3381 | */ |
||
3382 | double_data[0]= get_real(infile,1); |
||
3383 | if( double_data[0] > 255 || double_data[0] < 0 ){ canvas_error("opacity [0 - 255] ");}/* typo or non-RGB ? */ |
||
3384 | if( double_data[0] > 1 ){ stroke_opacity = (double) (0.0039215*double_data[0]); }else{ stroke_opacity = double_data[0];} /* 0.0 - 1.0 */ |
||
3385 | break; |
||
3386 | case FILLOPACITY: |
||
3387 | /* |
||
3388 | @ fillopacity [0-255] |
||
3389 | @ fillopacity [0.0 - 1.0] |
||
3390 | @%fillopacity%size 400,400%xrange -10,10%yrange -10,10%strokeopacity 100%%fillopacity 0%fcircle -10,0,100,blue%fillopacity 50%fcircle -5,0,100,blue%fillopacity 100%fcircle 0,0,100,blue%fillopacity 150%fcircle 5,0,100,blue%fillopacity 200%fcircle 10,0,100,blue |
||
3391 | */ |
||
3392 | double_data[0]= get_real(infile,1); |
||
3393 | if( double_data[0] > 255 || double_data[0] < 0 ){ canvas_error("fillopacity [0 - 255] ");}/* typo or non-RGB ? */ |
||
3394 | if( double_data[0] > 1 ){ fill_opacity = (double) (0.0039215*double_data[0]); }else{ fill_opacity = double_data[0];} /* 0.0 - 1.0 */ |
||
3395 | break; |
||
18552 | bpr | 3396 | case ONCLICK: |
3397 | /* |
||
18556 | bpr | 3398 | @ onclick |
3399 | @ keyword (no arguments required) |
||
3400 | @ if the next object is clicked, its ''object onclick_or_drag sequence number`` in fly script is returned by <code>javascript:read_canvas();</code> |
||
3401 | @ onclick seqeuence numbering starts at ''0``, e.g. if there are 6 objects set onclick, the first onclick object will have id-number ''0``, the last id-number ''5`` |
||
3402 | @ line based objects will show an increase in line width<br>font based objects will show the text in ''bold`` when clicked. |
||
3403 | @ the click zone (accuracy) is determined by 2× the line width of the object |
||
3404 | @ onclick and <a href="#drag">drag x|y|xy</a> may be combined in a single flyscript (although a single object can <b>not</b> be onclick and draggable at the same time...) |
||
3405 | @ note: not all objects may be set onclick |
||
3406 | @%onclick%size 400,400%xrange -10,10%yrange -10,10%opacity 255,60%linewidth 3%onclick%fcircles blue,-3,3,1,1,2,2,3,1,1%onclick%ftriangles red,-4,-4,-4,0,-3,-2,0,0,4,0,2,-4%onclick%frects green,-4,4,-2,2,1,-1,3,-4 |
||
18552 | bpr | 3407 | */ |
3408 | fprintf(js_include_file,"use_dragdrop_reply = true;"); |
||
3409 | onclick = 1; |
||
3410 | use_dragstuff=2; |
||
3411 | js_function[INTERACTIVE] = 1; |
||
3412 | break; |
||
3413 | case PARALLEL: |
||
3414 | /* |
||
18556 | bpr | 3415 | @ parallel x1,y1,x2,y2,dx,dy,n,[colorname or #hexcolor] |
3416 | @ affine transformations should be identical to flydraw |
||
3417 | @ in case of <a href='#rotate'>rotation</a> or <a href='#affine'>affine transformation </a>, command parallel will produce <em>n</em> individual segments, and these may be set ''onclick`` or ''drag xy`` individually. |
||
3418 | @ in case of <em>no rotation or transformations</em> the lines can not be set ''onclick`` or ''drag xy``. |
||
3419 | @ note: a large number of parallel lines (large <em>n</em>) may result in a canvasdraw error (...simplify your script...it produces too many lines...) |
||
3420 | @%parallel_click%size 400,400%xrange -10,10%yrange -10,10%parallel -5,5,-4,-5,0.25,0,40,red%rotate 45%onclick%parallel -5,5,-4,-5,0.25,0,40,blue |
||
3421 | @%parallel%size 400,400%xrange -10,10%yrange -10,10%parallel -5,5,-4,-5,0.25,0,40,red |
||
18552 | bpr | 3422 | */ |
3423 | decimals = find_number_of_digits(precision); |
||
3424 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3425 | if( use_rotate == TRUE || use_affine == TRUE ){ |
||
3426 | for( i = 0;i < 8; i++ ){ |
||
3427 | switch(i){ |
||
3428 | case 0: double_data[0] = get_real(infile,0);break; /* x1-values */ |
||
3429 | case 1: double_data[1] = get_real(infile,0);break; /* y1-values */ |
||
3430 | case 2: double_data[2] = get_real(infile,0);break; /* x2-values */ |
||
3431 | case 3: double_data[3] = get_real(infile,0);break; /* y2-values */ |
||
3432 | case 4: double_data[4] = get_real(infile,0);break; /* xv */ |
||
3433 | case 5: double_data[5] = get_real(infile,0);break; /* yv */ |
||
3434 | case 6: int_data[0] = (int) (get_real(infile,0));break; /* n */ |
||
3435 | case 7: stroke_color=get_color(infile,1);break;/* name or hex color */ |
||
3436 | default: break; |
||
3437 | } |
||
3438 | } |
||
3439 | double_data[6] = double_data[0]; /* x1 */ |
||
3440 | double_data[7] = double_data[1]; /* y1 */ |
||
3441 | double_data[8] = double_data[2]; /* x2 */ |
||
3442 | double_data[9] = double_data[3]; /* y2 */ |
||
3443 | for(i = 0 ; i < int_data[0] ; i++){ |
||
3444 | double_data[0] = double_data[6] + i*double_data[4]; |
||
3445 | double_data[1] = double_data[7] + i*double_data[5]; |
||
3446 | double_data[2] = double_data[8] + i*double_data[4]; |
||
3447 | double_data[3] = double_data[9] + i*double_data[5]; |
||
3448 | if(use_rotate == TRUE ){ rotate(4,angle,rotationcenter,2);} |
||
3449 | if(use_affine == TRUE ){ transform(4,2);} |
||
18557 | bpr | 3450 | tmp_buffer=my_newmem(MAX_BUFFER); |
3451 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3452 | add_to_buffer(tmp_buffer); |
3453 | if(onclick != 0){object_cnt++;} |
||
3454 | } |
||
3455 | dragstuff[4] = 1; |
||
3456 | } |
||
3457 | else /* use the old parallel version: calculations in javascript */ |
||
3458 | { |
||
3459 | for( i = 0;i < 8; i++ ){ |
||
3460 | switch(i){ |
||
3461 | case 0: double_data[0] = get_real(infile,0);break; /* x1-values */ |
||
3462 | case 1: double_data[1] = get_real(infile,0);break; /* y1-values */ |
||
3463 | case 2: double_data[2] = get_real(infile,0);break; /* x2-values */ |
||
3464 | case 3: double_data[3] = get_real(infile,0);break; /* y2-values */ |
||
3465 | case 4: double_data[4] = xmin + get_real(infile,0);break; /* xv */ |
||
3466 | case 5: double_data[5] = ymax + get_real(infile,0);break; /* yv */ |
||
3467 | case 6: int_data[0] = (int) (get_real(infile,0));break; /* n */ |
||
3468 | case 7: stroke_color=get_color(infile,1);/* name or hex color */ |
||
18557 | bpr | 3469 | tmp_buffer=my_newmem(MAX_BUFFER); |
3470 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,11,[%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f],[%d,%d,%d],[%d,%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],int_data[0],int_data[0],int_data[0],int_data[0],int_data[0],int_data[0],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3471 | add_to_buffer(tmp_buffer); |
3472 | if(onclick != 0){object_cnt++;} |
||
3473 | break; |
||
3474 | default: break; |
||
3475 | } |
||
3476 | dragstuff[11] = 1; |
||
3477 | } |
||
3478 | } |
||
3479 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3480 | reset(); |
||
3481 | break; |
||
3482 | case PLOTSTEPS: |
||
3483 | /* |
||
18556 | bpr | 3484 | @ plotsteps a_number |
3485 | @ default 150 |
||
3486 | @ only used for commands <a href="#curve">curve / plot</a> and <a href="#levelcurve">levelcurve</a> |
||
3487 | @ use with care ! |
||
18552 | bpr | 3488 | */ |
3489 | plot_steps = (int) (get_real(infile,1)); |
||
3490 | break; |
||
3491 | case POINT: |
||
3492 | /* |
||
3493 | @ point x,y,color |
||
3494 | @ draw a single point at (x;y) in color 'color' |
||
3495 | @ use command <code>linewidth int</code> to adjust size |
||
3496 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
3497 | @ will not resize on zooming (command <code>circle x,y,r,color</code> will resize on zooming) |
||
3498 | @ attention: in case of command <a href="#rotate">rotate angle</a> a point has rotation center (0:0) in x/y-range |
||
3499 | @%point%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%linewidth 1%onclick%point 0,0,red%linewidth 2%onclick%point 1,1,blue%linewidth 3%onclick%point 3,3,green%linewidth 4%point 4,4,orange |
||
3500 | */ |
||
3501 | for(i=0;i<3;i++){ |
||
3502 | switch(i){ |
||
3503 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
3504 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
3505 | case 2: stroke_color = get_color(infile,1);/* name or hex color */ |
||
3506 | if(use_rotate == TRUE ){rotate(2,angle,rotationcenter,2);} |
||
3507 | if(use_affine == TRUE ){ transform(2,2);} |
||
3508 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3509 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 3510 | tmp_buffer=my_newmem(MAX_BUFFER); |
3511 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,2,[%.*f],[%.*f],[%.2f],[%d],%.2f,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],1.5*line_width,line_width,1.5*line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,1,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3512 | add_to_buffer(tmp_buffer); |
3513 | /* object_cnt++; */ |
||
3514 | if(onclick != 0){object_cnt++;} |
||
3515 | break; |
||
3516 | default: break; |
||
3517 | } |
||
3518 | } |
||
3519 | dragstuff[2] = 1; |
||
3520 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3521 | reset(); |
||
3522 | break; |
||
3523 | case POINTS: |
||
3524 | /* |
||
3525 | @ points color,x1,y1,x2,y2,...,x_n,y_n |
||
3526 | @ draw multiple points at given coordinates in color 'color' |
||
3527 | @ use command <code>linewidth int</code> to adjust size |
||
3528 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
3529 | @ attention: in case of command <a href="#rotate">rotate angle</a> the points have rotation center (0:0) in x/y-range |
||
3530 | @%points_1%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%snaptogrid%linewidth 1%drag xy%points red,0,0,1,1,2,2,3,3%drag x%points blue,0,1,1,2,2,3,3,4 |
||
3531 | @%points_2%size 400,400%xrange -10,10%yrange -10,10%opacity 255,255%linewidth 1%onclick%points red,0,0,1,1,2,2,3,3%onclick%points blue,0,1,1,2,2,3,3,4 |
||
3532 | */ |
||
3533 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
3534 | fill_color = stroke_color; |
||
3535 | i=0; |
||
3536 | while( ! done ){ /* get next item until EOL*/ |
||
3537 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3538 | if(i%2 == 0 ){ |
||
3539 | double_data[i] = get_real(infile,0); /* x */ |
||
3540 | } |
||
3541 | else { |
||
3542 | double_data[i] = get_real(infile,1); /* y */ |
||
3543 | } |
||
3544 | i++; |
||
3545 | } |
||
3546 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3547 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3548 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3549 | decimals = find_number_of_digits(precision); |
||
3550 | for(c = 0 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 3551 | tmp_buffer=my_newmem(MAX_BUFFER); |
3552 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,2,[%.*f],[%.*f],[%.2f],[%d],%.2f,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],1.5*line_width,line_width,1.5*line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,1,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3553 | add_to_buffer(tmp_buffer); |
3554 | /* object_cnt++; */ |
||
3555 | if(onclick != 0){object_cnt++;} |
||
3556 | } |
||
3557 | dragstuff[2] = 1; |
||
3558 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3559 | reset(); |
||
3560 | break; |
||
3561 | case POLY: |
||
3562 | /* |
||
3563 | @ poly color,x1,y1,x2,y2...x_n,y_n |
||
3564 | @ polygon color,x1,y1,x2,y2...x_n,y_n |
||
3565 | @ draw closed polygon |
||
3566 | @ use command ''fpoly`` to fill it or use keyword <a href='#filled'>filled</a> |
||
3567 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
3568 | @%polygon_1%size 400,400%xrange -10,10%yrange -10,10%opacity 255,25%fillcolor orange%filled%linewidth 2%drag xy%snaptogrid%poly blue,0,0,1,3,3,1,2,4,-1,3 |
||
3569 | @%polygon_2%size 400,400%xrange -10,10%yrange -10,10%opacity 255,25%fillcolor orange%filled%linewidth 1%onclick%poly green,0,0,1,3,3,1,2,4,-1,3 |
||
3570 | */ |
||
3571 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
3572 | i=0; |
||
3573 | c=0; |
||
3574 | while( ! done ){ /* get next item until EOL*/ |
||
3575 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3576 | for( c = 0 ; c < 2; c++){ |
||
3577 | if(c == 0 ){ |
||
3578 | double_data[i] = get_real(infile,0); |
||
3579 | i++; |
||
3580 | } |
||
3581 | else { |
||
3582 | double_data[i] = get_real(infile,1); |
||
3583 | i++; |
||
3584 | } |
||
3585 | } |
||
3586 | } |
||
3587 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3588 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3589 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
8386 | schaersvoo | 3590 | |
18552 | bpr | 3591 | /* draw path: closed & optional filled */ |
3592 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 3593 | tmp_buffer=my_newmem(MAX_BUFFER); |
3594 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,5,%s,[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,double_xy2js_array(double_data,i,decimals),line_width,stroke_color,stroke_opacity,stroke_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3595 | add_to_buffer(tmp_buffer); |
3596 | if(onclick != 0){object_cnt++;} |
||
3597 | reset(); |
||
3598 | dragstuff[5] = 1; |
||
3599 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3600 | break; |
||
3601 | case POLYLINE: |
||
3602 | /* |
||
3603 | @ polyline color,x1,y1,x2,y2...x_n,y_n |
||
3604 | @ brokenline color,x1,y1,x2,y2...x_n,y_n |
||
3605 | @ path color,x1,y1,x2,y2...x_n,y_n |
||
3606 | @ remark: there is <b>no</b> command polylines | brokenlines | paths ... just use multiple commands <code>polyline, x1,y1,x2,y2...x_n,y_n</code> |
||
3607 | @ remark: there are commands <code>userdraw path(s),color</code> and <code>userdraw polyline,color</code>... these are two entirely different things ! the path(s) userdraw commands may be used for freehand drawing(s)<br>the polyline userdraw command is analogue to this polyline|brokenline command |
||
3608 | @ the command interconnects the points in the given order with a line (canvasdraw will not close the drawing: use command <a href="#poly">polygon</a> for this) |
||
3609 | @ use command <a href='#segments'>segments</a> for a series of segments. These may be clicked/dragged individually |
||
3610 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
3611 | @%polyline_1%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag xy%snaptogrid%polyline blue,0,0,1,3,3,1,2,4,-1,3 |
||
3612 | @%polyline_2%size 400,400%xrange -10,10%yrange -10,10%linewidth 1%onclick%polyline green,0,0,1,3,3,1,2,4,-1,3 |
||
3613 | */ |
||
11806 | schaersvoo | 3614 | |
18552 | bpr | 3615 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
3616 | i=0; |
||
3617 | c=0; |
||
3618 | while( ! done ){ /* get next item until EOL*/ |
||
3619 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3620 | for( c = 0 ; c < 2; c++){ |
||
3621 | if(c == 0 ){ |
||
3622 | double_data[i] = get_real(infile,0); |
||
3623 | i++; |
||
3624 | } |
||
3625 | else { |
||
3626 | double_data[i] = get_real(infile,1); |
||
3627 | i++; |
||
3628 | } |
||
3629 | } |
||
3630 | } |
||
11806 | schaersvoo | 3631 | |
18552 | bpr | 3632 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
3633 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3634 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
11806 | schaersvoo | 3635 | |
18552 | bpr | 3636 | /* draw path: not closed & not filled */ |
3637 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 3638 | tmp_buffer=my_newmem(MAX_BUFFER); |
3639 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,%s,[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,double_xy2js_array(double_data,i,decimals),line_width,stroke_color,stroke_opacity,stroke_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3640 | add_to_buffer(tmp_buffer); |
3641 | if(onclick != 0){object_cnt++;} |
||
3642 | /* object_cnt++;*/ |
||
3643 | reset(); |
||
3644 | dragstuff[4] = 1; |
||
3645 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3646 | break; |
||
3647 | case POPUP: |
||
3648 | /* |
||
18556 | bpr | 3649 | @ popup |
3650 | @ keyword (no arguments) |
||
3651 | @ if fly-script starts with keyword ''popup``, the canvas image will be exclusively in a popup window (xsize px × ysize px) |
||
3652 | @ if keyword ''popup`` is used after command <code>size xsize,ysize</code> the canvas will also be displayed in a popup window with size ''xsize × ysize`` |
||
3653 | @ the popup window will be embedded into the page as a normal image, when ''status=done``; override with keyword <a href="#status">nostatus</a> |
||
3654 | @ to access the read_canvas and read_dragdrop functions in a popup window, use:<br> <code> function read_all(){<br> if( typeof popup !== 'undefined' ){<br> var fun1 = popup['read_dragdrop'+canvas_scripts[0]];<br>var fun2 = popup['read_canvas'+canvas_scripts[0]];<br> popup.close();<br> return "dragdrop="+fun1()+"\\ncanvas="+fun2();<br> };</code> |
||
3655 | @ to set a canvasdraw produced <a href="#clock">clock</a> or multiple clocks...use something like: <code>popup.set_clock(clock_id,type,diff);</code> as js-function for a button (or something else) in your document page.<br>where in <b>clock_id</b> starts with 0 for the first clock<br><b>type</b> is 1 for Hours,2 for Minutes and 3 for Seconds<br><b>diff</b> is the increment (positive or negative) per click |
||
3656 | @%popup%popup%size 400,400%xrange -2*pi,2*pi%yrange -5,5%precision 0%axis%axisnumbering%opacity 100,190%grid 1,1,grey,2,2,5,black%linewidth 4%fillcolor blue%trange -pi,pi%animate%linewidth 1%precision 1000%jsplot red,4*cos(2*x),2*sin(3*x-pi/6)%strokecolor green%functionlabel H(x)=%userinput function |
||
18552 | bpr | 3657 | */ |
3658 | use_tooltip = 2; |
||
3659 | break; |
||
3660 | case PROTRACTOR: |
||
3661 | /* |
||
18556 | bpr | 3662 | @ protractor x,y,x_width,type,mode,use_a_scale |
3663 | @ x,y are the initial location |
||
3664 | @ x_width: give the width in x-coordinate system (e.g. not in pixels !) |
||
3665 | @ type = 1: a triangle range 0 - 180<br>type = 2: a circle shape 0 - 360 |
||
3666 | @ mode: use -1 to set the protractor interactive (mouse movement of protractor)<br>use mode = '0° - 360°' to set the protractor with a static angle of some value |
||
3667 | @ if the value of the user_rotation angle is to be shown...use command <a href='#display'>display degree,color,fontsize</a><a href='#display'>display radian,color,fontsize</a> |
||
3668 | @ use_scale = 1: the protractor will have some scale values printed; use_scale=0 to disable |
||
3669 | @ the rotating direction of the mouse around the protractor determines the clockwise/ counter clockwise rotation of the protractor... |
||
3670 | @ commands ''stroke_color | fill_color | linewidth | opacity | font_family`` will determine the looks of the protractor. |
||
3671 | @ default replyformat: reply[0] = x;reply[1] = y;reply[2] = angle_in_radians<br>use command ''precision`` to set the reply precision. |
||
3672 | @ if combined with a ruler, use replyformat = 32 |
||
3673 | @ command <code>snap_to_grid</code> may be used to assist the pupil at placing the protractor |
||
3674 | @ when using command ''zoom``, pay <b>attention</b> to the size and symmetry of your canvas<br>...to avoid a partial image, locate the start position near the center of the visual canvas<br>technical: the actual ''protractor`` is just a static generated image in a new canvas-memory<br>This image is only generated once, and a copy of its bitmap is translated & rotated onto the visible canvas.<br>That is the reason for the ''high-speed dragging and rotating``.<br>I've limited its size to xsize × ysize e.g. the same size as the visual canvas... |
||
3675 | @ only one protractor allowed (for the time being) |
||
3676 | @ usage: first left click on the protractor will activate dragging;<br>a second left click will activate rotating (just move mouse around)<br>a third click will freeze this position and the x/y-coordinate and angle in radians will be stored in reply(3)<br>a next click will restart this sequence... |
||
3677 | @%protractor%size 400,400%xrange -5,10%yrange -5,10%hline 0,0,black%vline 0,0,black%fillcolor orange%opacity 255,40%protractor 2,-2,6,0,-1,1,1%mouse red,22 |
||
18552 | bpr | 3678 | */ |
3679 | for( i = 0;i < 6; i++ ){ |
||
3680 | switch(i){ |
||
3681 | case 0: double_data[0] = get_real(infile,0);break; /* x-center */ |
||
3682 | case 1: double_data[1] = get_real(infile,0);break; /* y-center */ |
||
3683 | case 2: double_data[2] = get_real(infile,0);break; /* x-width */ |
||
3684 | case 3: int_data[0] = (int)(get_real(infile,0));break; /* type: 1==triangle 2 == circle */ |
||
3685 | case 4: int_data[1] = (int)(get_real(infile,0));break; /* passive mode == 0; active mode == -1 */ |
||
3686 | case 5: int_data[2] = (int)(get_real(infile,1)); /* use scale */ |
||
3687 | decimals = find_number_of_digits(precision); |
||
3688 | if( int_data[1] < 0 ){ js_function[JS_FIND_ANGLE] = 1;} |
||
18557 | bpr | 3689 | add_js_protractor(int_data[0],double_data[0], double_data[1], double_data[2],font_family,stroke_color,stroke_opacity,fill_color,fill_opacity,line_width,int_data[2],int_data[1],use_snap); |
3690 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
3691 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, ";protractor%d(); ",canvas_root_id)); |
||
18552 | bpr | 3692 | add_to_buffer(tmp_buffer); |
3693 | reply_precision = precision; |
||
3694 | /* no reply from protractor if non-interactive */ |
||
3695 | if( reply_format == 0 && int_data[1] == -1 ){reply_format = 30;} |
||
3696 | js_function[INTERACTIVE] = 1; |
||
3697 | break; |
||
3698 | default: break; |
||
3699 | } |
||
3700 | } |
||
3701 | break; |
||
3702 | case PIXELS: |
||
3703 | /* |
||
3704 | @ pixels color,x1,y1,x2,y2,x3,y3... |
||
3705 | @ draw rectangular "points" with diameter 1 pixel |
||
3706 | @ pixels can <b>not</b> be dragged or clicked |
||
3707 | @ "pixelsize = 1" may be changed by command <code>pixelsize int</code> |
||
3708 | @%pixels%size 400,400%opacity 255,255%pixelsize 5%pixels red,1,1,2,2,3,3,4,4,5,5,10,10,20,20,30,30,40,40,50,50,60,60,70,70,80,80,90,90,100,100,120,120,140,140,160,160,180,180,200,200,240,240,280,280,320,320,360,360,400,400%#NOTE pixelsize=5...otherwise you will not see them clearly... |
||
3709 | */ |
||
3710 | js_function[DRAW_PIXELS] = 1; |
||
3711 | stroke_color=get_color(infile,0); |
||
3712 | i=0; |
||
3713 | c=0; |
||
3714 | while( ! done ){ /* get next item until EOL*/ |
||
3715 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3716 | for( c = 0 ; c < 2; c++){ |
||
3717 | if(c == 0 ){ |
||
3718 | double_data[i] = get_real(infile,0); |
||
3719 | i++; |
||
3720 | } |
||
3721 | else { |
||
3722 | double_data[i] = get_real(infile,1); |
||
3723 | } |
||
3724 | } |
||
3725 | } |
||
3726 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3727 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3728 | decimals = find_number_of_digits(precision); |
||
3729 | /* *double_xy2js_array(double xy[],int len,int decimals) */ |
||
18557 | bpr | 3730 | tmp_buffer=my_newmem(MAX_BUFFER); |
3731 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_setpixel(%s,\"%s\",%.2f,%d);\n",double_xy2js_array(double_data,i,decimals),stroke_color,stroke_opacity,pixelsize)); |
||
18552 | bpr | 3732 | add_to_buffer(tmp_buffer); |
3733 | reset(); |
||
3734 | break; |
||
3735 | case PIXELSIZE: |
||
3736 | /* |
||
3737 | @ pixelsize int |
||
3738 | @ in case you want to deviate from default pixelsize = 1(...) |
||
3739 | @ pixelsize 100 is of course a filled rectangle 100px × 100px |
||
3740 | */ |
||
3741 | pixelsize = (int) get_real(infile,1); |
||
3742 | break; |
||
15111 | schaersvoo | 3743 | |
18552 | bpr | 3744 | case PIECHART: |
3745 | /* |
||
3746 | @ piechart xc,yc,radius,'data+colorlist' |
||
3747 | @ (xc: yc) center of circle diagram in xrange/yrange |
||
3748 | @ radius in pixels |
||
18627 | bpr | 3749 | @ data+color list: a colon separated list of raw data and corresponding colors<br>canvasdraw will not check validity of colornames...<br>in case of trouble look into javascript debugging of your browser |
18552 | bpr | 3750 | @ example data+colorlist: 32:red:65:green:23:black:43:orange:43:yellow:14:white |
3751 | @ the number of colors must match the number of data. |
||
3752 | @ if defined <a href='#fillpattern'>fillpattern some_pattern</a> then the pie pieces will be filled with the respective color and a fill pattern...<br>the pattern is cycled from the 4 pattern primitives: grid,hatch,diamond,dot,grid,hatch,diamond,dot,... |
||
18627 | bpr | 3753 | @ use command <a href='#opacity'>opacity</a> to adjust fill_opacity of colors |
3754 | @ use command <a href='#legend'>legend</a> to automatically create a legend using the same colors as pie segments; unicode allowed in legend; expect javascript trouble if the amount of ''pie-slices``, ''pie-colors``, ''pie-legend-titles`` do not match, a javascript console is your best friend...<br>use command ''fontfamily`` to set the font of the legend. |
||
18552 | bpr | 3755 | @ use command <a href='centered'>centered</a> to place <a href='#legend'>legend</a> text inside the piechart. The text is using the same color as the pie segment: use (fill) opacity to enhance visibility. |
3756 | @%piechart_1%size 300,200%xrange -10,10%yrange -10,10%legend cars:motorcycles:bicycles:trikes%opacity 255,120%piechart -5,0,75,22:red:8:blue:63:green:7:purple% |
||
3757 | @%piechart_2%size 200,200%xrange -10,10%yrange -10,10%fontfamily 16px Arial%centered%legend cars:motorcycles:bicycles:trikes%opacity 255,60%piechart 0,0,100,22:red:8:blue:63:green:7:purple |
||
3758 | */ |
||
3759 | js_function[DRAW_PIECHART] = 1; |
||
3760 | for(i=0;i<5;i++){ |
||
3761 | switch(i){ |
||
3762 | case 0: int_data[0] = x2px(get_real(infile,0)); break; /* x */ |
||
3763 | case 1: int_data[1] = y2px(get_real(infile,0)); break; /* y */ |
||
3764 | case 2: int_data[2] = (int)(get_real(infile,1));break;/* radius*/ |
||
3765 | case 3: temp = get_string(infile,1); |
||
3766 | if( strstr( temp, ":" ) != 0 ){ temp = str_replace(temp,":","\",\"");} |
||
18557 | bpr | 3767 | tmp_buffer=my_newmem(MAX_BUFFER); |
3768 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_piechart(%d,%d,%d,%d,[\"%s\"],%.2f,%d,\"%s\",%d,%d);\n",PIECHART,int_data[0],int_data[1],int_data[2],temp,fill_opacity,legend_cnt,font_family,use_filled,use_offset)); |
||
18552 | bpr | 3769 | add_to_buffer(tmp_buffer); |
3770 | break; |
||
3771 | default:break; |
||
3772 | } |
||
3773 | } |
||
3774 | reset(); |
||
3775 | break; |
||
3776 | case RANGE: |
||
3777 | /* |
||
3778 | @ range xmin,xmax,ymin,ymax |
||
3779 | @ if not given: 0,xsize,0,ysize (eg in pixels) |
||
3780 | */ |
||
3781 | for(i = 0 ; i<4; i++){ |
||
3782 | switch(i){ |
||
3783 | case 0: xmin = get_real(infile,0);break; |
||
3784 | case 1: xmax = get_real(infile,1);break; |
||
3785 | case 2: ymin = get_real(infile,0);break; |
||
3786 | case 3: ymax = get_real(infile,1);break; |
||
3787 | default: break; |
||
3788 | } |
||
3789 | } |
||
3790 | if(xmin >= xmax){canvas_error(" xrange is not OK: xmin < xmax !");} |
||
3791 | if(ymin >= ymax){canvas_error(" yrange is not OK: ymin < ymax !");} |
||
3792 | fprintf(js_include_file,"var xmin = %f;var xmax = %f;var ymin = %f;var ymax = %f;",xmin,xmax,ymin,ymax); |
||
3793 | found_size_command = found_size_command+2; |
||
3794 | break; |
||
3795 | case RAYS: |
||
3796 | /* |
||
18556 | bpr | 3797 | @ rays color,xc,yc,x1,y1,x2,y2,x3,y3...x_n,y_n |
3798 | @ draw rays in color 'color' and center (xc:yc) |
||
3799 | @ may be set draggable or onclick (every individual ray) |
||
3800 | @%rays_onclick%size 400,400%xrange -10,10%yrange -10,10%onclick%rays blue,0,0,3,9,-3,5,-4,0,4,-9,7,9,-8,1,-1,-9 |
||
3801 | @%rays_drag_xy%size 400,400%xrange -10,10%yrange -10,10%drag xy%rays blue,0,0,3,9,-3,5,-4,0,4,-9,7,9,-8,1,-1,-9 |
||
18552 | bpr | 3802 | */ |
3803 | stroke_color=get_color(infile,0); |
||
3804 | fill_color = stroke_color; |
||
3805 | double_data[0] = get_real(infile,0);/* xc */ |
||
3806 | double_data[1] = get_real(infile,0);/* yc */ |
||
3807 | i=2; |
||
3808 | while( ! done ){ /* get next item until EOL*/ |
||
3809 | if(i > MAX_INT - 1){canvas_error("in command rays too many points / rays in argument: repeat command multiple times to fit");} |
||
3810 | if(i%2 == 0 ){ |
||
3811 | double_data[i] = get_real(infile,0); /* x */ |
||
3812 | } |
||
3813 | else { |
||
3814 | double_data[i] = get_real(infile,1); /* y */ |
||
3815 | } |
||
3816 | fprintf(js_include_file,"/* double_data[%d] = %f */\n",i,double_data[i]); |
||
3817 | i++; |
||
3818 | } |
||
3819 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3820 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3821 | if( i%2 != 0 ){canvas_error("in command rays: unpaired x or y value");} |
||
3822 | decimals = find_number_of_digits(precision); |
||
3823 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3824 | for(c=2; c<i;c = c+2){ |
||
18557 | bpr | 3825 | tmp_buffer=my_newmem(MAX_BUFFER); |
3826 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[c],decimals,double_data[1],decimals,double_data[c+1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3827 | add_to_buffer(tmp_buffer); |
3828 | /* object_cnt++; */ |
||
3829 | if(onclick != 0){object_cnt++;} |
||
3830 | } |
||
3831 | reset(); |
||
3832 | dragstuff[4] = 1; |
||
3833 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3834 | break; |
||
3835 | case RECT: |
||
3836 | /* |
||
3837 | @ rect x1,y1,x2,y2,color |
||
3838 | @ use command <code>frect x1,y1,x2,y2,color</code> for a filled rectangle |
||
3839 | @ use command/keyword <a href='#filled'>filled</a> before command <code>rect x1,y1,x2,y2,color</code> |
||
3840 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
18572 | bpr | 3841 | @ note: internally a rect is defined with 4 points. So when performing some affine transformation, other than translation, it will result in some morphing of the rectangle !<br>this is a deviation of flydraw's rect&affine |
18552 | bpr | 3842 | @%rect%size 400,400%xrange -10,10%yrange -10,10%rect 0,0,4,-4,green%rect 0,5,4,1,red |
3843 | */ |
||
3844 | for(i=0;i<5;i++){ |
||
3845 | switch(i){ |
||
3846 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
3847 | case 1:double_data[1] = get_real(infile,0);break; /* y-values */ |
||
3848 | case 2:double_data[4] = get_real(infile,0);break; /* x-values */ |
||
3849 | case 3:double_data[5] = get_real(infile,0);break; /* y-values */ |
||
3850 | case 4:stroke_color = get_color(infile,1);/* name or hex color */ |
||
3851 | decimals = find_number_of_digits(precision); |
||
3852 | double_data[2] = double_data[4]; |
||
3853 | double_data[3] = double_data[1]; |
||
3854 | double_data[6] = double_data[0]; |
||
3855 | double_data[7] = double_data[5]; |
||
3856 | /* using closed PATH (type=5) instead of ctx.rect (type=1)!!! |
||
3857 | 0,1 2,3 |
||
3858 | 6,7 4,5 |
||
3859 | x = [0,2,4,6] |
||
3860 | y = [1,3,5,7] |
||
3861 | */ |
||
18623 | bpr | 3862 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 3863 | if(use_rotate == TRUE ){rotate(8,angle,rotationcenter,2);} |
3864 | if(use_affine == TRUE ){ transform(8,2);} |
||
3865 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 3866 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 3867 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,5,[%.*f,%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f,%.*f],[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[4],decimals,double_data[6],decimals,double_data[1],decimals,double_data[3],decimals,double_data[5],decimals,double_data[7],line_width,line_width,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 3868 | add_to_buffer(tmp_buffer); |
3869 | if(onclick != 0){object_cnt++;} |
||
18555 | bpr | 3870 | /* object_cnt++; */ |
18552 | bpr | 3871 | reset(); |
3872 | break; |
||
3873 | } |
||
3874 | } |
||
3875 | dragstuff[5] = 1; |
||
3876 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3877 | break; |
||
3878 | case RECTS: |
||
3879 | /* |
||
3880 | @ rects color,x1,y1,x2,y2,..... |
||
3881 | @ use command <code>frect color,x1,y1,x2,y2,.....</code> for a filled rectangle |
||
3882 | @ use command/keyword <a href='#filled'>filled</a> before command <code>rects color,x1,y1,x2,y2,....</code> |
||
18623 | bpr | 3883 | @ use command <code>fillcolor color</code> before ''frects`` to set the fill color. |
18552 | bpr | 3884 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
3885 | @%rects%size 400,400%xrange -10,10%yrange -10,10%rects red,0,0,4,-4,0,5,4,1 |
||
3886 | */ |
||
3887 | /* using closed PATH (type=5) in stead of ctx.rect (type=1)!!! |
||
3888 | 0,1 2,3 .....8,9 10,11..... |
||
3889 | 6,7 4,5 .....14,15 12,13..... |
||
3890 | x = [0,2,4,6,8,10,12,14...] |
||
3891 | y = [1,3,5,7,9,11,13,15...] |
||
3892 | */ |
||
3893 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
18623 | bpr | 3894 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 3895 | i=0; |
3896 | while( ! done ){ /* get next item until EOL*/ |
||
3897 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3898 | if(i%2 == 0 ){ |
||
3899 | double_data[i] = get_real(infile,0); /* x */ |
||
3900 | } |
||
3901 | else { |
||
3902 | double_data[i] = get_real(infile,1); /* y */ |
||
3903 | } |
||
3904 | i++; |
||
3905 | } |
||
3906 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3907 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3908 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
11806 | schaersvoo | 3909 | |
18552 | bpr | 3910 | decimals = find_number_of_digits(precision); |
3911 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18557 | bpr | 3912 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 3913 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,5,[%.*f,%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f,%.*f],[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+2],decimals,double_data[c],decimals,double_data[c+1],decimals,double_data[c+1],decimals,double_data[c+3],decimals,double_data[c+3],line_width,line_width,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 3914 | add_to_buffer(tmp_buffer); |
3915 | if(onclick != 0){object_cnt++;} |
||
3916 | /* object_cnt++; */ |
||
3917 | } |
||
3918 | dragstuff[5] = 1; |
||
3919 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3920 | if(use_rotate == TRUE ){ |
||
3921 | rotate(i-1,angle,rotationcenter,2); |
||
3922 | } |
||
3923 | reset(); |
||
3924 | break; |
||
3925 | case REPLYFORMAT: |
||
3926 | /* |
||
3927 | @ replyformat number |
||
3928 | @ use number=-1 to deactivate the js-functions read_canvas() and read_dragdrop() |
||
3929 | @ default values should be fine ! |
||
3930 | @ use command <code>precision [0,1,10,100,1000,10000...]</code> before command ''replyformat`` to set the desired number of decimals in the student reply / drawing |
||
3931 | @ the last value for ''precision int`` will be used to calculate the reply coordinates, if needed (read_canvas();) |
||
3932 | @ choose<ul><li>replyformat 1: <code>x1,x2,x3,x4....x_n<br>y1,y2,y3,y4....y_n</code> x/y in pixels</li><li>replyformat 2: <code> x1,x2,x3,x4....x_n<br> y1,y2,y3,y4....y_n</code> x/y in xrange / yrange coordinate system</li><li>replyformat 3: <code> x1,x2,x3,x4....x_n<br> y1,y2,y3,y4....y_n<br> r1,r2,r3,r4....r_n</code> x/y in pixels, r in pixels</li><li>replyformat 4: <code> x1,x2,x3,x4....x_n<br> y1,y2,y3,y4....y_n<br> r1,r2,r3,r4....r_n</code> x/y in xrange / yrange coordinate system, r in pixels</li><li>replyformat 5: <code> Ax1,Ax2,Ax3,Ax4....Ax_n<br> Ay1,Ay2,Ay3,Ay4....Ay_n<br> Bx1,Bx2,Bx3,Bx4....Bx_n<br> By1,By2,By3,By4....By_n<br> Cx1,Cx2,Cx3,Cx4....Cx_n<br> Cy1,Cy2,Cy3,Cy4....Cy_n<br> ....<br> Zx1,Zx2,Zx3,Zx4....Zx_n<br> Zy1,Zy2,Zy3,Zy4....Zy_n</code> x/y in pixels</li><li>replyformat 6: <code> Ax1,Ax2,Ax3,Ax4....Ax_n<br> Ay1,Ay2,Ay3,Ay4....Ay_n<br> Bx1,Bx2,Bx3,Bx4....Bx_n<br> By1,By2,By3,By4....By_n<br> Cx1,Cx2,Cx3,Cx4....Cx_n<br> Cy1,Cy2,Cy3,Cy4....Cy_n<br> ....<br> Zx1,Zx2,Zx3,Zx4....Zx_n<br> Zy1,Zy2,Zy3,Zy4....Zy_n</code> x/y in xrange / yrange coordinate system</li><li>replyformat 7: <code> x1:y1,x2:y2,x3:y3,x4:y4...x_n:y_n</code> x/y in pixels</li><li>replyformat 8: <code> x1:y1,x2:y2,x3:y3,x4:y4...x_n:y_n</code> x/y in xrange / yrange coordinate system</li><li>replyformat 9: <code> x1:y1:r1,x2:y2:r2,x3:y3:r3,x4:y4:r3...x_n:y_n:r_n</code> x/y in pixels</li><li>replyformat 10: <code> x1:y1:r1,x2:y2:r2,x3:y3:r3,x4:y4:r3...x_n:y_n:r_n</code> x/y in xrange / yrange coordinate system</li><li>replyformat 11: <code> Ax1,Ay1,Ax2,Ay2<br>Bx1,By1,Bx2,By2<br> Cx1,Cy1,Cx2,Cy2<br> Dx1,Dy1,Dx2,Dy2<br> ......<br> Zx1,Zy1,Zx2,Zy2</code> x/y in xrange / yrange coordinate system</li><li>replyformat 12: <code> Ax1,Ay1,Ax2,Ay2<br> Bx1,By1,Bx2,By2<br>Cx1,Cy1,Cx2,Cy2<br> Dx1,Dy1,Dx2,Dy2<br> ......<br> Zx1,Zy1,Zx2,Zy2</code> x/y in pixels</li><li>replyformat 13: <code> Ax1:Ay1:Ax2:Ay2,Bx1:By1:Bx2:By2,Cx1:Cy1:Cx2:Cy2,Dx1:Dy1:Dx2:Dy2, ... ,Zx1:Zy1:Zx2:Zy2</code> x/y in xrange / yrange coordinate system</li><li>replyformat 14: <code> Ax1:Ay1:Ax2:Ay2,Bx1:By1:Bx2:By2....Zx1:Zy1:Zx2:Zy2</code> x/y in pixels</li><li>replyformat 15: reply from inputfields,textareas <code>reply1,reply2,reply3,...,reply_n</code></li><li>replyformat 16: mathml input fields</li><li>replyformat 17: read ''userdraw text,color`` only <code>x1,y1,text1 \\n x2,y2,text2...\\n...x_n,y_n,text_n </code> x/y-values are in xrange/yrange</li><li>replyformat 18: read_canvas() will read all interactive clocks in <code>H1:M1:S1,H2:M2:S2...Hn:Mn:Sn</code></li><li>replyformat 19: read_canvas() will return the object number of marked / clicked object (clock), analogue to (shape library) onclick command</li><li>replyformat 20: read_canvas() will reply "object_number:x:y" of external images: object_number of the first draggable external image in the fly-script starts with 0, e.g. expect something like 0:-5:4,1:6:2,2:-2:-5, the first image position is (-5:4), the second image position is (6:2) and the third image position is (-2:-5) <li>replyformat 21: <code> (x1:y1) (x2:y2) ... (x_n:y_n)</code> verbatim coordinate return</li><li>replyformat 22: returns an array .... <code>reply[0]=x1 reply[1]=y1 reply[2]=x2 reply[3]=y2 ... reply[n-1]=x_n reply[n]=y_n</code> x/y in xrange / yrange coordinate system</li><li>replyformat 23: can only be used for drawtype ''polyline``. A typical click sequence in drawtype polyline is x1,y1,x2,y2,x2,y2,x3,y3,x3,y3.....,x(n-1),y(n-1),x(n-1),y(n-1),xn,yn --replyformat 23 gives <code>x1,y1,x2,y2,x3,y3,.....x(n-1),y(n-1),xn,yn</code>; multiple occurences will be filtered out. The reply will be in x-y-range (xreply \\n yreply)</li><li>replyformat 24: read all inputfield values: even those set ''readonly``</li><li>replyformat 25: <code> angle1,angle2;...;angle_n</code> will return the radius (one or many) of the user drawn circle segment in degrees</li><li>replyformat 26: <code> rad1,rad2,...rad_n</code> will return the radius (one or many) of the user drawn circle segment in radians</li><li>replyformat 27: return (only) userdraw inputfields <code>x1,y1,text1<br> x2,y2,text2...<br>...x_n,y_n,textn</code></li><li>replyformat 28: <code> x1,y1,r1,x2,y2,r2...x_n,y_n,r_n</code> x / y / r in xrange / yrange coordinate system: may be used to reinput into command <code>circles color,x1,y1,r1,x2,y2,r2...x_n,y_n,r_n</code> will not return anything else (e.g. no inputfields, text etc)</li><li>replyformat 34: a special for OEF and dragging external images -included via commands <a href='#copy'>copy</a> or <a href='#copyresized'>copyresized</a> there will be an extra function <code>read_canvas_images()</code> for reading the coordinates of the images.<br>for now this is a unique function, e.g. there is no ''canvas id`` linked to it. (TO DO !!! 18/5/2019)</li></ul> |
||
3933 | @ special replyformat = 100 ; will access to the raw javascript object data...use: read_dragdrop([property,property,...])<br>for example properies like 'clicked','text', 'angle' , 'x' |
||
3934 | */ |
||
3935 | reply_format = (int) get_real(infile,1); |
||
3936 | reply_precision = precision; |
||
3937 | break; |
||
3938 | case ROUNDRECT: |
||
3939 | /* |
||
3940 | @ roundrect x1,y1,x2,y2,radius in px,color |
||
3941 | @ use command <code>froundrect x1,y1,x2,y2,radius,color</code> for a filled rectangle |
||
3942 | @ use command/keyword <a href='#filled'>filled</a> before command <code>roundrect x1,y1,x2,y2,radius,color</code> |
||
3943 | @ fillcolor will be identical to ''color`` |
||
3944 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
3945 | @%roundrect%size 400,400%xrange -10,10%yrange -10,10%roundrect 0,0,4,-4,20,green%roundrect 0,5,4,1,10,red |
||
3946 | */ |
||
3947 | for(i=0;i<6;i++){ |
||
3948 | switch(i){ |
||
3949 | case 0:double_data[0] = get_real(infile,0);break; /* x-values */ |
||
3950 | case 1:double_data[1] = get_real(infile,0);break; /* y-values */ |
||
3951 | case 2:double_data[2] = get_real(infile,0);break; /* x-values */ |
||
3952 | case 3:double_data[3] = get_real(infile,0);break; /* y-values */ |
||
3953 | case 4:int_data[0] = (int) (get_real(infile,0));break; /* radius value in pixels */ |
||
3954 | case 5:stroke_color = get_color(infile,1);/* name or hex color */ |
||
3955 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
3956 | if(use_affine == TRUE ){ transform(2,4);} |
||
3957 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3958 | /* ensure no inverted roundrect is produced... */ |
||
3959 | if( double_data[0] > double_data[2] ){double_data[4] = double_data[0];double_data[0] = double_data[2];double_data[2] = double_data[4];} |
||
3960 | if( double_data[3] > double_data[1] ){double_data[4] = double_data[1];double_data[1] = double_data[3];double_data[3] = double_data[4];} |
||
3961 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 3962 | tmp_buffer=my_newmem(MAX_BUFFER); |
3963 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,6,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],int_data[0],int_data[0],int_data[0],int_data[0],line_width,stroke_color,stroke_opacity,stroke_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 3964 | add_to_buffer(tmp_buffer); |
3965 | if(onclick != 0){object_cnt++;} |
||
3966 | /* object_cnt++;*/ |
||
3967 | reset(); |
||
3968 | break; |
||
3969 | } |
||
3970 | } |
||
3971 | dragstuff[6] = 1; |
||
3972 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
3973 | break; |
||
3974 | case ROUNDRECTS: |
||
3975 | /* |
||
3976 | @ roundrects color,radius in px,x1,y1,x2,y2,x3,y3,x4,y4,.... |
||
3977 | @ for filled roundrects use command/keyword <a href='#filled'>filled</a> before command |
||
3978 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
||
3979 | @%roundrects%size 400,400%xrange -10,10%yrange -10,10%roundrects blue,5,0,0,4,-4,5,4,1,2 |
||
3980 | */ |
||
11806 | schaersvoo | 3981 | |
18552 | bpr | 3982 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
3983 | int_data[0] = (int) (get_real(infile,0)); /* radius value in pixels */ |
||
18623 | bpr | 3984 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 3985 | i=0; |
3986 | while( ! done ){ /* get next item until EOL*/ |
||
3987 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
3988 | if(i%2 == 0 ){ |
||
3989 | double_data[i] = get_real(infile,0); /* x */ |
||
3990 | } |
||
3991 | else { |
||
3992 | double_data[i] = get_real(infile,1); /* y */ |
||
3993 | } |
||
3994 | i++; |
||
3995 | } |
||
3996 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
3997 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
3998 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
3999 | decimals = find_number_of_digits(precision); |
||
4000 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
4001 | /* ensure no inverted roundrect is produced... */ |
||
4002 | if( double_data[c] > double_data[c+2] ){double_data[c+4] = double_data[c];double_data[c] = double_data[c+2];double_data[c+2] = double_data[c+4];} |
||
4003 | if( double_data[c+3] > double_data[c+1] ){double_data[c+4] = double_data[c+1];double_data[c+1] = double_data[c+3];double_data[c+3] = double_data[c+4];} |
||
18557 | bpr | 4004 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 4005 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,6,[%.*f,%.*f],[%.*f,%.*f],[%d,%d],[%d,%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],int_data[0],int_data[0],int_data[0],int_data[0],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 4006 | add_to_buffer(tmp_buffer); |
4007 | if(onclick != 0){object_cnt++;} |
||
4008 | /* object_cnt++; */ |
||
4009 | } |
||
4010 | dragstuff[6] = 1; |
||
4011 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4012 | reset(); |
||
4013 | break; |
||
4014 | case RULER: |
||
4015 | /* |
||
4016 | @ ruler x,y,x-width,y-height,mode |
||
4017 | @ x,y are the initial location |
||
4018 | @ x-width, y-height are the ruler dimensions width & height in xy-coordinate system |
||
4019 | @ the ruler scale is by definition the x-scale, set by command ''xrange``. For example: a ruler x-width of 6 will have a scale ranging from 0 to 6 |
||
4020 | @ mode: use -1 to set the ruler interactive (eg mouse movement of ruler; drag & rotate)<br>use mode = '0° - 360°' to set the ruler with a static angle of some value |
||
4021 | @ if combined with a protractor, use replyformat = 32 |
||
4022 | @ only one ruler allowed (for the time being) |
||
4023 | @ when using command ''zoom``, pay <b>attention</b> to the size and symmetry of your canvas to avoid a partial image, locate the start position near the center of the visual canvas; technical: the actual ''ruler`` is just a static generated image in a new canvas-memory. This image is only generated once, and a copy of its bitmap is translated & rotated onto the visible canvas. That is the reason for the ''high-speed dragging and rotating``. I have limited its size to xsize × ysize e.g. the same size as the visual canvas... |
||
4024 | @ usage: first left click on the ruler will activate dragging; a second left click will activate rotating (just move mouse around), a third click will freeze this position and the x/y-coordinate and angle in radians will be stored in reply(3), a next click will restart this sequence... |
||
4025 | @%ruler_interactive%size 800,400%xrange -10,10%yrange -10,10%strokecolor blue%opacity 200,50%filled%fillcolor lightgrey%ruler -9,0,10,2,-1%display degree,blue,22 |
||
4026 | @%ruler_set_degree_45%size 800,400%xrange -10,10%yrange -10,10%strokecolor blue%opacity 200,50%filled%fillcolor lightgrey%ruler 0,0,10,2,45 |
||
4027 | @%ruler_set_degree_125%size 800,400%xrange -10,10%yrange -10,10%strokecolor blue%opacity 200,50%filled%fillcolor lightgrey%ruler 0,0,10,2,125 |
||
4028 | */ |
||
4029 | for( i = 0;i < 5; i++ ){ |
||
4030 | switch(i){ |
||
4031 | case 0: double_data[0] = get_real(infile,0);break; /* x-center */ |
||
4032 | case 1: double_data[1] = get_real(infile,0);break; /* y-center */ |
||
4033 | case 2: double_data[2] = get_real(infile,0);break; /* x-width */ |
||
4034 | case 3: double_data[3] = get_real(infile,0);break; /* y-width */ |
||
4035 | case 4: int_data[0] = (int)(get_real(infile,1)); /* passive mode */ |
||
4036 | decimals = find_number_of_digits(precision); |
||
4037 | if( int_data[0] < 0 ){ |
||
4038 | js_function[JS_FIND_ANGLE] = 1; |
||
4039 | } |
||
18557 | bpr | 4040 | add_js_ruler(double_data[0],double_data[1],double_data[2],double_data[3], font_family,stroke_color,stroke_opacity,fill_color,fill_opacity,line_width,int_data[0],use_snap); |
4041 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
4042 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, ";ruler%d(); ",canvas_root_id)); |
||
18552 | bpr | 4043 | add_to_buffer(tmp_buffer); |
4044 | reply_precision = precision; |
||
4045 | /* no reply from ruler if non-interactive */ |
||
4046 | if( reply_format == 0 && int_data[0] == -1 ){reply_format = 31;} |
||
4047 | break; |
||
4048 | default: break; |
||
4049 | } |
||
4050 | } |
||
4051 | break; |
||
4052 | case RESET: |
||
4053 | /* |
||
4054 | @ reset |
||
4055 | @ keyword |
||
4056 | @ disables the effects of the <a href="noreset">noreset</a> command |
||
4057 | @ so the next objects will not be <a href="#filled">filled</a> and <a href="#dashed">dashed</a> |
||
4058 | */ |
||
4059 | no_reset = FALSE; reset(); |
||
4060 | break; |
||
4061 | case RESETOFFSET: |
||
4062 | /* |
||
18556 | bpr | 4063 | @ resetoffset |
4064 | @ keyword ; use to restore text placement on the canvas to the real (x;y) coordinates of the left bottom corner of the text |
||
4065 | @ may be active for commands <a href="#text">text</a> and <a href="#string">string</a> (e.g. objects in the drag/drop/onclick-librariy |
||
18552 | bpr | 4066 | */ |
4067 | use_offset = 0; |
||
4068 | break; |
||
4069 | case ROTATE: |
||
4070 | /* |
||
18556 | bpr | 4071 | @ rotate rotation_angle |
4072 | @ angle in degrees |
||
4073 | @ (only) the next object will be rotated is given angle |
||
4074 | @ positive values rotate counter clockwise |
||
4075 | @ attention: all objects will be rotated around their first point...<br><code>rotate 45<br>triangle 1,1,5,1,3,4,red</code><br>will rotate 45 degrees around point (1:1) |
||
4076 | @ if another rotation center is needed, use command <a href="#rotationcenter">rotationcenter xc,yc</a>.<br>to reset this rotationcenter, use keyword <a href="#killrotate">killrotate</a> |
||
4077 | @ attention: rotate will mess up the interactivity of the rotated object <br>e.g. if combined with command <a href="#drag">drag xy</a> or keyword <a href="#onclick">onclick</a>: the mouse recognises the original -unrotated- coordinates of the object |
||
4078 | @%rotate_1%size 400,400%xrange -10,10%yrange -10,10%fpoly yellow,0,0,4,3,2,5%rotate 45%fpoly violet,0,0,4,3,2,5%killrotate%rotate 90%fpoly violet,0,0,4,3,2,5% |
||
18552 | bpr | 4079 | */ |
4080 | use_rotate = TRUE; |
||
4081 | angle = -1*(get_real(infile,1));/* -1: to be compatible with Flydraw... */ |
||
4082 | break; |
||
4083 | case ROTATION_CENTER: |
||
4084 | /* |
||
4085 | @ rotationcenter x_center,y_center |
||
4086 | @ define an rotation center in your x/y-coordinate system |
||
4087 | @ wims will not check the validity of your input; use javascript console to debug any erors |
||
4088 | @ if not defined a rotation will be around the first point of an object |
||
4089 | @ to be used before command <a href="#rotate">rotate</a> |
||
18572 | bpr | 4090 | @ use <a href="#killrotate">killrotate</a> to reset to 'null' <br>(eg. the rotationcenter of the next object(s) will be the first (x;y) coordinate of the object(s)) |
18552 | bpr | 4091 | @ all other commands will use this rotation center, unless a <a href="#killrotation">killrotation</a> is given |
4092 | @%rotationcenter%size 400,400%xrange -5,10%yrange -5,10%circles green,3,3,4.25%rotationcenter 3,3%opacity 255,80%fpoly yellow,0,0,4,3,2,5%rotate 45%fpoly violet,0,0,4,3,2,5%rotate 90%fpoly lightblue,0,0,4,3,2,5%rotate 135%fpoly blue,0,0,4,3,2,5%rotate 180%fpoly orange,0,0,4,3,2,5%rotate 225%fpoly green,0,0,4,3,2,5%rotate 270%fpoly cyan,0,0,4,3,2,5%rotate 315%fpoly purple,0,0,4,3,2,5%linewidth 3%point 3,3,red%mouse red,22 |
||
4093 | @%rotationcenter_slider%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%fillcolor black%strokecolor yellow%rotationcenter 0,0%fontsize 28%slider 0,2*pi,400,30,angle degrees active, rotate...%plot red,5*sin(x)%filled%linewidth 1%opacity 150,50%fillcolor orange%angle 0,0,pi,0,0,blue |
||
4094 | */ |
||
4095 | for( i = 0;i < 2; i++ ){ |
||
4096 | switch(i){ |
||
4097 | case 0: rotationcenter[0] = get_real(infile,0);break; /* x-center */ |
||
4098 | case 1: rotationcenter[1] = get_real(infile,1);break; /* y-center */ |
||
4099 | } |
||
4100 | string_length = 1 + snprintf(NULL,0,"[%f,%f ]",rotationcenter[0],rotationcenter[1]); |
||
18557 | bpr | 4101 | |
18552 | bpr | 4102 | rotation_center = my_newmem(string_length); |
4103 | snprintf(rotation_center,string_length,"[%f,%f]",rotationcenter[0],rotationcenter[1]); |
||
4104 | } |
||
4105 | break; |
||
4106 | case SIZE: |
||
4107 | /* |
||
18556 | bpr | 4108 | @ size width,height |
4109 | @ set canvas size in pixels |
||
4110 | @ mandatory first command (can only be preceded by keyword <a href="#popup">popup</a>) |
||
4111 | @ if xrange and/or yrange is not given the range will be set to pixels:<br>xrange 0,xsize yrange 0,ysize<br>note: lower left corner is origin (0:0) !!! this in contrast to flydraw |
||
18552 | bpr | 4112 | */ |
4113 | found_size_command = 1; |
||
4114 | /* using fabs: however "xsize == int": so "xsize = abs( (int) get_real(infile,0))" would be the idea... */ |
||
4115 | xsize = (int)(fabs(round(get_real(infile,0)))); /* just to be sure that sizes > 0 */ |
||
4116 | ysize = (int)(fabs(round(get_real(infile,1)))); |
||
4117 | /* sometimes we want xrange / yrange to be in pixels...without telling x/y-range */ |
||
4118 | xmin = 0;xmax = xsize; |
||
4119 | ymin = 0;ymax = ysize; |
||
11806 | schaersvoo | 4120 | |
4121 | /* |
||
4122 | The sequence in which stuff is finally printed is important !! |
||
4123 | */ |
||
18552 | bpr | 4124 | fprintf(stdout,"\n\ |
4125 | <script>\n\ |
||
4126 | /*<![CDATA[*/\n\ |
||
4127 | if( typeof(wims_status) === 'undefined' ){ var wims_status = \"$status\";};\ |
||
4128 | if( typeof(use_dragdrop_reply) === 'undefined' ){ var use_dragdrop_reply = false;};\ |
||
4129 | if( typeof(canvas_scripts) === 'undefined' ){ var canvas_scripts = new Array();};\ |
||
4130 | canvas_scripts.push(\"%d\");\n/*]]>*/\n</script>\n\ |
||
4131 | ",canvas_root_id); |
||
11806 | schaersvoo | 4132 | |
18552 | bpr | 4133 | /* style=\"display:block;position:relative;margin-left:auto;margin-right:auto;margin-bottom:4px;\" */ |
4134 | if( use_tooltip != 2){ |
||
4135 | fprintf(stdout,"<!-- canvasdraw div -->\n\ |
||
4136 | <div tabindex=\"0\" id=\"canvas_div%d\" style=\"max-width:%dpx;width:%dpx;height:%dpx\" class=\"canvas_wrapper\" oncontextmenu=\"return false;\">\ |
||
4137 | <canvas class=\"canvas_placeholder\" width=\"%d\" height=\"%d\"></canvas>\ |
||
4138 | </div>\n\ |
||
4139 | <!-- tooltip and input placeholder -->\n\ |
||
4140 | <div id=\"tooltip_placeholder_div%d\" style=\"text-align:center\">\ |
||
4141 | <span id=\"tooltip_placeholder%d\" class=\"tooltip_placeholder\"></span></div>\ |
||
4142 | <!-- include actual object code via include file -->\n\ |
||
4143 | <script id=\"canvas_script%d\" src=\"%s\" defer></script>\n",canvas_root_id,xsize,xsize,ysize,xsize,ysize,canvas_root_id,canvas_root_id,canvas_root_id,getfile_cmd); |
||
4144 | } else { |
||
11806 | schaersvoo | 4145 | /* |
14066 | bpr | 4146 | set canvas_div invisible and do not include placeholder in main html page: |
15111 | schaersvoo | 4147 | the js-include will also be in a popup window...to be shown when wims $status = done |
11806 | schaersvoo | 4148 | */ |
18552 | bpr | 4149 | fprintf(stdout,"<!-- canvasdraw div invisible -->\n\ |
4150 | <div tabindex=\"0\" id=\"canvas_div%d\" class=\"canvas_wrapper\" style=\"display:none;max-width:%dpx;width:%dpx;height:%dpx;\">\ |
||
4151 | <canvas class=\"canvas_placeholder\" width=\"%d\" height=\"%d\"></canvas>\ |
||
4152 | </div>\n\ |
||
4153 | <div id=\"tooltip_placeholder_div%d\" style=\"display:none;position:relative;margin-left:auto;margin-right:auto;margin-bottom:4px;\">\ |
||
4154 | <span id=\"tooltip_placeholder%d\" class=\"tooltip_placeholder\"></span></div>\ |
||
4155 | <!-- include actual object code via include file -->\n\ |
||
4156 | <script id=\"canvas_script%d\" src=\"%s\"></script>\n",canvas_root_id,xsize,xsize,ysize,xsize,ysize,canvas_root_id,canvas_root_id,canvas_root_id,getfile_cmd); |
||
4157 | } |
||
11806 | schaersvoo | 4158 | |
14071 | bpr | 4159 | /* these must be global...it is all really very poor javascript:( */ |
15734 | schaersvoo | 4160 | fprintf(js_include_file,"\n/* begin generated javascript include for canvasdraw version %s */\n\ |
11806 | schaersvoo | 4161 | \"use strict\";\n\ |
15111 | schaersvoo | 4162 | /* these variables and functions must be global */\ |
11806 | schaersvoo | 4163 | var read_dragdrop%d;\ |
14038 | schaersvoo | 4164 | var read_canvas_images;\ |
11806 | schaersvoo | 4165 | var read_canvas%d;\ |
4166 | var set_clock;\ |
||
4167 | var clear_draw_area%d;\ |
||
4168 | var update_draw_area%d;\ |
||
14038 | schaersvoo | 4169 | var place_image_on_canvas;\ |
11806 | schaersvoo | 4170 | var draw_boxplot;\ |
4171 | var redraw_all%d;\ |
||
15111 | schaersvoo | 4172 | var userdraw_primitive;\ |
4173 | var wims_canvas_function%d = function(){\n/* common used stuff */\ |
||
4174 | var userdraw_x = [];var userdraw_y = [];var userdraw_radius = [];\ |
||
11806 | schaersvoo | 4175 | var xsize = %d;\ |
4176 | var ysize = %d;\ |
||
4177 | var precision = 100;\ |
||
4178 | var canvas_div = document.getElementById(\"canvas_div%d\");\ |
||
4179 | var create_canvas%d = function(canvas_type,size_x,size_y){var cnv;if(document.getElementById(\"wims_canvas%d\"+canvas_type)){ cnv = document.getElementById(\"wims_canvas%d\"+canvas_type);}else{try{ cnv = document.createElement(\"canvas\"); }catch(e){alert(\"Your browser does not support HTML5 CANVAS:GET FIREFOX !\");return;};canvas_div.appendChild(cnv);};cnv.width = size_x;cnv.height = size_y;cnv.style.top = 0;cnv.style.left = 0;cnv.style.position = \"absolute\";cnv.id = \"wims_canvas%d\"+canvas_type;return cnv;};\ |
||
4180 | function findPosX(i){ var obj = i;var curleft = 0;if(obj.offsetParent){while(1){curleft += obj.offsetLeft;if(!obj.offsetParent){break;};obj = obj.offsetParent;};}else{if(obj.x){curleft += obj.x;};};return curleft;};function findPosY(i){var obj = i;var curtop = 0;if(obj.offsetParent){while(1){curtop += obj.offsetTop;if(!obj.offsetParent){break;};obj = obj.offsetParent;};}else{if(obj.y){curtop += obj.y;};};return curtop;};\ |
||
18638 | bpr | 4181 | function x2px(x){if(use_xlogscale == 0 ){let res=parseFloat((x-xmin)/(xmax - xmin)*xsize);return (res==xsize)?xsize-1:res;}else{let x_max = Math.log(xmax)/Math.log(xlogbase);let x_min = Math.log(xmin)/Math.log(xlogbase);let x_in = Math.log(x)/Math.log(xlogbase);let res=(x_in-x_min)/(x_max - x_min)*xsize; return (res==xsize)?xsize-1:res;};};\ |
18606 | bpr | 4182 | function px2x(px){if(use_xlogscale == 0 ){return px*(xmax - xmin)/xsize + xmin;}else{let x_max = Math.log(xmax)/Math.log(xlogbase);let x_min = Math.log(xmin)/Math.log(xlogbase);let x_out = x_min +px*(x_max - x_min)/xsize;return Math.pow(xlogbase,x_out);};};\ |
4183 | function px2y(py){if(use_ylogscale == 0 ){return ymax - py*(ymax - ymin)/ysize;}else{let y_max = Math.log(ymax)/Math.log(ylogbase);let y_min = Math.log(ymin)/Math.log(ylogbase);let y_out = y_max +py*(y_min - y_max)/ysize;return Math.pow(ylogbase,y_out);};};\ |
||
18638 | bpr | 4184 | function y2px(y){if(use_ylogscale == 0){let res= parseFloat((ymax-y)/(ymax - ymin)*ysize);return (res==ysize)?ysize-1:res;}else{var y_max = Math.log(ymax)/Math.log(ylogbase);var y_min = Math.log(ymin)/Math.log(ylogbase);var y_in = Math.log(y)/Math.log(ylogbase);return (y_max - y_in)*ysize/(y_max - y_min);};};\ |
11806 | schaersvoo | 4185 | function scale_x_radius(rx){return rx*xsize/(xmax - xmin);};\ |
4186 | function scale_y_radius(ry){return ry*ysize/(ymax - ymin);};\ |
||
4187 | function distance(x1,y1,x2,y2){return Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );};\ |
||
4188 | function distance_to_line (r,q,x,y){var c = (y) - (-1/r)*(x);var xs = r*(c - q)/(r*r+1);var ys = (r)*(xs)+(q);return parseInt(Math.sqrt( (xs-x)*(xs-x) + (ys-y)*(ys-y) ));};\ |
||
4189 | function move(obj,dx,dy){for(var p = 0 ; p < obj.x.length; p++){obj.x[p] = obj.x[p] + dx;obj.y[p] = obj.y[p] + dy;};return obj;};\ |
||
15111 | schaersvoo | 4190 | var snap_x = 1;var snap_y = 1;\ |
11806 | schaersvoo | 4191 | function snap_to_x(x){return x2px(snap_x*(Math.round((px2x(x))/snap_x)));};\ |
11890 | schaersvoo | 4192 | function snap_to_y(y){return y2px(snap_y*(Math.round((px2y(y))/snap_y)));};\ |
15111 | schaersvoo | 4193 | function multisnap_check(x,y,snap){switch(snap){case 1:return [snap_to_x(x),snap_to_y(y)];break;case 2:return [snap_to_x(x),y];break;case 3:return [x,snap_to_y(y)];break;case 4:return snap_to_points(x,y);break;case 5: return snap_to_fun(x,y);break;default: return [x,y];break;};};\ |
11806 | schaersvoo | 4194 | var xlogbase = 10;\ |
4195 | var ylogbase = 10;\ |
||
4196 | var use_xlogscale = 0;\ |
||
4197 | var use_ylogscale = 0;\ |
||
11891 | schaersvoo | 4198 | var x_strings = {};var x_strings_up = [];\ |
11806 | schaersvoo | 4199 | var y_strings = null;\ |
4200 | var use_jsmath = 0;\ |
||
4201 | var xstart = 0;\ |
||
4202 | var ystart = 0;\ |
||
4203 | var unit_x=\" \";\ |
||
4204 | var unit_y=\" \";\ |
||
15111 | schaersvoo | 4205 | var dragdrop_reply = [];\ |
15734 | schaersvoo | 4206 | var external_canvas = create_canvas%d(%d,xsize,ysize);",VERSION,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,xsize,ysize,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,EXTERNAL_IMAGE_CANVAS); |
15111 | schaersvoo | 4207 | /* var xstart,ystart are normally 0 : in case of sgraph they have the 'jump' in the graph */ |
18552 | bpr | 4208 | break; |
4209 | case SEGMENT: |
||
4210 | /* |
||
4211 | @ segment x1,y1,x2,y2,color |
||
4212 | @ alternative: seg |
||
4213 | @ draw a line segment between points (x1:y1)--(x2:y2) in color ''color`` |
||
4214 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
4215 | @%segment_onclick%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%segment 1,1,-9,3,green |
||
4216 | @%segment_drag_y%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag y%segment 1,1,-9,3,green |
||
4217 | */ |
||
4218 | for(i=0;i<5;i++) { |
||
4219 | switch(i){ |
||
4220 | case 0: double_data[0]= get_real(infile,0);break; /* x1-values */ |
||
4221 | case 1: double_data[1]= get_real(infile,0);break; /* y1-values */ |
||
4222 | case 2: double_data[2]= get_real(infile,0);break; /* x2-values */ |
||
4223 | case 3: double_data[3]= get_real(infile,0);break; /* y2-values */ |
||
4224 | case 4: stroke_color=get_color(infile,1);/* name or hex color */ |
||
4225 | if(use_rotate == TRUE ){rotate(4,angle,rotationcenter,2);} |
||
4226 | if(use_affine == TRUE ){ transform(4,2);} |
||
4227 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
4228 | decimals = find_number_of_digits(precision); |
||
18557 | bpr | 4229 | tmp_buffer=my_newmem(MAX_BUFFER); |
4230 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,double_data[1],decimals,double_data[3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4231 | add_to_buffer(tmp_buffer); |
4232 | if(onclick != 0){object_cnt++;} |
||
4233 | /* object_cnt++; */ |
||
4234 | reset(); |
||
4235 | break; |
||
4236 | default: break; |
||
4237 | } |
||
4238 | } |
||
4239 | dragstuff[4] = 1; |
||
4240 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4241 | break; |
||
4242 | case SEGMENTS: |
||
4243 | /* |
||
4244 | @ segments color,x1,y1,x2,y2,...,x_n,y_n |
||
4245 | @ alternative: segs |
||
4246 | @ draw multiple segments between points (x1:y1)--(x2:y2).....and... (x_n-1:y_n-1)--(x_n:y_n) in color ''color`` |
||
4247 | @ use command ''linewidth int`` to adjust size |
||
4248 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
4249 | @%segments_onclick%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%segments green,1,1,3,3,0,0,-3,3,1,1,4,-1,-5,5,-3,-1 |
||
4250 | @%segments_drag_y%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag y%segments green,1,1,3,3,0,0,-3,3,1,1,4,-1,-5,5,-3,-1 |
||
4251 | */ |
||
4252 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
4253 | fill_color = stroke_color; |
||
4254 | i=0; |
||
4255 | while( ! done ){ /* get next item until EOL*/ |
||
4256 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
4257 | if(i%2 == 0 ){ |
||
4258 | double_data[i] = get_real(infile,0); /* x */ |
||
4259 | } |
||
4260 | else { |
||
4261 | double_data[i] = get_real(infile,1); /* y */ |
||
4262 | } |
||
4263 | i++; |
||
4264 | } |
||
4265 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
4266 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
4267 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
4268 | decimals = find_number_of_digits(precision); |
||
4269 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18557 | bpr | 4270 | tmp_buffer=my_newmem(MAX_BUFFER); |
4271 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4272 | add_to_buffer(tmp_buffer); |
4273 | if(onclick != 0){object_cnt++;} |
||
4274 | /* object_cnt++;*/ |
||
4275 | } |
||
4276 | reset(); |
||
4277 | dragstuff[4] = 1; |
||
4278 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4279 | break; |
||
4280 | case SETLIMITS: |
||
4281 | /* |
||
18556 | bpr | 4282 | @ setlimits |
4283 | @ keyword: if set, it will produce 4 inputfields for ''xmin,xmax,ymin,ymax`` and an ''ok`` button |
||
4284 | @ may be used for inputfield based zooming / panning |
||
4285 | @ may be styled using command <a href="#css">css</a> |
||
4286 | @ use commands <a href="#xlabel">xlabel / ylabel</a> to change text from xmin to ''xlabel`` etc |
||
4287 | @ note: the input value will not be checked on validity |
||
4288 | @%setlimits%size 400,400%xrange -10,10%yrange -10,10%precision 1%xlabel T%ylabel H%axis%axisnumbering%grid 2,2,grey,2,2,5,grey%precision 100%multistrokecolors red,green,blue,orange%multilinewidth 1,1,2,2%multistrokeopacity 0.6,0.7,0.8,0.9%jsplot red,1/x,-1,x,1/(x-3),1/(x+3)%setlimits |
||
18552 | bpr | 4289 | */ |
4290 | js_function[JS_SAFE_EVAL] = 1; |
||
4291 | js_function[JSPLOT_AND_ZOOM] = 1; |
||
4292 | add_setlimits(font_size,css_class); |
||
4293 | done = TRUE; |
||
4294 | break; |
||
4295 | case SETPIXEL: |
||
4296 | /* |
||
4297 | @ setpixel x,y,color |
||
4298 | @ A rectangular "point" with diameter 1 pixel centered at (x:y) in xrange / yrange |
||
4299 | @ pixels can <b>not</b> be dragged or clicked |
||
4300 | @ "pixelsize = 1" may be changed by command <code>pixelsize int</code> |
||
4301 | @%setpixel%size 400,400%xrange -10,10%yrange -10,10%setpixel 1,1,red%pixelsize 2%setpixel 2,2,green%pixelsize 3%setpixel 3,3,blue% |
||
4302 | */ |
||
4303 | js_function[DRAW_PIXELS] = 1; |
||
4304 | for(i=0;i<3;i++){ |
||
4305 | switch(i){ |
||
4306 | case 0: double_data[0] = get_real(infile,0); break; /* x */ |
||
4307 | case 1: double_data[1] = get_real(infile,0); break; /* y */ |
||
4308 | case 2: stroke_color = get_color(infile,1); |
||
18557 | bpr | 4309 | tmp_buffer=my_newmem(MAX_BUFFER); |
4310 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_setpixel([%f],[%f],\"%s\",%.2f,%d);\n",double_data[0],double_data[1],stroke_color,stroke_opacity,pixelsize)); |
||
18552 | bpr | 4311 | add_to_buffer(tmp_buffer); |
4312 | break; |
||
4313 | default:break; |
||
4314 | } |
||
4315 | } |
||
4316 | reset(); |
||
4317 | break; |
||
4318 | case SLIDER: |
||
4319 | /* |
||
4320 | @ slider start_value,end_value,width px,height px,type,label |
||
4321 | @ type may be: ''x,y,angle`` |
||
4322 | @ if a slider value display is desired, use for argument ''type``: ''x display``, ''y display``, ''angle radian``, ''angle degree`` |
||
4323 | @ is the slider is used for animation, add keyword ''anim`` or ''animate`` to ''type``; for now only one animated slider may be used... |
||
18572 | bpr | 4324 | @ default behaviour is: click on an object to use its slider(s)<br>to use sliders without clicking on an object, use for ''type`` keyword ''active``<br>eg: <code>slider -2*pi,2*pi,300,30,angle degree active,Rotate</code> |
18552 | bpr | 4325 | @ if a unit (or something like that...) for x/y-value display is needed, use commands ''xunit`` and / or ''yunit`` |
4326 | @ if the translation should be performed using a function, use for type: ''x function``, ''y function``<br>use commands ''sliderfunction_x`` and/or ''sliderfunction_y`` before the slider command to define the functions. Example:<code>sliderfunction_x x^2<br>sliderfunction_y y^2<br>slider -5,5,100,100,xy function,Some_Text<br>...some stuff to slide<br>killslider<br>sliderfunction_x x^2-2<br>slider -15,15,100,10,x function,Some_Other_Text<br>...more stuff to slide<br>killslider... etc</code> |
||
4327 | @ use command ''slider`` before draggable/clickable objects. |
||
4328 | @ drag and drop may be combined with rotation slider<br>for example an arrow rotated by a slider may be placed anywhere (drag&drop)<br><code>size 300,300<br>xrange -5,5<br>yrange -5,5<br>grid 1,1,grey<br>linewidth 3<br>drag xy<br>fillcolor orange<br>strokecolor blue<br>slider 0,2*pi,250,30,angle degrees,Rotate arrow<br>arrow 2,2,5,5,8,red</code><br>note: except a combination 'drag' and 'slider' for command 'latex, katex, mathml, html, obabel' |
||
4329 | @ no slider for a math function, these can be traced using command ''trace_jscurve some_function_in_x`` |
||
4330 | @ a slider will affect all draggable objects after the ''slider`` command...<br>and can be used to group translate / rotate several objects...<br>until a next ''slider`` or keyword ''killslider`` |
||
4331 | @ amount of sliders is not limited. |
||
4332 | @ a slider can not be set ''snaptogrid`` or other ''snapto*`` : you may always use 'drag xy' in combination with the slider objects |
||
4333 | @ <code>javascript:read_dragdrop();</code> will return an array with ''object_number:slider_value`` |
||
4334 | @ every draggable object may have its own slider (no limit in amount of sliders) |
||
4335 | @ label: some slider text. <br>Note: on <a target='new' href='https://katex.org'>KaTeX</a> enabled wims, TeX produced by wims command ''mathmlmath``, is allowed. |
||
4336 | @ use fillcolor for slider controlkey |
||
4337 | @ use strokecolor for slider bar |
||
4338 | @ use fontfamily / fontcolor to set used fonts |
||
4339 | @ use opacity (only fill opacity will be used) to set transparency |
||
4340 | @ the slider canvas will be added to the ''tooltip div``: so incompatible with command tooltip ; setlimits etc |
||
4341 | @%slider_x_y_angle%%size 300,300%xrange -5,5%yrange -5,5%grid 1,1,grey%linewidth 3%fillcolor orange%strokecolor blue%slider 0,2*pi,300,30,angle active degrees,Rotate arrow%arrow 0,0,4.5,0,8,red%killslider%opacity 200,100%slider -2,2,300,30,x active,move blue rectangle%frect -4,4,1,-1,blue%killslider%linewidth 2%slider -2,2,300,30,y,move green rectangle%frect -4,4,1,-1,green |
||
4342 | @%slider_click%%size 300,300%xrange -6,6%yrange -6,6%grid 1,1,grey%linewidth 2%slider 0,2*pi,300,28,angle degree, name%fillcolor lightgreen%#CLICK ON THE OBJECTS TO ACTIVATE%opacity 255,30%ftriangle 2,2,-2,2,0,0,red%ftriangle -2,2,-2,-2,0,0,blue%ftriangle -2,-2,2,-2,0,0,green%ftriangle 2,-2,2,2,0,0,orange%rotationcenter 0,0%frect -2,2,2,-2,black |
||
4343 | @%slider_active%%size 300,300%xrange -6,6%yrange -6,6%grid 1,1,grey%linewidth 1%slider 0,2*pi,300,28,angle degree active, name%fillcolor lightgreen%opacity 255,30%ftriangle 2,2,-2,2,0,0,red%ftriangle -2,2,-2,-2,0,0,blue%ftriangle -2,-2,2,-2,0,0,green%ftriangle 2,-2,2,2,0,0,orange%rotationcenter 0,0%frect -2,2,2,-2,black |
||
4344 | @%slider_animate%%size 300,300%xrange -6,6%yrange -6,6%grid 1,1,grey%linewidth 1%slider 0,2*pi,300,28,angle anim active, name%fillcolor lightgreen%opacity 255,30%ftriangle 2,2,-2,2,0,0,red%ftriangle -2,2,-2,-2,0,0,blue%ftriangle -2,-2,2,-2,0,0,green%ftriangle 2,-2,2,2,0,0,orange%rotationcenter 0,0%frect -2,2,2,-2,black |
||
4345 | @%slider_html_image%%size 400,400%xrange -6,6%yrange -6,6%bgcolor white%grid 1,1,grey%linewidth 1%slider 0,2*pi,300,28,angle active degree,%centered%html 0,0,<img src="gifs/domains/sciences/flasks.svg" width="100px" height="100px"> |
||
4346 | */ |
||
4347 | js_function[INTERACTIVE] = 1; |
||
4348 | int_data[2] = 0; /* --> show_display = 0; */ |
||
4349 | for(i=0; i<6 ; i++){ |
||
4350 | switch(i){ |
||
4351 | case 0: double_data[0] = get_real(infile,0);break; /* start value */ |
||
4352 | case 1: double_data[1] = get_real(infile,0);break; /* end value */ |
||
4353 | case 2: int_data[0] = (int)(get_real(infile,0));break; /* width */ |
||
4354 | case 3: int_data[1] = (int)(get_real(infile,0));break; /* height */ |
||
4355 | case 4: temp = get_string_argument(infile,0); /* type: x,y,angle */ |
||
4356 | if( strstr(temp,"displ")!=0 || strstr(temp,"deg")!=0 || strstr(temp,"rad")!=0 ){int_data[5] = 1; }else{int_data[5] = 0;} |
||
4357 | if(strstr(temp,"anim")!= 0){int_data[3] = 1;}else{int_data[3] = 0;} |
||
4358 | if(strstr(temp,"active")!= 0){onclick = 4;}else{onclick=0;} |
||
4359 | if(strstr(temp,"angle")!= 0){slider_type="R";if( strstr(temp,"rad")!= 0){int_data[2] = 3;}if( strstr(temp,"deg")!= 0){int_data[2] = 4;}} |
||
4360 | else |
||
4361 | if(strstr(temp,"xy") != 0){slider_type = "XY";if( strstr(temp,"disp")!= 0){int_data[2] = 5;}} |
||
4362 | else |
||
4363 | if(strstr(temp,"x") != 0){slider_type = "X";if( strstr(temp,"disp")!= 0){int_data[2] = 1;}} |
||
4364 | else |
||
4365 | if(strstr(temp,"y") != 0){slider_type = "Y";if( strstr(temp,"disp")!= 0){int_data[2] = 2;}} |
||
4366 | else |
||
4367 | canvas_error("slider can be of type: x,y,angle,fun_x:fun_y"); |
||
4368 | break; |
||
4369 | case 5: temp = get_string_argument(infile,1); if( strstr(temp,"\"") != 0 ){ temp = str_replace(temp,"\""," ");} |
||
4370 | /* slider label : in case of latex/mathmlmath we need to remove the extra " */ |
||
4371 | break; |
||
4372 | } |
||
4373 | } |
||
4374 | if(use_slider == -1 ){ /* add once */ |
||
4375 | add_slider(int_data[3]); |
||
4376 | if(int_data[5] == 1 ){add_slider_display(precision,font_size,font_color,stroke_opacity);} |
||
4377 | } |
||
4378 | use_slider++; |
||
4379 | if(int_data[3] == 0){\ |
||
18557 | bpr | 4380 | |
4381 | tmp_buffer=my_newmem(MAX_BUFFER); |
||
18570 | bpr | 4382 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"slider%d = new slider(\"%s\",\"%s\",%d,%d,%d,%d,\"%s\",\"%s\",[%f,%f],%f,%f,'%s',%d);\n",use_slider,slider_type,temp,use_slider,int_data[0],int_data[1],line_width,fill_color,stroke_color,fill_opacity,stroke_opacity,double_data[0],double_data[1],font_family,int_data[2])); |
18552 | bpr | 4383 | }else{ |
18557 | bpr | 4384 | |
18552 | bpr | 4385 | add_slider(int_data[3]);/* use only once !! */ |
18557 | bpr | 4386 | tmp_buffer=my_newmem(MAX_BUFFER); |
18570 | bpr | 4387 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"slider%d = new animslider(\"%s\",\"%s\",%d,%d,%d,%d,\"%s\",\"%s\",[%f,%f],%f,%f,'%s',%d);\n",use_slider,slider_type,temp,use_slider,int_data[0],int_data[1],line_width,fill_color,stroke_color,fill_opacity,stroke_opacity,double_data[0],double_data[1],font_family,int_data[2])); |
18552 | bpr | 4388 | } |
4389 | add_to_buffer(tmp_buffer); |
||
4390 | fprintf(js_include_file,"var slider%d;",use_slider); |
||
4391 | use_dragstuff = 2; |
||
4392 | // dragstuff[22] = 1; /* dragstuff switch no 22 is a slider...*/ |
||
4393 | if(onclick != 4 ){ js_function[INTERACTIVE] = 1; }/* no need to click on object to use slider... */ |
||
4394 | //js_function[JS_ROTATE_MOUSE] = 1; |
||
4395 | c = 0; |
||
4396 | for(i=last_slider;i<=use_slider;i++){ |
||
4397 | int_data[c] = i; c++; |
||
4398 | } |
||
4399 | my_sliders = data2js_array(int_data,use_slider - last_slider+1); |
||
4400 | break; |
||
4401 | case SGRAPH: |
||
4402 | /* |
||
18556 | bpr | 4403 | @ sgraph xstart,ystart,xmajor,ymajor,xminor,yminor,majorgrid_color,minorgrid_color |
4404 | @ primitive implementation of a ''broken scale`` graph... |
||
4405 | @ not very versatile: only usable in combination with userdraw <br>eg no other objects will obey this "coordinate system"<br>if you want to place an object into this coordinate system, be aware that 10% or 20% of xsize and/or ysize is ''lost``.<br>Use these "formulas" to recalculate the virtual coordinates:<br>factor=0.8 in case xstart != xmin (or ystart != ymin)<br>factor=0.9 in case xstart = xmin (or ystart = ymin)<br>px_x_point = ((factor*xsize)/(xmax - xstart))*(x_point - xmax)+xsize<br>x_recalculated = px*(xmax - xmin)/xsize + $xmin<br>px_y_point = -1*factor*y_point*ysize/(ymax - ystart) + ymax*factor*ysize/(ymax - ystart)<br>y_recalculated = ymax - py*(ymax - ymin)/ysize<br> |
||
4406 | @%sgraph%size 400,400%xrange 0,10000%yrange 0,100%sgraph 9000,50,100,10,4,4,grey,blue%userinput_xy%linewidth 2%userdraw segments,red%precision 0%mouse blue,22 |
||
18552 | bpr | 4407 | */ |
4408 | js_function[DRAW_SGRAPH] = 1; |
||
4409 | for(i = 0 ; i < 8 ;i++){ |
||
4410 | switch(i){ |
||
4411 | case 0:double_data[0] = get_real(infile,0);break; |
||
4412 | case 1:double_data[1] = get_real(infile,0);break; |
||
4413 | case 2:double_data[2] = get_real(infile,0);break; |
||
4414 | case 3:double_data[3] = get_real(infile,0);break; |
||
4415 | case 4:int_data[0] = (int)(get_real(infile,0));break; |
||
4416 | case 5:int_data[1] = (int)(get_real(infile,0));break; |
||
4417 | case 6:stroke_color = get_color(infile,0);break; |
||
4418 | case 7:font_color = get_color(infile,1); |
||
18557 | bpr | 4419 | tmp_buffer=my_newmem(MAX_BUFFER); |
4420 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "xstart = %f;\n ystart = %f;\ndraw_sgraph(%d,%d,%f,%f,%d,%d,\"%s\",\"%s\",\"%s\",%f,%d);\n", double_data[0],double_data[1],GRID_CANVAS,precision,double_data[2],double_data[3],int_data[0],int_data[1],stroke_color,font_color,font_family,stroke_opacity,font_size)); |
||
18552 | bpr | 4421 | add_to_buffer(tmp_buffer); |
4422 | break; |
||
4423 | default:break; |
||
4424 | } |
||
4425 | } |
||
4426 | /* sgraph(canvas_type,precision,xmajor,ymajor,xminor,yminor,majorcolor,minorcolor,fontfamily,opacity)*/ |
||
4427 | break; |
||
4428 | case SNAPTOFUNCTION: |
||
4429 | /* |
||
4430 | @ snaptofunction some_function_in_x,some_funtion_in_y |
||
4431 | @ alternative: snaptofun |
||
4432 | @ the next object will snap to the calculated values |
||
4433 | @ note: snaptofun is probably not really useful feature... |
||
4434 | @ if you want only modification of y-values,just use: <code>snaptofunction x,5*sin(1/y)</code> |
||
4435 | @ if you want only modification of x-values,just use: <code>snaptofunction 5*sin(1/x),y</code> |
||
4436 | @ for now only one instance of ''snaptofunction`` is allowed |
||
4437 | @ use rawmath on your functions: no validity checking is done by wims ! |
||
4438 | @ note: switching x and y coordinates? <code>snaptofunction y,x</code> |
||
4439 | @%snaptofunction_1%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 100%snaptofunction x,5*sin(x)%linewidth 3%crosshairsize 6%userdraw crosshairs,red%linewidth 2%curve blue,5*sin(x)%xunit = x-value%display x,blue,22 |
||
4440 | @%snaptofunction_2%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 100%snaptofunction y^2-9,y%#snaptofunction y^2-9,abs(y)%linewidth 3%crosshairsize 6%userdraw crosshairs,red%linewidth 2%curve blue,sqrt(x+9)%curve blue,-1*sqrt(x+9)%yunit = y-value%display y,blue,22 |
||
4441 | */ |
||
4442 | temp = get_string_argument(infile,0); |
||
4443 | use_snap = 2; |
||
4444 | use_snap = 5; |
||
4445 | js_function[JS_MATH] = 1; |
||
4446 | fprintf(js_include_file,"var snap_fun = {x:to_js_math('%s'),y:to_js_math('%s')};function snap_to_fun(px,py){ var x = px2x(px); var y = px2y(py); return [ x2px(eval(snap_fun.x)) , y2px(eval(snap_fun.y)) ];};",temp,get_string(infile,1)); |
||
4447 | break; |
||
4448 | case SNAPTOPOINTS: |
||
4449 | /* |
||
4450 | @ snaptopoints x1,y1,x2,y2,x3,y3.... |
||
4451 | @ a userdraw object will snap to these points. |
||
18572 | bpr | 4452 | @ the array size (e.g. the number of points) of command ''snaptopoints`` is limited by constant MAX_INT (canvasdraw.h)<br>this command may be repeated multiple times (no limit) to add points |
18552 | bpr | 4453 | @ a draggable object (use command ''drag x|y|xy``) will snap to the closed of these points when dragged (mouseup) |
4454 | @ other options: use keyword ''snaptogrid``, ''xsnaptogrid`` or ''ysnaptogrid`` |
||
18616 | bpr | 4455 | @%snaptopoints_1%size 400,400%xrange -5,5%yrange -5,5%snaptopoints -1,-3,-1,-2,-1,0,-1,1,-1,2,-1,3,1,-3,1,-2,1,-1,1,0,1,1,1,2,1,3%linewidth 2%points red,-1,-3,-1,-2,-1,0,-1,1,-1,2,-1,3,1,-3,1,-2,1,-1,1,0,1,1,1,2,1,3%userdraw arrows,red |
4456 | @%snaptopoints_2%size 400,400%xrange -5,5%yrange -5,5%snaptopoints -1,-3,-1,-2,-1,0,-1,1,-1,2,-1,3,1,-3,1,-2,1,-1,1,0,1,1,1,2,1,3%linewidth 3%%points blue,-1,-3,-1,-2,-1,0,-1,1,-1,2,-1,3,1,-3,1,-2,1,-1,1,0,1,1,1,2,1,3%drag xy%ftriangle -4,0,-2,3,0,0,red |
||
18552 | bpr | 4457 | */ |
4458 | i = 0; |
||
4459 | while( ! done ){ /* get next item until EOL*/ |
||
4460 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
4461 | if(i%2 == 0 ){ |
||
4462 | double_data[i] = get_real(infile,0); /* x */ |
||
4463 | } |
||
4464 | else { |
||
4465 | double_data[i] = get_real(infile,1); /* y */ |
||
4466 | } |
||
4467 | i++; |
||
4468 | } |
||
4469 | decimals = find_number_of_digits(precision); |
||
4470 | /* NEED AN EXTRA COUNTER VARIABLE FOR MORE THAN 2 CALLS */ |
||
4471 | fprintf(js_include_file,"if( temp_push_array === 'undefined' ){var temp_push_array;};if( points_to_snap_on === 'undefined' ){var points_to_snap_on;};var temp_push_array = [%s];\n",double_xy2js_array(double_data,i,decimals)); |
||
4472 | if( snap_to_points_cnt == 0 ){ |
||
4473 | fprintf(js_include_file,"points_to_snap_on = temp_push_array;function find_min_diff(x,y,X,Y){var diff = 100000000;var chk;var idx = 0;var p = 0;while(X[p] != null){chk = distance(x,y,X[p],Y[p]);if( chk < diff ){ diff = chk; idx = p;};p++;};return idx;};function snap_to_points(x,y){x = px2x(x); y = px2y(y);var xpoints = points_to_snap_on[0];var ypoints = points_to_snap_on[1];var idx = find_min_diff(x,y,xpoints,ypoints);x = xpoints[idx];y = ypoints[idx];return [x2px(x),y2px(y)];};"); |
||
4474 | }else{ |
||
4475 | fprintf(js_include_file,"points_to_snap_on[0].push.apply(points_to_snap_on[0],temp_push_array[0]);points_to_snap_on[1].push.apply(points_to_snap_on[1],temp_push_array[1]);"); |
||
4476 | } |
||
4477 | snap_to_points_cnt = 1; /* do not repeat including the js-functions...just once*/ |
||
4478 | use_snap = 4; |
||
4479 | break; |
||
4480 | case SNAPTOGRID: |
||
4481 | /* |
||
18556 | bpr | 4482 | @ snaptogrid |
4483 | @ keyword (no arguments required) |
||
4484 | @ a draggable object (use command ''drag x|y|xy``) will snap to the given grid when dragged (mouseup) |
||
4485 | @ in case of userdraw the drawn points will snap to xmajor / ymajor grid |
||
4486 | @ if no grid is defined, points will snap to every integer xrange/yrange value. (eg snap_x=1,snap_y=1) |
||
4487 | @ if you do not want a visible grid, but you only want a ''snaptogrid`` with some value...define this grid with opacity 0. |
||
4488 | @ if xminor / yminor is defined,(use keyword ''axis`` to activate the minor steps) the drawing will snap to xminor and yminor<br>use only even dividers in x/y-minor...for example <code>snaptogrid<br>axis<br>grid 2,1,grey,4,4,7,red</code> will snap on x=0, x=0.5, x=1, x=1.5 .... will snap on y=0, y=0.25 y=0.5 y=0.75 ... |
||
4489 | @%snaptogrid_1%size 400,400%xrange -5,5%yrange -5,5%axis%axisnumbering%precision 1%grid 1,1,grey,2,2,6,grey%linewidth 2%snaptogrid%userdraw crosshairs,blue%mouse red,22 |
||
4490 | @%snaptogrid_2%size 400,400%xrange -5,5%yrange -5,5%axis%axisnumbering%precision 1%grid 1,1,grey,4,1,6,grey%linewidth 1%snaptogrid%userdraw crosshairs,blue%mouse red,22 |
||
18552 | bpr | 4491 | */ |
4492 | use_snap = 1; |
||
4493 | break; |
||
4494 | case SQUARE: |
||
4495 | /* |
||
4496 | @ square x,y,side (px),color |
||
4497 | @ draw a square with left top corner (x:y) with side ''side`` in color 'color' |
||
4498 | @ use command <code>fsquare x,y,side,color</code> for a filled square |
||
4499 | @ use command/keyword <a href='#filled'>filled</a> before command <code>square x,y,side,color</code> |
||
4500 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
4501 | @%square%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%filled%fillcolor blue%square 0,0,120,green |
||
4502 | */ |
||
4503 | for(i=0;i<4;i++){ |
||
4504 | switch(i){ |
||
4505 | case 0:double_data[0] = get_real(infile,0);break; /* x1-values */ |
||
4506 | case 1:double_data[1] = get_real(infile,0);break; /* y1-values */ |
||
4507 | case 2:double_data[2] = get_real(infile,0);break; /* width in px */ |
||
4508 | case 3:stroke_color = get_color(infile,1);/* name or hex color */ |
||
4509 | decimals = find_number_of_digits(precision); |
||
4510 | double_data[3] = double_data[0] + (xmax - xmin)*double_data[2]/xsize; |
||
4511 | double_data[4] = double_data[1] + -1*(ymax - ymin)*double_data[2]/ysize; |
||
4512 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 4513 | tmp_buffer=my_newmem(MAX_BUFFER); |
4514 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,1,[%.*f,%.*f,%.*f,%.*f],[%.*f,%.*f,%.*f,%.*f],[%d],[%d],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[3],decimals,double_data[3],decimals,double_data[0],decimals,double_data[1],decimals,double_data[1],decimals,double_data[4],decimals,double_data[4],line_width,line_width,line_width,stroke_color,stroke_opacity,stroke_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4515 | add_to_buffer(tmp_buffer); |
4516 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
4517 | reset();break; |
||
4518 | default: break; |
||
4519 | } |
||
4520 | } |
||
4521 | dragstuff[1] = 1; |
||
4522 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4523 | break; |
||
4524 | case STATUS: |
||
4525 | /* |
||
4526 | @ status |
||
4527 | @ keyword |
||
4528 | @ alernative: nostatus |
||
4529 | @ used to override the effects of ''status=done`` in wims (answer.phtml) |
||
4530 | @ affects ''readonly`` in inputfields / textareas in canvasimage and all userdraw based commands |
||
4531 | @ e.g.: if keyword ''status`` is set, the pupil will be able to modify the canvas when the ''wims $status variable`` is set to ''done`` |
||
4532 | */ |
||
11806 | schaersvoo | 4533 | |
18552 | bpr | 4534 | fprintf(js_include_file,"\nwims_status=\"waiting\";\n"); |
4535 | break; |
||
4536 | case STRING: |
||
4537 | /* |
||
18556 | bpr | 4538 | @ string color,x,y,the text string |
4539 | @ may be set ''onclick`` or ''drag xy`` |
||
4540 | @ note: when set ''onclick``, use an extra command ''fontsize`` (default: fontsize=12) to adjust the size of the clicked text-string<br>note: a clicked text string will be hardcoded : fontsize+10 in the font family courier |
||
18572 | bpr | 4541 | @ unicode supported: <code>string red,0,0,\\u2232</code><br> See <a target='new' href='https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode'>https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode</a><br> See <a target='new' href='https://en.wikipedia.org/wiki/Greek_script_in_Unicode'>https://en.wikipedia.org/wiki/Greek_script_in_Unicode</a> |
18556 | bpr | 4542 | @ use a command like <code>fontfamily italic 24px Arial</code> to set fonts on browser that support font change |
4543 | @ super / sub script is supported, using '<b>_</b>' and '<b>^</b>' <br>The font family for the sub/sup string will be Helvetica e.g. your font family settings will be ignored <br>to force end the subscript/supscript, use an extra space...see example: |
||
4544 | @%string_sup_sub%size 400,400%xrange -6,6%yrange -6,6%fontfamily 22px Arial%# you can use a single space for separation in formula...%# use double space to create new word%string blue,-5,3,H_3O^+ + OH^- \\u2192 2H_2O%# you can use a single space for separation in formula...%string red,-5,-3,H_3 O^+ + OH^\\u2212 \\u2192 2H_2 O% |
||
4545 | @%string%size 400,400%xrange -10,10%yrange -10,10%fontfamily 14px Arial%crosshair -3,-3,red%crosshair 3,3,blue%string red,-3,-3,Hello World%fontfamily Italic 18px Arial%string red,3,3,Hello World%fontfamily 22pt STIX%string black,-10,8,\\u03B1 \\u03B2 \\u03B3 \\u03B4 \\u03B5 \\u03B6 \\u03B7 \\u03B8 \\u03B9 \\u03BA \\u03BB \\u03BC \\u03BD \\u03BE \\u03BF |
||
18552 | bpr | 4546 | */ |
4547 | if( use_rotate == TRUE ){js_function[JS_ROTATE_MOUSE] = 1; } |
||
4548 | dragstuff[14] = 1; |
||
4549 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4550 | for(i=0;i<5;i++){ |
||
4551 | switch(i){ |
||
4552 | case 0: stroke_color = get_color(infile,0);break;/* name or hex color */ |
||
4553 | case 1: double_data[0] = get_real(infile,0);break; /* x in xrange*/ |
||
4554 | case 2: double_data[1] = get_real(infile,0);break; /* y in yrange*/ |
||
4555 | case 3: decimals = find_number_of_digits(precision); |
||
4556 | if(use_affine == TRUE ){ transform(2,2);} |
||
4557 | /* rotate is done by HTML5/CANVAS context rotation */ |
||
4558 | temp = get_string_argument(infile,1); |
||
4559 | if(strstr(temp,"_") != NULL || strstr(temp,"^") != NULL){js_function[DRAW_SUBSUP] = 1;} |
||
4560 | decimals = find_number_of_digits(precision); |
||
4561 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 4562 | tmp_buffer=my_newmem(MAX_BUFFER); |
4563 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,14,[%.*f],[%.*f],[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,0,0,0,use_rotate,angle,temp,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4564 | add_to_buffer(tmp_buffer); |
4565 | if(onclick != 0){object_cnt++;} |
||
4566 | //onclick = 0; |
||
4567 | //use_offset = 0; |
||
4568 | reset(); |
||
4569 | break; |
||
4570 | default:break; |
||
4571 | } |
||
4572 | } |
||
4573 | break; |
||
4574 | case STRINGUP: |
||
4575 | /* |
||
18556 | bpr | 4576 | @ stringup color,x,y,rotation_degrees,the text string |
4577 | @ may be set ''onclick`` or ''drag xy`` |
||
4578 | @ note: when set ''onclick``, use an extra command ''fontsize`` (default: fontsize=12) to adjust the size of the clicked text-string<br>note: a clicked text string will be hardcoded : fontsize+10 in the font family courier |
||
4579 | @ unicode supported: <code>stringup red,0,0,45,\\u2232</code> |
||
4580 | @ use a command like <code>fontfamily bold 34px Courier</code> to set fonts on browser that support font change |
||
4581 | @ you could use keyword <a href='#yoffset'>yoffset</a> to -sometimes- do a small correction of text placement under/above a point (e.g. text & point have thesame coordinates) |
||
18572 | bpr | 4582 | @ note: no need to ''killrotate`` after ''stringup``<br><code>onclick<br>rotate 45<br>string red,0,0,AAAAAA<br>killrotate<br>string red,4,4,BBBBBB</code><br>is identical with:<br><code>onclick<br>stringup red,0,0,45,AAAAAA<br>string red,4,4,BBBBBB</code> |
18556 | bpr | 4583 | @ super / sub script is supported, using '<b>_</b>' and '<b>^</b>' <br>to end the subscript/supscript, use an extra space...see example: |
4584 | @%stringup_sub_sup%size 400,400%xrange -6,6%yrange -6,6%fontfamily 22px Arial%# use single space for separation in formula...%# use double space to create new word%stringup red,-5,0,45,H_3 O^+ + OH^\\u2212 \\u2192 2H_2 O% |
||
4585 | @%stringup%size 400,400%xrange -10,10%yrange -10,10%fontsize 24%fontfamily 14px Arial%crosshair -3,0,red%crosshair 3,0,blue%onclick%stringup red,-3,0,-90,Hello World%drag xy%stringup red,-3,0,-45,Hello World%stringup red,-3,0,45,Hello World%stringup red,-3,0,90,Hello World%stringup blue,3,0,-90,Hello World%stringup blue,3,0,-45,Hello World%stringup blue,3,0,45,Hello World%stringup blue,3,0,90,Hello World |
||
11806 | schaersvoo | 4586 | |
18552 | bpr | 4587 | */ |
4588 | /* html5 canvas rotation is only used for text objects */ |
||
4589 | use_rotate = TRUE ; |
||
4590 | dragstuff[14] = 1; |
||
4591 | js_function[JS_ROTATE_MOUSE] = 1; |
||
4592 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
10953 | bpr | 4593 | |
18552 | bpr | 4594 | for(i=0;i<6;i++){ |
4595 | switch(i){ |
||
4596 | case 0: stroke_color = get_color(infile,0);break;/* name or hex color */ |
||
4597 | case 1: double_data[0] = get_real(infile,0);break; /* x */ |
||
4598 | case 2: double_data[1] = get_real(infile,0);break; /* y */ |
||
4599 | case 3: angle = get_real(infile,0);break;/* rotation */ |
||
4600 | case 4: decimals = find_number_of_digits(precision); |
||
4601 | temp = get_string_argument(infile,1); |
||
4602 | if(strstr(temp,"_") != NULL || strstr(temp,"^") != NULL){js_function[DRAW_SUBSUP] = 1;} |
||
4603 | decimals = find_number_of_digits(precision); |
||
4604 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 4605 | tmp_buffer=my_newmem(MAX_BUFFER); |
4606 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,14,[%.*f],[%.*f],[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,0,0,0,use_rotate,angle,temp,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4607 | add_to_buffer(tmp_buffer); |
4608 | if(onclick != 0){object_cnt++;} |
||
4609 | //onclick = 0; |
||
4610 | //use_offset = 0; |
||
4611 | reset(); |
||
4612 | break; |
||
4613 | default:break; |
||
4614 | } |
||
4615 | } |
||
4616 | use_rotate = FALSE; |
||
4617 | break; |
||
4618 | case STYLE: |
||
4619 | /* |
||
18556 | bpr | 4620 | @ highlight color,opacity,linewidth |
4621 | @ NOT IMPLEMENTED |
||
4622 | @ use command ''onclick``: when the object receives a userclick it will increase its linewidth |
||
18552 | bpr | 4623 | */ |
4624 | break; |
||
4625 | case STROKECOLOR: |
||
4626 | /* |
||
4627 | @ strokecolor colorname or #hex |
||
4628 | @ to be used for commands that do not supply a color argument (like command ''linegraph``) |
||
4629 | */ |
||
4630 | stroke_color = get_color(infile,1); |
||
4631 | break; |
||
4632 | case FLY_TEXT: |
||
4633 | /* |
||
4634 | @ text fontcolor,x,y,font,text_string |
||
4635 | @ font may be described by keywords: giant,huge,normal,small,tiny |
||
4636 | @ use command ''fontsize`` to increase base fontsize for these keywords |
||
4637 | @ may be set ''onclick`` or ''drag xy`` |
||
4638 | @ backwards compatible with flydraw |
||
4639 | @ unicode supported: text red,0,0,huge,\\u2232 |
||
4640 | @ special: use '_' and '^' to imitate html sup/sub, like H_3O^+ + OH^\\u22i2 \\u2192 2H_2 O |
||
4641 | @ much better to use command <a href='#string'>string</a> combined with <a href='#fontfamily'>fontfamily</a> for a more fine grained control over html5 canvas text element |
||
4642 | @ super / sub script is supported, using '<b>_</b>' and '<b>^</b>' <br>to end the subscript/supscript, use an extra space...see <a href='#string'>string </a> command |
||
4643 | @ Avoid mixing old flydraw commands ''text``, ''textup`` with new canvasdraw commands ''string``, ''stringup``. If the fontfamily was set completely like <code>fontfamily italic 24px Arial</code>. In that case reset ''fontfamily`` to something lke ''fontfamily Arial`` before the old flydraw commands. |
||
4644 | @%text%size 400,400%xrange -10,10%yrange -10,10%fontsize 14%onclick%drag xy%text green,-4,-4,small,Hello World%drag xy%text red,-4,-2,large,Hello World%drag xy%text blue,-4,0,huge,Hello World%drag xy%text green,-4,3,giant,Hello World%drag xy |
||
4645 | */ |
||
4646 | for(i = 0; i < 5 ;i++){ |
||
4647 | switch(i){ |
||
4648 | case 0: stroke_color = get_color(infile,0);break;/* font_color == stroke_color name or hex color */ |
||
4649 | case 1: double_data[0] = get_real(infile,0);break; /* x */ |
||
4650 | case 2: double_data[1] = get_real(infile,0);break; /* y */ |
||
4651 | case 3: fly_font = get_string_argument(infile,0); |
||
4652 | if(strcmp(fly_font,"giant") == 0){ |
||
4653 | fly_font_size = (int)(font_size + 24); |
||
4654 | } |
||
4655 | else { |
||
4656 | if(strcmp(fly_font,"huge") == 0){ |
||
4657 | fly_font_size = (int)(font_size + 14); |
||
4658 | } |
||
4659 | else { |
||
4660 | if(strcmp(fly_font,"large") == 0){ |
||
4661 | fly_font_size = (int)(font_size + 6); |
||
4662 | } |
||
4663 | else { |
||
4664 | if(strcmp(fly_font,"small") == 0){ |
||
4665 | fly_font_size = (int)(font_size - 4); |
||
4666 | if(fly_font_size<0){fly_font_size = 8;} |
||
4667 | } |
||
4668 | } |
||
4669 | } |
||
4670 | } |
||
4671 | break; |
||
4672 | case 4: |
||
4673 | temp = get_string_argument(infile,1); |
||
4674 | if(strstr(temp,"_") != NULL || strstr(temp,"^") != NULL){js_function[DRAW_SUBSUP] = 1;} |
||
4675 | decimals = find_number_of_digits(precision); |
||
4676 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
4677 | if(use_affine == TRUE ){ transform(2,2);} |
||
18557 | bpr | 4678 | tmp_buffer=my_newmem(MAX_BUFFER); |
4679 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,14,[%.*f],[%.*f],[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%f,\"%s\",%d,%s,%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,0,0,0,use_rotate,angle,temp,fly_font_size,"null",my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 4680 | add_to_buffer(tmp_buffer); |
4681 | if(onclick != 0){object_cnt++;} |
||
4682 | reset(); |
||
4683 | break; |
||
4684 | default:break; |
||
4685 | } |
||
4686 | } |
||
4687 | dragstuff[14] = 1; |
||
4688 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4689 | break; |
||
4690 | case TEXTAREA: |
||
4691 | /* |
||
18556 | bpr | 4692 | @ textarea x,y,cols,rows,readonly,value |
4693 | @ may be further controlled by <a href="#css">css</a> |
||
4694 | @ if ''$status=done`` (e.g. in answer.phtml) the inputfield will be cleared and set readonly. Override this by keyword <a href="#status">status</a>. |
||
4695 | @ if mathml inputfields are present and / or some userdraw is performed, these data will <b>not</b> be send as well (<code>javascript:read_canvas();</code>) |
||
4696 | @ keyword ''xoffset | centered`` is not active for command ''textarea`` |
||
4697 | @%textarea%size 400,400%xrange -10,10%yrange -10,10%css color:red;background-color:lightblue;font-size:14px;text-align:center%textarea -3,-2,6,3,1,?%css color:blue;background-color:yellow;font-size:14px;text-align:center%textarea 0,-2,8,2,1,? |
||
18552 | bpr | 4698 | */ |
4699 | js_function[DRAW_TEXTAREAS] = 1; |
||
4700 | for(i = 0 ; i<6;i++){ |
||
4701 | switch(i){ |
||
4702 | case 0: int_data[0]=x2px(get_real(infile,0));break; /* x in px */ |
||
4703 | case 1: int_data[1]=y2px(get_real(infile,0));break; /* y in px */ |
||
4704 | case 2: int_data[2]=abs( (int)(get_real(infile,0)));break;/* cols */ |
||
4705 | case 3: int_data[3]=abs( (int)(get_real(infile,0)));break;/* rows */ |
||
4706 | case 4: if( get_real(infile,1) >0){int_data[4] = 1;}else{int_data[3] = 0;};break; /* readonly */ |
||
4707 | case 5: temp = get_string_argument(infile,1); |
||
18557 | bpr | 4708 | tmp_buffer=my_newmem(MAX_BUFFER); |
4709 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_textareas(%d,%d,%d,%d,%d,%d,%d,\"%s\",\"%s\");\n",canvas_root_id,input_cnt,int_data[0],int_data[1],int_data[2],int_data[3],int_data[4],css_class,temp)); |
||
18552 | bpr | 4710 | add_to_buffer(tmp_buffer); |
4711 | input_cnt++;break; |
||
4712 | default: break; |
||
4713 | } |
||
4714 | } |
||
4715 | if(reply_format == 0 ){reply_format = 15;} |
||
4716 | reset(); |
||
4717 | break; |
||
4718 | case TEXTFILL: |
||
4719 | /* |
||
4720 | @ textfill x0,y0,color,some_text |
||
4721 | @ x0,y0 in xrange / yrange |
||
4722 | @ color will be used for the font color |
||
4723 | @ use command <a href="#fontfamily">fontfamily</a> to set font type and size |
||
4724 | @ there is also a command <a href="#userdraw">userdraw textfill,color,some_text</a> |
||
4725 | @%textfill%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%fontfamily 24pt Arial%circles red,0,0,3,3,3,6%textfill 4,4,blue,HELLO WORLD |
||
4726 | */ |
||
11806 | schaersvoo | 4727 | |
18552 | bpr | 4728 | js_function[DRAW_TEXTFILL] = 1; |
4729 | if(js_function[DRAW_FILLTOBORDER] != 1 ){/* use only once */ |
||
4730 | js_function[DRAW_FILLTOBORDER] = 1; |
||
4731 | add_js_filltoborder(canvas_type); |
||
4732 | } |
||
4733 | decimals = find_number_of_digits(precision); |
||
4734 | for(i=0;i<4;i++){ |
||
4735 | switch(i){ |
||
4736 | case 0: double_data[0] = get_real(infile,0); break; /* x in px */ |
||
4737 | case 1: double_data[1] = get_real(infile,0); break; /* y in py */ |
||
4738 | case 2: font_color = get_color(infile,0); break; |
||
4739 | case 3: temp = get_string(infile,1); |
||
18557 | bpr | 4740 | tmp_buffer=my_newmem(MAX_BUFFER); |
4741 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_textfill(%d,%*.f,%*.f,'%s','%s',%d,%d,'%s',false); ",FILL_CANVAS+fill_cnt,decimals,double_data[0],decimals,double_data[1],font_color,font_family,xsize,ysize,temp)); |
||
18552 | bpr | 4742 | add_to_buffer(tmp_buffer); |
4743 | fill_cnt++; |
||
4744 | break; |
||
4745 | default:break; |
||
4746 | } |
||
4747 | } |
||
4748 | reset(); |
||
4749 | break; |
||
4750 | case FLY_TEXTUP: |
||
4751 | /* |
||
18556 | bpr | 4752 | @ textup fontcolor,x,y,font,text_string |
4753 | @ can <b>not</b> be set ''onclick`` or ''drag xy`` (because of translaton matrix...mouse incompatible) |
||
4754 | @ font may be described by keywords: giant,huge,normal,small,tiny |
||
4755 | @ use command ''fontsize`` to increase base fontsize for the keywords |
||
4756 | @ backwards compatible with flydraw |
||
4757 | @ unicode supported: textup red,0,0,huge,\\u2232 |
||
4758 | @ use command ''stringup`` and ''fontfamily`` for a more fine grained control over html5 canvas text element |
||
4759 | @ Avoid mixing old flydraw commands ''text``, ''textup`` with new canvasdraw commands ''string``; ''stringup``. If the fontfamily was set completely like <code>fontfamily italic 24px Arial</code>. In that case reset ''fontfamily`` to something like ''fontfamily Arial`` before the old flydraw commands. |
||
18552 | bpr | 4760 | */ |
4761 | js_function[DRAW_TEXTS] = 1; |
||
4762 | for(i = 0; i<5 ;i++){ |
||
4763 | switch(i){ |
||
4764 | case 0: font_color = get_color(infile,0);break;/* name or hex color */ |
||
4765 | case 1: int_data[0] = x2px(get_real(infile,0));break; /* x */ |
||
4766 | case 2: int_data[1] = y2px(get_real(infile,0));break; /* y */ |
||
4767 | case 3: fly_font = get_string_argument(infile,0); |
||
4768 | if(strcmp(fly_font,"giant") == 0){ |
||
4769 | fly_font_size = (int)(font_size + 24); |
||
4770 | } |
||
4771 | else { |
||
4772 | if(strcmp(fly_font,"huge") == 0){ |
||
4773 | fly_font_size = (int)(font_size + 14); |
||
4774 | } |
||
4775 | else { |
||
4776 | if(strcmp(fly_font,"large") == 0){ |
||
4777 | fly_font_size = (int)(font_size + 6); |
||
4778 | } |
||
4779 | else { |
||
4780 | if(strcmp(fly_font,"small") == 0){ |
||
4781 | fly_font_size = (int)(font_size - 4); |
||
4782 | if(fly_font_size<0){fly_font_size = 8;} |
||
4783 | } |
||
4784 | } |
||
4785 | } |
||
4786 | } |
||
4787 | break; |
||
4788 | case 4: |
||
4789 | decimals = find_number_of_digits(precision); |
||
4790 | temp = get_string_argument(infile,1); |
||
4791 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 4792 | tmp_buffer=my_newmem(MAX_BUFFER); |
4793 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_text(%d,%d,%d,%d,\"%s\",\"%s\",%.2f,90,\"%s\",%d,%.2f,%d);\n",STATIC_CANVAS,int_data[0],int_data[1],fly_font_size,"null",font_color,stroke_opacity,temp,use_rotate,angle,use_offset)); |
||
18552 | bpr | 4794 | add_to_buffer(tmp_buffer); |
4795 | reset(); |
||
4796 | //use_offset = 0; |
||
4797 | break; |
||
4798 | default:break; |
||
4799 | } |
||
4800 | } |
||
4801 | break; |
||
4802 | case TRACE_JSCURVE: |
||
4803 | /* |
||
18556 | bpr | 4804 | @ trace_jscurve some_math_function |
4805 | @ will use a crosshair to trace the jsmath curve |
||
4806 | @ two inputfields will display the current x/y-values (numerical evaluation by javascript) |
||
4807 | @ default labels ''x`` and ''y``; use commands ''xlabel some_x_axis_name`` and ''ylabel some_y_axis_name`` to customize the labels for the input fields |
||
4808 | @ use commands fontsize and css to format the fonts for labels and inputfields. |
||
4809 | @ use commands ''linewidth, strokecolor, crosshairsize`` to adjust the corsshair. |
||
4810 | @ the client browser will convert your math function to javascript math.<br>use parenthesis and rawmath: use 2*x instead of 2x etc etc no check is done on the validity of your function and/or syntax (use error console to debug any errors...) |
||
4811 | @ be aware that the formulas of the plotted function(s) can be found in the page javascript source |
||
4812 | @%trace_jscurve%size 400,400%xrange -10,10%yrange -10,10%precision 0%axis%axisnumbering%grid 2,2,grey,2,2,5,gray%recision 100%css color:blue;%linewidth 4%crosshairsize 8%trace_jscurve 5*sin(0.1*x^2)%linewidth 1%jsplot red,5*sin(0.1*x^2)%#only one curve can be traced |
||
18552 | bpr | 4813 | */ |
4814 | js_function[INTERACTIVE] = 1; |
||
4815 | js_function[DRAW_CROSSHAIRS] = 1; |
||
4816 | js_function[DRAW_LINES] = 1; |
||
4817 | js_function[JS_MATH] = 1; |
||
4818 | add_trace_js_mouse(TRACE_CANVAS,stroke_color,get_string(infile,1),font_size,stroke_opacity,line_width,crosshair_size,css_class); |
||
4819 | break; |
||
4820 | case TRANGE: |
||
4821 | /* |
||
4822 | @ trange tmin,tmax |
||
4823 | @ alternative: ranget |
||
4824 | @ default -2,2 |
||
4825 | */ |
||
4826 | use_parametric = TRUE; |
||
4827 | for(i = 0 ; i<2; i++){ |
||
4828 | switch(i){ |
||
4829 | case 0: tmin = get_real(infile,0);break; |
||
4830 | case 1: tmax = get_real(infile,1);break; |
||
4831 | default: break; |
||
4832 | } |
||
4833 | } |
||
4834 | if(tmin >= tmax ){canvas_error(" trange is not OK: tmin < tmax!\n");} |
||
4835 | break; |
||
4836 | case TRANSLATION: |
||
4837 | /* |
||
18556 | bpr | 4838 | @ translation tx,ty |
4839 | @ alternative: translate |
||
4840 | @ will translate the next objects tx in xrange and ty in yrange |
||
4841 | @ use command ''killtranstation`` to end the command |
||
18569 | bpr | 4842 | @%translation%size 400,400%xrange -10,10%yrange -10,10%linewidth 1%fillpattern grid%triangle -6,6,8,6,5,1,blue%translation 2,2%ftriangle -6,6,8,6,5,1,red |
18552 | bpr | 4843 | */ |
4844 | for(i = 0 ; i<2;i++){ |
||
4845 | switch(i){ |
||
4846 | case 0: affine_matrix[4] = get_real(infile,0);break; |
||
4847 | case 1: affine_matrix[5] = get_real(infile,1); |
||
4848 | use_affine = TRUE; |
||
4849 | /* the other values affine_matrix[0..3] remain untouched*/ |
||
4850 | break; |
||
4851 | default: break; |
||
4852 | } |
||
4853 | } |
||
4854 | break; |
||
4855 | case TRIANGLE: |
||
4856 | /* |
||
18556 | bpr | 4857 | @ triangle x1,y1,x2,y2,x3,y3,color |
4858 | @ use ftriangle or keyword <a href='#filled'>filled</a> for a solid triangle |
||
4859 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
4860 | @%triangle%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%opacity 250,150%drag xy%triangle 0,0,-4,4,6,8,red%drag xy%ftriangle 0,0,-4,-4,6,-8,red%fillpattern grid%drag xy%ftriangle -6,6,8,6,5,1,blue |
||
18552 | bpr | 4861 | */ |
4862 | for(i=0;i<7;i++){ |
||
4863 | switch(i){ |
||
4864 | case 0: double_data[0] = get_real(infile,0);break; /* x */ |
||
4865 | case 1: double_data[1] = get_real(infile,0);break; /* y */ |
||
4866 | case 2: double_data[2] = get_real(infile,0);break; /* x */ |
||
4867 | case 3: double_data[3] = get_real(infile,0);break; /* y */ |
||
4868 | case 4: double_data[4] = get_real(infile,0);break; /* x */ |
||
4869 | case 5: double_data[5] = get_real(infile,0);break; /* y */ |
||
4870 | case 6: stroke_color = get_color(infile,1);/* name or hex color */ |
||
4871 | decimals = find_number_of_digits(precision); |
||
18623 | bpr | 4872 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 4873 | if( use_rotate == TRUE ){ rotate(6,angle,rotationcenter,2);} |
4874 | if( use_affine == TRUE ){ transform(6,2);} |
||
4875 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 4876 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 4877 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,5,%s,[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,double_xy2js_array(double_data,6,decimals),line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 4878 | add_to_buffer(tmp_buffer); |
4879 | if(onclick != 0){object_cnt++;} |
||
4880 | /* object_cnt++;*/ |
||
4881 | reset(); |
||
4882 | break; |
||
4883 | default: break; |
||
4884 | } |
||
4885 | } |
||
4886 | dragstuff[5] = 1; |
||
4887 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4888 | break; |
||
4889 | case TRIANGLES: |
||
4890 | /* |
||
18556 | bpr | 4891 | @ triangles color,x1,y1,x2,y2,x3,y3,... |
4892 | @ use ftriangles or keyword <a href='#filled'>filled</a> for solid triangles |
||
4893 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
4894 | @%triangles%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%onclick%triangles red,0,0,-4,4,6,8,0,0,-4,-4,6,-8,-6,6,8,6,5,1%# the same as 3 calls to command triangle |
||
18552 | bpr | 4895 | */ |
4896 | stroke_color = get_color(infile,0);/* name or hex color */ |
||
18623 | bpr | 4897 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18552 | bpr | 4898 | i = 0; |
4899 | decimals = find_number_of_digits(precision); |
||
4900 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
4901 | while( ! done ){ |
||
4902 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
4903 | double_data[0] = get_real(infile,0); /* x1 */ |
||
4904 | double_data[1] = get_real(infile,0); /* y1 */ |
||
4905 | double_data[2] = get_real(infile,0); /* x2 */ |
||
4906 | double_data[3] = get_real(infile,0); /* y2 */ |
||
4907 | double_data[4] = get_real(infile,0); /* x3 */ |
||
4908 | double_data[5] = get_real(infile,1); /* y3 */ |
||
18557 | bpr | 4909 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 4910 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,5,%s,[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,double_xy2js_array(double_data,6,decimals),line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 4911 | add_to_buffer(tmp_buffer); |
4912 | if(onclick != 0){object_cnt++;} |
||
4913 | i = i + 6; |
||
4914 | } |
||
4915 | reset(); |
||
4916 | dragstuff[5] = 1; |
||
4917 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
4918 | break; |
||
4919 | case USERBOXPLOT: |
||
4920 | /* |
||
18556 | bpr | 4921 | @ userboxplot |
4922 | @ keyword, no arguments |
||
4923 | @ use before command <a href="#boxplot">boxplot x_or_y,box-height_or_box-width,x_or_y-position</a> |
||
4924 | @ if set, the student will have to calculate "min,Q1,median,Q3,max" and feed these data into the ''draw_boxplot`` function |
||
4925 | @ for example: put the canvas-script into a html element with id='boxplot' and set style='display:none'<br>define a variable called ''student_boxplot`` and fill it with the 5 student-data (from inputfields or something)<br><code>var student_boxplot = new Array(5)<br>function show_boxplot(){<br>student_boxplot[0] = min;<br>student_boxplot[1] = Q1;<br>student_boxplot[2] = median;<br>student_boxplot[3] = Q3;<br>student_boxplot[4] = max;<br>document.getElementById('boxplot').style.display = "block";<br>draw_boxplot(12345,1,2.00,5.00,[0,0,0,0,0],4,"0,0,255",0.78,"255,165,0",0.60,1,0,1,1);<br>};</code><br>In the canvas-script the function draw_boxplot has the following arguments:<br>draw_boxplot=function(canvas_type,xy,hw,cxy,data,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1) |
||
18552 | bpr | 4926 | */ |
4927 | js_function[DRAW_BOXPLOT] = 1; |
||
4928 | fprintf(js_include_file,"var boxplot_source = 3;\n"); |
||
4929 | js_function[DRAW_JSBOXPLOT] = 2; |
||
4930 | break; |
||
4931 | case USERBOXPLOTDATA: |
||
4932 | /* |
||
18556 | bpr | 4933 | @ userboxplotdata |
4934 | @ keyword, no arguments |
||
4935 | @ use before command <a href="#boxplot">boxplot x_or_y,box-height_or_box-width,x_or_y-position</a> |
||
4936 | @ if set, the student will have to generate some statistical data. These data should be put in a named array ''student_boxplot_data`` |
||
4937 | @ ''min,Q1,median,Q3,max`` are calculated by a js-function and the 'draw_boxplot' function will draw a boxplot. |
||
4938 | @ see command <a href="#userboxplot">userboxplot</a> for calling 'draw_boxplot()' |
||
18552 | bpr | 4939 | */ |
4940 | js_function[DRAW_BOXPLOT] = 1; |
||
4941 | fprintf(js_include_file,"var boxplot_source = 2;\n"); |
||
4942 | js_function[DRAW_JSBOXPLOT] = 1; |
||
4943 | break; |
||
4944 | case USERDRAW: |
||
4945 | /* |
||
4946 | @ userdraw object_type,color |
||
4947 | @ only a single object_type is allowed. |
||
4948 | @ right mouse click will remove last drawn object. |
||
4949 | @ for multiple different 'userdraw' objects in an exercise, use command <a href="#multidraw">multidraw</a> |
||
18572 | bpr | 4950 | @ implemented object_type: <ul><li>point</li><li>points</li><li>crosshair</li><li>crosshairs</li><li>line</li><li>lines</li><li>vline</li><li>vlines</li><li>hline</li><li>hlines</li><li>demiline</li><li>demilines</li><li>segment</li><li>segments</li><li>polyline | brokenline</li><li>circle</li><li>circles</li><li>arrow</li><li>arrow2 (double arrow)</li><li>arrows</li><li>arrows2 (double arrows)</li><li>curvedarrow</li><li>curvedarrows</li><li>curvedarrow2</li><li>curvedarrows2</li><li>triangle</li><li>polygon</li><li>poly[3-9] (e.g poly3 ... poly7...poly9</li><li>rect</li><li>roundrect</li><li>rects</li><li>roundrects</li><li>freehandline | path</li><li>freehandlines | paths</li><li>clickfill: fill the clicked area with color<br>multiple areas may be selected <br>multiple colors may be provided using commands <a href='#colorpalette'>colorpalette color1,color2,color3,...</a> use <a href='#replyformat'>replyformat 10</a> for checking the user click color ... reply=x1:y1:color1,x2:y2:color2...<br>attention: this will <b>not</b> work for pattern filling, because the pattern image is only generated once and after creation can not be changed !<br>the opacity of this image on a separate canvas is set to 0.01 and not 0 (!!)...in the ''fill algorithm`` the opacity of the matching pixels is set to 1</li><li>dotfill: fill the clicked area with a dot pattern; use command linewidth to change dot size</li><li>diamondfill: fill the clicked area with a diamond pattern</li><li>hatchfill: fill the clicked area with a hatch pattern</li><li>gridfill: fill the clicked area with a grid pattern</li><li>textfill: fill the clicked area with a repeating string<br>userdraw textfill,blue,some_text<br>use command <a href="#fontfamily">fontfamily</a> to adjust text style and size</li><li>''clickfill | pattern filling`` in general:<br>the clicks may be set <a href="#snaptogrid">snaptogrid</a><br>can be used together with command <a href="#floodfill">floodfill or fill</a><br><b>always</b> use together with command <a href="#clearbutton">clearbutton some_text</a> for removal of all click_colored areas<br>the function read_canvas() will return the click coordinates in the sequence of the user clicks<br>use command <a href="#canvastype">canvastype</a> to fill another canvas (default should be fine: DRAG_CANVAS = 5)</li><li>text <br>an inputfield is provided, unicode allowed. The text is drawn a the mouse click, or if used with command ''userinput inputfield`` also at the given x/y-coordonates</li><li>arc</li><li>arcs</li><li>image<br>only a single "image" of every supported type(*) may be added to canvas window from the surrounding html page.<br>the image should have an 'id' and an onclick handler.<br>(*) supported types are ''svg``,''bitmap``,''p-element``,''div-element`` and ''mathml/tex-code`` with ''\\mmlid{int}``.</li><li>images</li><li>input<br>place a single inputfield on ''canvas`` <br>use commands 'css' for css styling: use command ''linewidth`` for adjusting the input field size (default 1)</li><li>inputs<br>place multiple inputfield: placing inputfields on top of each other is not possible</li><li>function : identical to <a href="#userinput">userinput function</a></li></ul> |
18552 | bpr | 4951 | @ note: mouselisteners are only active if ''$status != done`` (eg only drawing in an active/non-finished exercise) <br> to overrule use command/keyword ''status`` (no arguments required) |
4952 | @ note: object_type text: Any string or multiple strings may be placed anywhere on the canvas.<br>Use command ''fontfamily`` to set font |
||
4953 | @ note: object_type polygone: Will be finished (the object is closed) when clicked on the first point of the polygone again. |
||
4954 | @ note: all objects will be removed -after a javascript confirm box- when clicked on an object point with middle or right mouse button (e.g. event.button != 1: all buttons but left) |
||
18572 | bpr | 4955 | @ use a prefix <a href='#filled'>filled</a> or ''f`` to set fillable objects filled. (fcircles,filledcircles etc)<br> in case of ''fillpattern`` do not use the ''f`` prefix ! |
18552 | bpr | 4956 | @ for non solid filling, use command <a href="#fillpattern">fillpattern grid,hatch,diamond,dot</a> |
4957 | @ use <a href='#opacity'>opacity int,int</a> and <a href='#fillcolor'>fillcolor color</a> to trigger coloured filling of fillable objects |
||
4958 | @ use command ''dashed`` and/or ''dashtype int,int`` to trigger dashing |
||
4959 | @ use command ''replyformat int`` to control / adjust output formatting of javascript function read_canvas(); (the defaults should be fine...) |
||
4960 | @ may be combined with onclick or drag xy of other components of flyscript objects (although not very useful...) |
||
4961 | @ may be combined with keyword <a href='#userinput_xy'>userinput_xy</a> |
||
4962 | @ may be combined width the <a href='#snaptogrid'>snaptogrid snaptopoints </a> etc, to simplify the checking of the student reply |
||
4963 | @ the cursor may be appropriately styled using command <a href='cursor'>cursor</a> |
||
4964 | @ note: when zooming / panning after a drawing, the drawing will NOT be zoomed / panned...this is a "design" flaw and not a feature <br>To avoid trouble do not use zooming / panning together width userdraw.!<br>use command <a href="#multidraw">multidraw</a> is this is a problem for you... |
||
4965 | @ note: the default replyformat for ''userdraw input(s),color`` used format x1;y1;text1 \n x2;y2;test2 \n x_n;y_n;text_n (e.g. it is not a comma separated array...use ''direct exec`` to test) |
||
4966 | @ note: a special case is ''userdraw image,boguscolor``. Images (bitmap or svg or div) present in the exercise page and the img/svg/div-tag with an unique 'id' and <code>onclick='javascript:place_image_on_canvas(this.id)'</code> can be placed onto the canvas.<br>The ''id`` and (x;y) coordinates will be returned using read_canvas();<br> native MathML, MathJax or KaTeX typesetting may be included in div's.(experiments; wims_modules svn version only!) |
||
4967 | @ note: command <br><code>userdraw function,color</code> is identical to acombination of <code>strokecolor color</code> and <code>userinput function</code><br> |
||
18572 | bpr | 4968 | @ note: commands :<br><code>multicolors red,green,blue<br>multilabel f(x)=:g(x)=:h(x)=<br>userdraw functions3,color</code><br>is identical to commands :<br><code>functionlabel f(x)=:p(x)=:w(x)=<br>strokecolor red<br>userinput function <br>strokecolor green<br>userinput function <br>strokecolor blue<br>userinput function</code> |
18552 | bpr | 4969 | @%userdraw_canvastype_a%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%grid 2,2,grey%replyformat 10%colorpalette orange,yellow,red,green,lightgreen,blue,lightblue,cyan%canvastype 4%userdraw clickfill,blue%clearbutton REMOVE LAST RECTANGLE |
4970 | @%userdraw_canvastype_b%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%canvastype 4%snaptogrid%replyformat 10%userdraw dotfill,blue%clearbutton REMOVE LAST RECTANGLE |
||
4971 | @%userdraw_rect%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw rect,green |
||
4972 | @%userdraw_rects%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw rects,green |
||
4973 | @%userdraw_frect%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw frect,green |
||
18635 | bpr | 4974 | @%userdraw_frects%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw rects,green |
4975 | @%userdraw_roundrect%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw roundrect,green |
||
4976 | @%userdraw_roundrects%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw roundrects,green |
||
4977 | @%userdraw_froundrect%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw roundrect,green |
||
4978 | @%userdraw_froundrects%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw roundrects,green |
||
18552 | bpr | 4979 | @%userdraw_line%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw line,green |
4980 | @%userdraw_lines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw lines,green |
||
4981 | @%userdraw_vline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw vline,green |
||
4982 | @%userdraw_vlines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw vlines,green |
||
4983 | @%userdraw_hline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw hline,green |
||
4984 | @%userdraw_hlines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw hlines,green |
||
4985 | @%userdraw_demiline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw demiline,green |
||
4986 | @%userdraw_demilines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw demilines,green |
||
4987 | @%userdraw_arc%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw arc,green |
||
4988 | @%userdraw_arcs%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw arcs,green |
||
4989 | @%userdraw_point%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw point,green |
||
4990 | @%userdraw_points%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw points,green |
||
4991 | @%userdraw_arrow%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw arrow,green |
||
4992 | @%userdraw_arrows%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw arrows,green |
||
4993 | @%userdraw_arrow2%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw arrow2,green |
||
4994 | @%userdraw_arrows2%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw arrows2,green |
||
4995 | @%userdraw_curvedarrow%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 1%linewidth 3%userdraw curvedarrow,red%clearbutton REMOVE ALL ARROWS |
||
4996 | @%userdraw_curvedarrows%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 1%linewidth 3%userdraw curvedarrows,red%clearbutton REMOVE ALL ARROWS |
||
4997 | @%userdraw_curvedarrow2%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 1%linewidth 3%userdraw curvedarrow2,red%clearbutton REMOVE ALL ARROWS |
||
4998 | @%userdraw_curvedarrows2%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%precision 1%linewidth 3%userdraw curvedarrows2,red%clearbutton REMOVE ALL ARROWS |
||
4999 | @%userdraw_crosshair%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw crosshair,green |
||
5000 | @%userdraw_crosshairs%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw crosshairs,green |
||
18635 | bpr | 5001 | @%userdraw_circle%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw circle,green |
5002 | @%userdraw_circles%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw circles,green |
||
18552 | bpr | 5003 | @%userdraw_segment%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw segment,green |
5004 | @%userdraw_segments%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw segments,green |
||
5005 | @%userdraw_line%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw line,green |
||
5006 | @%userdraw_lines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw lines,green |
||
18635 | bpr | 5007 | @%userdraw_triangle%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%filled%opacity 200,50%userdraw triangle,green |
5008 | @%userdraw_poly5%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw poly5,green |
||
18552 | bpr | 5009 | @%userdraw_filled_poly5%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%filled%userdraw poly5,green |
5010 | @%userdraw_poly7%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%userdraw poly7,green |
||
5011 | @%userdraw_filled_poly7%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%filled%userdraw poly7,green |
||
18635 | bpr | 5012 | @%userdraw_polyline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw polyline,green |
18552 | bpr | 5013 | @%userdraw_freehandline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw freehandline,green |
5014 | @%userdraw_filled_freehandline%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%fillcolor orange%opacity 200,50%filled%userdraw freehandline,green |
||
5015 | @%userdraw_freehandlines%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%opacity 200,50%userdraw freehandlines,green |
||
5016 | @%userdraw_input%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%userdraw input,green |
||
5017 | @%userdraw_inputs%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%userdraw inputs,green |
||
5018 | @%userdraw_text%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%fontfamily 42px Courier%userdraw text,green |
||
5019 | @%userdraw_function%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 1%grid 2,2,grey,2,2,5,grey%multicolors orange,red,green,blue,cyan%precision 1000%userdraw functions3,red%jscurve blue,x^2,-x^2,5*cos(x)%precision 1%mouse red,22 |
||
5020 | @%userdraw_clickfill_colorpalette%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%circles blue,0,0,4,1,1,6,3,3,3,-3,-3,5%opacity 255,120%colorpalette red,green,yellow,blue%userdraw clickfill,green |
||
5021 | @%userdraw_clickfill_1%size 400,400%xrange -10,10%yrange -10,10%linewidth 3%circles blue,0,0,4,1,1,6,3,3,3,-3,-3,5%opacity 255,120%userdraw clickfill,green |
||
18609 | bpr | 5022 | @%userdraw_clickfill_2%size 400,400%xrange -10,10%yrange -10,10%circles blue,0,0,2,1,1,5,5,5,4,-5,5,6,5,-5,6%userdraw hatchfill,red%#userdraw dotfill,red%#userdraw diamondfill,red%#userdraw gridfill,red |
18552 | bpr | 5023 | @%userdraw_clickfill_2%size 400,400%xrange -10,10%yrange -10,10%bgcolor white%# to get nice click coordinates take invisible ''grid`` and use ''snaptogrid`` %grid 1,1,white%snaptogrid%circles blue,0,0,2,1,1,5,5,5,4,-5,5,6,5,-5,6%userdraw gridfill,red |
5024 | */ |
||
5025 | if( use_userdraw != 0 ){ /* only one object type may be drawn*/ |
||
5026 | canvas_error("Only one userdraw primitive may be used in command 'userdraw' use command 'multidraw' for this..."); |
||
5027 | } |
||
5028 | js_function[INTERACTIVE] = 1; |
||
5029 | draw_type = get_string_argument(infile,0); |
||
5030 | if( strcmp(draw_type,"textfill") == 0){ |
||
5031 | fprintf(js_include_file,"var userdraw_text_string = \"%s\";", get_string(infile,1)); |
||
5032 | } |
||
5033 | else { |
||
5034 | if( strcmp(draw_type,"imagefill") == 0){ |
||
5035 | fprintf(js_include_file,"var userdraw_image_url = \"%s\";", get_string(infile,1)); |
||
5036 | } |
||
5037 | else { |
||
5038 | stroke_color = get_color(infile,1); |
||
5039 | } |
||
5040 | } |
||
5041 | if( strcmp(draw_type,"clickfill") == 0){use_filled = 1;fill_color = stroke_color;} |
||
5042 | reply_precision = precision; |
||
5043 | use_userdraw = 1; |
||
5044 | fprintf(js_include_file,"\n\ |
||
15111 | schaersvoo | 5045 | /* begin userdraw */\ |
5046 | userdraw_x = new Array();userdraw_y = new Array();userdraw_radius = new Array();\ |
||
5047 | var forbidden_zone=[xsize+1,ysize+1];var xy_cnt = 0;\ |
||
5048 | var canvas_userdraw = create_canvas%d(%d,xsize,ysize);\ |
||
5049 | var context_userdraw = canvas_userdraw.getContext(\"2d\");\ |
||
5050 | var use_dashed = %d;\ |
||
5051 | var use_snap = %d;if(use_dashed == 1){if( context_userdraw.setLineDash ){context_userdraw.setLineDash([%d,%d]);}else{if(context_userdraw.mozDash){context_userdraw.mozDash = [%d,%d];};};};\ |
||
5052 | context_userdraw.lineWidth = %d;var use_filled = %d;\ |
||
5053 | context_userdraw.strokeStyle = \"rgba(%s,%.2f)\";\ |
||
5054 | context_userdraw.font = \"%s\";\ |
||
15128 | schaersvoo | 5055 | var user_is_dragging = false;\ |
15111 | schaersvoo | 5056 | if(wims_status != \"done\"){\ |
5057 | canvas_div.addEventListener(\"mousedown\" ,user_draw,false);\ |
||
5058 | canvas_div.addEventListener(\"mousemove\" ,user_drag,false);\ |
||
5059 | canvas_div.addEventListener(\"touchstart\",function(e){ e.preventDefault();user_draw(e.changedTouches[0]);},false);\ |
||
5060 | canvas_div.addEventListener(\"touchmove\" ,function(e){ e.preventDefault();user_drag(e.changedTouches[0]);},false);\ |
||
15128 | schaersvoo | 5061 | canvas_div.addEventListener(\"touchend\" ,function(e){ e.preventDefault();user_drawstop(e.changedTouches[0]);},false);\ |
15111 | schaersvoo | 5062 | };",canvas_root_id,DRAW_CANVAS,use_dashed,use_snap,dashtype[0],dashtype[1],dashtype[0],dashtype[1],line_width,use_filled,stroke_color,stroke_opacity,font_family); |
5063 | |||
18552 | bpr | 5064 | if( use_filled == 0 ){ |
5065 | fprintf(js_include_file,"context_userdraw.fillStyle = \"rgba(255,255,255.0)\";"); |
||
5066 | } |
||
5067 | else { |
||
5068 | if( use_filled == 1 ){ |
||
5069 | fprintf(js_include_file,"context_userdraw.fillStyle = \"rgba(%s,%.2f)\";",fill_color,fill_opacity); |
||
5070 | } |
||
5071 | else { |
||
5072 | js_function[DRAW_FILL_PATTERN] = 1; |
||
5073 | fprintf(js_include_file,"context_userdraw.fillStyle = create_Pattern(0,0,%d,[%s]);\n",use_filled,fill_color); |
||
5074 | } |
||
5075 | } |
||
5076 | add_js_userdraw(draw_type,stroke_color,stroke_opacity,crosshair_size,arrow_head,use_offset,css_class,use_snap,canvas_type,use_filled,fill_color,fill_opacity,line_width,font_family); |
||
5077 | reset(); |
||
5078 | break; |
||
5079 | case USERINPUT: |
||
5080 | /* |
||
18556 | bpr | 5081 | @ userinput function inputfield |
5082 | @ alternative: userinput_function |
||
5083 | @ alternative: userinput_xy |
||
5084 | @ ''inputfield`` is only usable in combination with some ''userdraw draw_type`` |
||
5085 | @ note: the input fields are not cleared after the object is drawn...be aware of multiple idential drawings (many clicks on the ''ok`` button) |
||
5086 | @ ''userinput function`` may be used any time (e.g. without userdraw) |
||
5087 | @ multiple ''userinput function`` commands may be used. |
||
5088 | @ use command <code>functionlabel some_string</code> to define the inputfield text: default value "f(x)=" |
||
5089 | @ use command <code>strokecolor some_color</code> to adjust the plot / functionlabel color |
||
5090 | @ use command <code>css some_css</code> to adjust the inputfields |
||
5091 | @ use command <code>fontsize int</code> to adjust the label fonts. (default 12px) |
||
5092 | @ the user input for the function will be corrected by a simple ''rawmath`` implementation...<br>an error message will be shown if javascript can not interpret the user input |
||
5093 | @%userinput_function%size 400,400%xrange -10,10%yrange -10,10%functionlabel your function g(x)=%axis%axisnumbering%xlabel x-axis%ylabel y-axis%grid 2,2,grey,3,3,5,grey%css color:blue;text-align:center%userinput function%# note: number of function inputs not limited |
||
5094 | @%userinput_points%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%# adding 2 inputfields for x and y%userinput inputfield%userdraw points,blue |
||
5095 | @%userinput_arrows%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%#adding 4 inputfields for (x1;y1)---(x2;y2)%userinput inputfieldd%userdraw arrows,blue |
||
5096 | @%userinput_combined%size 400,400%xrange -10,10%yrange -10,10%functionlabel your function g(x)=%axis%axisnumbering%xlabel x-axis%ylabel y-axis%precision 0%grid 2,2,grey,3,3,5,grey%css color:blue;text-align:center%precision 1000%strokecolor red%opacity 255,255%userinput function%# note: number of function inputs not limited%userdraw line,blue |
||
18552 | bpr | 5097 | */ |
5098 | temp = get_string_argument(infile,1); |
||
5099 | if(strstr(temp,"function") != 0 || strstr(temp,"curve") != 0 || strstr(temp,"plot") != 0 ){ |
||
5100 | if( js_function[DRAW_JSFUNCTION] != 1 ){ |
||
5101 | js_function[JS_RAWMATH] = 1; |
||
5102 | js_function[DRAW_JSFUNCTION] = 1; |
||
5103 | if(reply_format == 0){reply_format = 24;}/* read canvas_input values */ |
||
5104 | add_input_jsfunction(css_class,function_label,input_cnt,stroke_color,stroke_opacity,line_width,use_dashed,dashtype[0],dashtype[1],font_size); |
||
5105 | input_cnt++; |
||
5106 | } |
||
5107 | else { |
||
5108 | /* no need to add DRAW_JSFUNCTION, just call it with the parameters */ |
||
5109 | fprintf(js_include_file,"add_input_jsfunction(%d,\"%s\",%s,%d,\"%s\",\"%.2f\",%d,%d,%d,%d);\n",input_cnt,css_class,function_label,line_width,stroke_color,stroke_opacity,use_dashed,dashtype[0],dashtype[1],font_size); |
||
5110 | input_cnt++; |
||
5111 | } |
||
5112 | js_function[JS_MATH] = 1; |
||
5113 | js_function[JS_PLOT] = 1; |
||
5114 | } |
||
5115 | else { |
||
5116 | if(strstr(temp,"inputfield") != 0 ){ |
||
5117 | js_function[JS_SAFE_EVAL] = 1; |
||
5118 | js_function[ADD_USER_INPUTS] = 1; |
||
5119 | } |
||
5120 | else { |
||
5121 | canvas_error("userinput argument may be \"function\" or \"inputfield\""); |
||
5122 | } |
||
5123 | } |
||
5124 | break; |
||
5125 | case USERINPUT_XY: |
||
5126 | /* |
||
5127 | @ userinput_xy |
||
5128 | @ keyword (no arguments required) |
||
5129 | @ to be used in combination with command "userdraw object_type,color" |
||
5130 | @ if set two (or three) input fields are added to the document<br>(one for x-values, one for y-values and in case of drawing circle one for radius-values) |
||
5131 | @ the student may use this as correction for (x:y) on a drawing (or to draw without mouse, using just the coordinates) |
||
5132 | @ math input is allowed (e.g something like: 1+3,2*6,1/3,sqrt(3), sin(pi/4),10^-2,log(2)...)<br>eval function is ''protected`` against code injection. |
||
5133 | @ can <b>not</b> be combined with command ''intooltip tiptext`` <br>note: the ''tooltip div element`` is used for placing inputfields |
||
5134 | @ user drawings will not zoom on zooming (or pan on panning) |
||
5135 | @ use command ''css some_css`` to adjust the inputarea. |
||
5136 | @ use command ''fontsize int`` to adjust the text labels (if needed) |
||
5137 | @%userinput_xy%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%precision 0%grid 2,2,grey,3,3,6,black%# provides inputfields for (x1:y1)---(x2:y2)%userinput_xy%linewidth 2%precision 1000%userdraw lines,blue |
||
5138 | */ |
||
5139 | /* add simple eval check to avoid code injection with unprotected eval(string) */ |
||
5140 | js_function[JS_SAFE_EVAL] = 1; |
||
5141 | js_function[ADD_USER_INPUTS] = 1; |
||
5142 | break; |
||
5143 | case USERINPUT_FUNCTION: |
||
5144 | /* |
||
5145 | @ userinput_function |
||
5146 | @ alternative: userinput |
||
5147 | @ keyword (no arguments required) |
||
5148 | @ if set, a inputfield will be added to the page |
||
5149 | @ repeat keyword for more function input fields |
||
5150 | @ the userinput value will be plotted in the canvas |
||
5151 | @ this value may be read with <code>read_canvas()</code>. <br>for do it yourself js-scripters: If this is the first inputfield in the script, its id is canvas_input0 |
||
5152 | @ use before this command ''userinput_function``,<br>commands like ''css some_css``, ''xlabel some_description``, ''opacity int,int``, ''linewidth int``, ''dashed`` and ''dashtype int,int`` to modify |
||
5153 | @ fontsize can be set using command ''fontsize int`` |
||
5154 | @ incompatible with command ''intooltip link_text_or_image``: it uses the tooltip div for adding the inputfield |
||
5155 | @%userinput_function%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%xlabel x-axis%ylabel y-axis%precision 0%grid 2,2,grey,2,2,5,grey%precision 1000%linewidth 2%# first inputfield%css color:blue;text-align:center;font-family:Italic;%strokecolor blue%functionlabel g(x)=:p(x)=:k(x)=%userinput function%# second inputfield%css color:green;text-align:center;font-family:Italic;%strokecolor green%userinput function%# third inputfield%css color:purple;text-align:center;font-family:Italic;%strokecolor purple%userinput function%# no limit in number of function inputfields |
||
5156 | */ |
||
5157 | if( js_function[DRAW_JSFUNCTION] != 1 ){ |
||
5158 | js_function[DRAW_JSFUNCTION] = 1; |
||
5159 | js_function[JS_RAWMATH] = 1; |
||
5160 | if(reply_format == 0){reply_format = 24;}/* read canvas_input values */ |
||
5161 | add_input_jsfunction(css_class,function_label,input_cnt,stroke_color,stroke_opacity,line_width,use_dashed,dashtype[0],dashtype[1],font_size); |
||
5162 | input_cnt++; |
||
5163 | } |
||
5164 | else { |
||
5165 | /* no need to add DRAW_JSFUNCTION, just call it with the parameters */ |
||
5166 | fprintf(js_include_file,"add_input_jsfunction(%d,\"%s\",%s,%d,\"%s\",\"%.2f\",%d,%d,%d,%d);\n",input_cnt,css_class,function_label,line_width,stroke_color,stroke_opacity,use_dashed,dashtype[0],dashtype[1],font_size); |
||
5167 | input_cnt++; |
||
5168 | } |
||
5169 | js_function[JS_MATH] = 1; |
||
5170 | js_function[JS_PLOT] = 1; |
||
5171 | break; |
||
5172 | case VLINE: |
||
5173 | /* |
||
5174 | @ vline x,y,color |
||
5175 | @ alternative: verticalline |
||
5176 | @ draw a vertical line through point (x:y) in color 'color' |
||
5177 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
5178 | @%vline%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%vline 0,0,red%onclick%vline 1,0,orange%onclick%vline 2,0,blue%onclick%vline 3,0,green |
||
5179 | */ |
||
5180 | for(i=0;i<3;i++) { |
||
5181 | switch(i){ |
||
5182 | case 0: double_data[0] = get_real(infile,0);break; /* x-values */ |
||
5183 | case 1: double_data[1] = get_real(infile,0);break; /* y-values */ |
||
5184 | case 2: stroke_color=get_color(infile,1);/* name or hex color */ |
||
5185 | double_data[2] = double_data[0]; |
||
5186 | decimals = find_number_of_digits(precision); |
||
5187 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18557 | bpr | 5188 | tmp_buffer=my_newmem(MAX_BUFFER); |
5189 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[2],decimals,100*ymin,decimals,100*ymax,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 5190 | add_to_buffer(tmp_buffer); |
5191 | if(onclick != 0){object_cnt++;} |
||
5192 | /* object_cnt++; */ |
||
5193 | reset(); |
||
5194 | break; |
||
5195 | } |
||
5196 | } |
||
5197 | dragstuff[4] = 1; |
||
5198 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5199 | break; |
||
5200 | case VLINES: |
||
5201 | /* |
||
5202 | @ vlines color,x1,y1,x2,y2.... |
||
5203 | @ alternative: verticallines |
||
5204 | @ draw vertical lines through points (x1:y1),(x2:y2)... in color 'color' |
||
5205 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually |
||
5206 | @%vlines%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%vlines red,1,0,2,0,3,0,4,0 |
||
5207 | */ |
||
5208 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
5209 | fill_color = stroke_color; |
||
5210 | i=0; |
||
5211 | while( ! done ){ /* get next item until EOL*/ |
||
5212 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
5213 | if(i%2 == 0 ){ |
||
5214 | double_data[i] = get_real(infile,0); /* x */ |
||
5215 | } |
||
5216 | else { |
||
5217 | double_data[i] = get_real(infile,1); /* y */ |
||
5218 | } |
||
5219 | i++; |
||
5220 | } |
||
5221 | decimals = find_number_of_digits(precision); |
||
5222 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5223 | for(c = 0 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 5224 | tmp_buffer=my_newmem(MAX_BUFFER); |
18607 | bpr | 5225 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[0],[0],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c],decimals,100*ymin,decimals,100*ymax,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18552 | bpr | 5226 | add_to_buffer(tmp_buffer); |
5227 | if(onclick != 0){object_cnt++;} |
||
5228 | /* object_cnt++; */ |
||
5229 | } |
||
5230 | reset(); |
||
5231 | dragstuff[4] = 1; |
||
5232 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5233 | break; |
||
5234 | case VIDEO: |
||
5235 | /* |
||
5236 | @ video x,y,w,h,videofile location |
||
5237 | @ x,y: left top corner of audio element (in xrange / yrange) |
||
5238 | @ w,y: width and height in pixels |
||
5239 | @ video format may be in *.mp4 (todo: other formats) |
||
5240 | @%video%size 400,400%xrange -10,10%yrange -10,10%opacity 200,100%frect -9,9,6,-6,green%video -5,5,200,200,http://techslides.com/demos/sample-videos/small.mp4 |
||
5241 | */ |
||
5242 | js_function[DRAW_VIDEO] = 1; |
||
5243 | for(i=0;i<5;i++){ |
||
5244 | switch(i){ |
||
5245 | case 0: int_data[0] = x2px(get_real(infile,0)); break; /* x in x/y-range coord system -> pixel */ |
||
5246 | case 1: int_data[1] = y2px(get_real(infile,0)); break; /* y in x/y-range coord system -> pixel */ |
||
5247 | case 2: int_data[2] = (int) (get_real(infile,0)); break; /* pixel width */ |
||
5248 | case 3: int_data[3] = (int) (get_real(infile,0)); break; /* height pixel height */ |
||
5249 | case 4: temp = get_string(infile,1); |
||
18557 | bpr | 5250 | tmp_buffer=my_newmem(MAX_BUFFER); |
5251 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_video(%d,%d,%d,%d,%d,\"%s\");\n",canvas_root_id,int_data[0],int_data[1],int_data[2],int_data[3],temp)); |
||
18552 | bpr | 5252 | add_to_buffer(tmp_buffer); |
5253 | break; |
||
5254 | default:break; |
||
5255 | } |
||
5256 | } |
||
5257 | reset(); |
||
5258 | break; |
||
5259 | case X_AXIS_STRINGS: |
||
5260 | /* |
||
18556 | bpr | 5261 | @ xaxis num1:string1:num2:string2:num3:string3:num4:string4:....num_n:string_n |
5262 | @ alternative: xaxistext |
||
5263 | @ usable for commands <a href="#numberline">numberline</a> and <a href="#grid">grid</a> or combinations thereof |
||
5264 | @ use these x-axis num1...num_n values instead of default xmin...xmax |
||
5265 | @ in case of command ''grid``. there is no need to use keyword <a href="#axisnumbering">axisnumbering</a> |
||
5266 | @ use command <a href="#axis">axis</a> to have visual x/y-axis lines (see command <a href="#grid">grid</a> |
||
5267 | @ use command ''fontcolor``, ''fontfamily`` to adjust font <br>defaults: black,12,Arial<br>note: command ''fontsize`` is not active for this command.(''fontsize`` can be used for the <a href="#legend">legend</a> in a <a href="#grid">grid</a>) |
||
5268 | @ a javascript error message will flag non-matching value:name pairs |
||
5269 | @ if the ''x-axis words`` are too big and will overlap, a simple alternating offset will be applied |
||
5270 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
5271 | @ ''xmajor`` steps should be synchronised with numbers eg. ''1`` in the next example <code>grid 1,100,grey,1,4,6,grey</code> |
||
5272 | @%xaxistext%size 800,200%xrange -1,13%yrange -5,10%axis%xaxistext 1:january:2:february:3:march:4:april:5:may:6:june:7:july:8:august:9:september:10:october:11:november:12:december%grid 1,4,grey,1,2,10,red |
||
18552 | bpr | 5273 | */ |
5274 | use_axis_numbering++; |
||
5275 | temp = get_string(infile,1); |
||
5276 | if( strstr(temp,":") != 0 ){ temp = str_replace(temp,":","\",\"");} |
||
5277 | if( strstr(temp,"pi") != 0 ){ temp = str_replace(temp,"pi","(3.1415927)");}/* we need to replace pi for javascript y-value*/ |
||
5278 | fprintf(js_include_file,"x_strings[%d] = [\"%s\"];x_strings_up[%d] = null;",use_axis_numbering,temp,use_axis_numbering); |
||
5279 | break; |
||
5280 | case X_AXIS_STRINGS_UP: |
||
5281 | /* |
||
18556 | bpr | 5282 | @ xaxisup num1:string1:num2:string2:num3:string3:num4:string4:....num_n:string_n |
5283 | @ alternative: xaxistextup |
||
5284 | @ the text will be rotated 90° up |
||
5285 | @ no need to use keyword <a href="#axisnumbering">axisnumbering</a> |
||
5286 | @ use command <a href="#axis">axis</a> to have visual x/y-axis lines (see command <a href="#grid">grid</a> |
||
5287 | @ use these x-axis num1...num_n values instead of default xmin...xmax |
||
5288 | @ use command ''fontcolor``, <a href="#fontfamily">fontfamily</a> to adjust font <br>defaults: black,12,Arial<br>note: command ''fontsize`` is not active for this command.(''fontsize`` can be used for the <a href="#legend">legend</a> in a <a href="#grid">grid</a>) |
||
5289 | @ a javascript error message will flag non-matching value:name pairs |
||
5290 | @ if the ''x-axis words`` are too big, they will overlap the graph<br> (in this case the text will start from ysize upwards) |
||
5291 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
5292 | @''xmajor`` steps should be synchronised with numbers eg. "1" in the next example <code>grid 1,100,grey,1,4,6,grey</code> |
||
5293 | @%xaxistextup%size 800,300%xrange -1,13%yrange -10,10%fontfamily Italic 18pt Courier%axis%xaxistextup 1:january:2:february:3:march:4:april:5:may:6:june:7:july:8:august:9:september:10:october:11:november:12:december%grid 1,4,grey,1,2,10,red |
||
18552 | bpr | 5294 | */ |
5295 | use_axis_numbering++; |
||
5296 | temp = get_string(infile,1); |
||
5297 | if( strstr(temp,":") != 0 ){ temp = str_replace(temp,":","\",\"");} |
||
5298 | if( strstr(temp,"pi") != 0 ){ temp = str_replace(temp,"pi","(3.1415927)");}/* we need to replace pi for javascript y-value*/ |
||
5299 | fprintf(js_include_file,"x_strings_up[%d] = 1;x_strings[%d] = [\"%s\"];",use_axis_numbering,use_axis_numbering,temp); |
||
5300 | break; |
||
5301 | case XERRORBARS: |
||
5302 | /* |
||
5303 | @ xerrorbars color,E1,E2,x1,y1,x2,y2,...,x_n,y_n |
||
5304 | @ draw multiple points with x-errorbars E1 (error value left from point) and E2 (error value right from point) at given coordinates in color 'color' |
||
5305 | @ the errors E1 and E2 values are in xrange. |
||
5306 | @ use command ''linewidth int`` to adust size |
||
5307 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
5308 | @%xerrorbars%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%drag xy%xerrorbars red,0.8,1.3,0,0,1,1,2,3,3,2,4,5,5,2,6,1,-1,-2,-2,0,-3,2,-4,4,-5,-1 |
||
8386 | schaersvoo | 5309 | |
18552 | bpr | 5310 | */ |
5311 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
5312 | fill_color = stroke_color; |
||
5313 | i=0; |
||
5314 | while( ! done ){ /* get next item until EOL*/ |
||
5315 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
5316 | if(i%2 == 0 ){ |
||
5317 | double_data[i] = get_real(infile,0); /* x */ |
||
5318 | } |
||
5319 | else { |
||
5320 | double_data[i] = get_real(infile,1); /* y */ |
||
5321 | } |
||
5322 | i++; |
||
5323 | } |
||
5324 | decimals = find_number_of_digits(precision); |
||
5325 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5326 | for(c = 2 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 5327 | tmp_buffer=my_newmem(MAX_BUFFER); |
5328 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,20,[%.*f],[%.*f],[%.2f],[%.2f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],double_data[0],double_data[1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,1,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18552 | bpr | 5329 | add_to_buffer(tmp_buffer); |
5330 | /* object_cnt++; */ |
||
5331 | if(onclick != 0){object_cnt++;} |
||
5332 | } |
||
5333 | reset(); |
||
5334 | dragstuff[20] = 1; |
||
5335 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5336 | break; |
||
5337 | case NEWRANGE: |
||
5338 | /* |
||
5339 | @ newrange xmin,xmax,ymin,ymax |
||
5340 | @ objects defined after command will make use of this new range |
||
5341 | @ https://wimsedu.info/?topic=dessiner-des-portions-de-fonctions-sur-un-meme-graphe |
||
5342 | */ |
||
5343 | for(i = 0 ; i<4; i++){ |
||
5344 | switch(i){ |
||
5345 | case 0: xmin = get_real(infile,0);break; |
||
5346 | case 1: xmax = get_real(infile,0);break; |
||
5347 | case 2: ymin = get_real(infile,0);break; |
||
5348 | case 3: ymax = get_real(infile,1);break; |
||
5349 | default: break; |
||
5350 | } |
||
5351 | } |
||
18557 | bpr | 5352 | tmp_buffer=my_newmem(MAX_BUFFER); |
5353 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "\n\nxmin = %f;xmax = %f;ymin = %f;ymax = %f;\n\n",xmin,xmax,ymin,ymax)); |
||
18552 | bpr | 5354 | add_to_buffer(tmp_buffer); |
5355 | break; |
||
5356 | case XRANGE: |
||
5357 | /* |
||
5358 | @ xrange xmin,xmax |
||
5359 | @ alternative: rangex |
||
5360 | @ if not given: 0,xsize (eg in pixels) |
||
5361 | */ |
||
18556 | bpr | 5362 | for(i = 0 ; i<2; i++){ |
5363 | switch(i){ |
||
5364 | case 0: xmin = get_real(infile,0);break; |
||
5365 | case 1: xmax = get_real(infile,1);break; |
||
5366 | default: break; |
||
5367 | } |
||
5368 | } |
||
5369 | if(xmin >= xmax){canvas_error(" xrange is not OK: xmin < xmax !");} |
||
5370 | fprintf(js_include_file,"var xmin = %f;var xmax = %f;",xmin,xmax); |
||
5371 | found_size_command++; |
||
5372 | break; |
||
18552 | bpr | 5373 | case XSNAPTOGRID: |
5374 | /* |
||
18556 | bpr | 5375 | @ xsnaptogrid |
5376 | @ keyword (no arguments required) |
||
5377 | @ a draggable object (use command ''drag x|y|xy``) will snap to the given x-grid values when dragged (mouseup) |
||
5378 | @ in case of userdraw the drawn points will snap to xmajor grid |
||
5379 | @ if no grid is defined, points will snap to every integer xrange value. (eg snap_x=1) |
||
5380 | @ if you do not want a visible grid, but you only want a ''snaptogrid`` with some value...define this grid with opacity 0. |
||
5381 | @ if xminor is defined (use keyword ''axis`` to activate xminor), the drawing will snap to xminor <br>use only even dividers in x-minor...for example<br><code>xsnaptogrid<br>axis<br>grid 2,1,grey,4,4,7,red</code><br> will snap on x=0, x=0.5, x=1, x=1.5 ....<br> will snap on y=0, y=0.25 y=0.5 y=0.75 ...<br> |
||
5382 | @%xsnaptogrid_1%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 2%xsnaptogrid%userdraw segments,red%precision 1%display x,red,12 |
||
5383 | @%xsnaptogrid_2%size 400,400%xrange -10,10%yrange -10,10%grid 1,1,grey%linewidth 3%drag x%points red,0,0,0,0,0,0,0,0,0,0 |
||
5384 | */ |
||
5385 | use_snap = 2; |
||
5386 | break; |
||
18552 | bpr | 5387 | case XOFFSET: |
5388 | /* |
||
18556 | bpr | 5389 | @ xoffset |
5390 | @ keyword ; to place the text centered above the text coordinates(x:y) ... |
||
5391 | @ may be used for points or other things requiring centered labels |
||
5392 | @ use <a href="#fontfamily">fontfamily</a> for setting the font |
||
5393 | @ may be active for commands <a href="#text">text</a> and <a href="#string">string</a> (e.g. objects in the drag/drop/onclick-library) |
||
18552 | bpr | 5394 | @%xoffset%size 400,400%xrange -10,10%yrange -10,10%fontfamily 12pt Arial%string blue,-9,-9,no offset%point -9,-9,red%centered%string blue,-6,-6,centered%point -6,-6,red%xoffset%string blue,-3,-3,xoffset%point -3,-3,red%yoffset%string blue,0,0,yoffset%point 0,0,red%xyoffset%string blue,3,3,xyoffset%point 3,3,red%resetoffset%string blue,6,6,resetoffset%point 6,6,red |
5395 | */ |
||
18556 | bpr | 5396 | use_offset = 2; |
5397 | break; |
||
18552 | bpr | 5398 | case XYOFFSET: |
5399 | /* |
||
18556 | bpr | 5400 | @ xyoffset |
5401 | @ keyword ; to place the text (x:y) to (x+dx:y+dy)... dx/dy are dependent on fontsize/fontfamily |
||
5402 | @ may be used for points or other things requiring labels |
||
5403 | @ use <a href="#fontfamily">fontfamily</a> for setting the font |
||
5404 | @ only active for commands <a href="#text">text</a> and <a href="#string">string</a> (e.g. objects in the drag/drop/onclick-librariy |
||
5405 | @ in case of inputfields the inputfield will be centered x and y on its coordinates.<br>for example:<br>inputs 1,1,10,? <br>point 1,1,red <br> the point will be completely invisible<br>note: keyword ''xyoffset`` will also provide centering if used with <a href='#userdraw'>input(s),color</a> |
||
5406 | @%xyoffset%size 400,400%xrange -10,10%yrange -10,10%fontfamily 12pt Arial%string blue,-9,-9,no offset%point -9,-9,red%centered%string blue,-6,-6,centered%point -6,-6,red%xoffset%string blue,-3,-3,xoffset%point -3,-3,red%yoffset%string blue,0,0,yoffset%point 0,0,red%xyoffset%string blue,3,3,xyoffset%point 3,3,red%resetoffset%string blue,6,6,resetoffset%point 6,6,red |
||
18552 | bpr | 5407 | */ |
18556 | bpr | 5408 | use_offset = 3; |
5409 | break; |
||
18552 | bpr | 5410 | case XUNIT: |
5411 | /* |
||
18556 | bpr | 5412 | @ xunit some_unit_for_x-values |
5413 | @ unicode allowed (no html code) |
||
5414 | @ use together with command <a href="#display">display or mouse</a> |
||
5415 | @ will display the cursor x-coordinate in ''unit`` |
||
5416 | @%xunit%size 400,400%xrange -10,10%yrange -10,10%xunit cm \\u00B2%grid 2,2,grey%linewidth 2%userdraw segments,blue%display x,blue,18 |
||
18552 | bpr | 5417 | */ |
18556 | bpr | 5418 | fprintf(js_include_file,"unit_x = \"%s\";",get_string(infile,1)); |
5419 | break; |
||
18552 | bpr | 5420 | case XLABEL: |
5421 | /* |
||
5422 | @ xlabel some_string |
||
5423 | @ will be used to create a label for the x-axis (label is in quadrant I) |
||
5424 | @ can only be used together with command ''grid``<br>not depending on keywords ''axis`` and ''axisnumbering`` |
||
5425 | @ font setting: italic Courier, fontsize will be slightly larger (fontsize + 4)<br>use command ''fontsize`` to adjust.<br>(command ''fontfamily`` is not active for this command) |
||
5426 | @ use <a href="#ylabel">ylabel</a> |
||
5427 | @%xlabel%size 400,400%xrange -10,10%yrange -10,10%axis%axisnumbering%xlabel cm\\u00B2 %ylabel v\\u00B2 %precision 1%grid 2,2,grey,2,2,5,grey |
||
5428 | */ |
||
18556 | bpr | 5429 | temp = get_string(infile,1); |
5430 | fprintf(js_include_file,"var xaxislabel = \"%s\";",temp); |
||
5431 | break; |
||
18552 | bpr | 5432 | case XLOGBASE: |
5433 | /* |
||
5434 | @ xlogbase number |
||
5435 | @ sets the logbase number for the x-axis |
||
5436 | @ default value 10 |
||
5437 | @ use together with commands xlogscale / xylogscale |
||
5438 | */ |
||
18556 | bpr | 5439 | fprintf(js_include_file,"xlogbase=%d;",(int)(get_real(infile,1))); |
5440 | break; |
||
18552 | bpr | 5441 | case XLOGSCALE: |
5442 | /* |
||
18556 | bpr | 5443 | @ xlogscale ymajor,yminor,majorcolor,minorcolor |
5444 | @ the x/y-range are set using commands <code>xrange xmin,xmax</code> and <code>yrange ymin,ymax</code> |
||
5445 | @ ymajor is the major step on the y-axis; yminor is the divisor for the y-step |
||
5446 | @ the linewidth is set using command ''linewidth int`` |
||
5447 | @ the opacity of major / minor grid lines is set by command <a href='#opacity'>opacity</a> |
||
5448 | @ default logbase number = 10 ... when needed, set the logbase number with command ''xlogbase number`` |
||
18627 | bpr | 5449 | @ the x/y- axis numbering is triggered by keyword ''axisnumbering``<ul><li>use command ''precision`` before ''xlogscale`` command to set the precision (decimals) of the axis numbering</li><li>use commands ''xlabel some_text`` and/or ''ylabel some_text`` for text on axis: use command ''fontsize int`` to set the fontsize (default 12px)</li><li>use command ''fontfamily fnt_family_string`` to set the fonts for axis-numbering</li><li>use command ''fontcolor`` to set the color</li></ul> |
18556 | bpr | 5450 | @ note: the complete canvas will be used for the ''log paper`` |
5451 | @ note: userdrawings are done in the log paper, e.g. javascript:read_canvas() will return the real values |
||
5452 | @ note: command ''mouse color,fontsize`` will show the real values in the logpaper.<br>\ |
||
5453 | @ note: when using something like ''xrange 0.0001,0.01``...combined with commands <a href='#mouse'>mouse</a> and/or <a href='#userdraw'>userdraw</a>...<br> make sure the <a href='#precision'>precision</a> is set accordingly |
||
5454 | @ note: in case of userdraw, the use of keyword <a href='#userinput_xy'>userinput_xy</a> may be handy ! |
||
5455 | @ <b>attention</b>: keyword ''snaptogrid`` may not lead to the desired result... |
||
5456 | @ <b>attention</b>: do not use command ''zoom`` |
||
5457 | @%xlogscale%size 400,400%xrange 10,50000%yrange -5,5%xlabel x-axis%ylabel y-axis%xlogscale 10,1,black,grey%display x,red,22 |
||
18552 | bpr | 5458 | */ |
18556 | bpr | 5459 | use_axis_numbering++;if(use_axis_numbering > 1){use_axis_numbering = 1;} |
5460 | if( js_function[DRAW_GRID] == 1 ){canvas_error("only one type of grid is allowed...");} |
||
5461 | js_function[DRAW_XLOGSCALE] = 1; |
||
5462 | for(i=0;i<4;i++){ |
||
5463 | switch(i){ |
||
5464 | case 0: double_data[0] = get_real(infile,0);break; /* xmajor */ |
||
5465 | case 1: int_data[0] = (int) (get_real(infile,0));break; /* xminor */ |
||
5466 | case 2: stroke_color = get_color(infile,0); break; |
||
5467 | case 3: fill_color = get_color(infile,1); |
||
18557 | bpr | 5468 | tmp_buffer=my_newmem(MAX_BUFFER); |
5469 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_grid%d(%d,%d,\"%s\",\"%s\",%.2f,%.2f,%d,\"%s\",\"%s\",%d,%f,%d,%d); ",canvas_root_id,GRID_CANVAS,line_width,stroke_color,fill_color,stroke_opacity,fill_opacity,font_size,font_family,font_color,use_axis_numbering,double_data[0],int_data[0],precision)); |
||
18556 | bpr | 5470 | fprintf(js_include_file,"use_xlogscale=1;snap_y = %f;snap_x = xlogbase;",double_data[0]/int_data[0]); |
5471 | add_to_buffer(tmp_buffer); |
||
5472 | break; |
||
5473 | default:break; |
||
5474 | } |
||
5475 | } |
||
5476 | break; |
||
18552 | bpr | 5477 | case XYLOGSCALE: |
5478 | /* |
||
18556 | bpr | 5479 | @ xylogscale majorcolor,minorcolor |
5480 | @ the x/y-range are set using commands ''xrange xmin,xmax`` and ''yrange ymin,ymax`` |
||
5481 | @ the linewidth is set using command ''linewidth int`` |
||
5482 | @ the opacity of major / minor grid lines is set by command ''opacity [0-255],[0-255]`` |
||
5483 | @ default logbase number = 10 ... when needed, set the logbase number with command ''xlogbase number`` and/or ''ylogbase number`` |
||
18627 | bpr | 5484 | @ the x/y- axis numbering is triggered by keyword ''axisnumbering``<ul><li>use commands ''xlabel some_text`` and/or ''ylabel some_text`` for text on axis: use command ''fontsize int`` to set the fontsize (default 12px)</li><li>use command ''fontfamily fnt_family_string`` to set the fonts for axis-numbering</li><li>use command ''fontcolor`` to set the color</li></ul> |
18556 | bpr | 5485 | @ note: the complete canvas will be used for the ''log paper`` |
5486 | @ note: userdrawings are done in the log paper, e.g. javascript:read_canvas() will return the real values |
||
5487 | @ note: command ''mouse color,fontsize`` will show the real values in the logpaper.<br>\ |
||
5488 | @ note: when using something like ''yrange 0.0001,0.01``...combined with commands ''mouse color,fontsize`` and/or ''userdraw type,color``...<br> make sure the precision is set accordingly (eg command ''precision 10000``) |
||
5489 | @ note: in case of userdraw, the use of keyword ''userinput_xy`` may be handy ! |
||
5490 | @ <b>attention</b>: keyword ''snaptogrid`` may not lead to the desired result... |
||
5491 | @ <b>attention</b>: do not use command ''zoom`` |
||
5492 | @%xylogscale%size 400,400%xrange 10,50000%yrange 10,50000%xlabel x-axis%ylabel y-axis%xylogscale black,grey%display xy,red,22 |
||
18552 | bpr | 5493 | */ |
18556 | bpr | 5494 | use_axis_numbering++;if(use_axis_numbering > 1){use_axis_numbering = 1;} |
5495 | if( js_function[DRAW_GRID] == 1 ){canvas_error("only one type of grid is allowed...");} |
||
5496 | js_function[DRAW_XYLOGSCALE] = 1; |
||
5497 | for(i=0;i<2;i++){ |
||
5498 | switch(i){ |
||
5499 | case 0: stroke_color = get_color(infile,0); break; |
||
5500 | case 1: fill_color = get_color(infile,1); |
||
18557 | bpr | 5501 | tmp_buffer=my_newmem(MAX_BUFFER); |
5502 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_grid%d(%d,%d,\"%s\",\"%s\",%.2f,%.2f,%d,\"%s\",\"%s\",%d,%d); ",canvas_root_id,GRID_CANVAS,line_width,stroke_color,fill_color,stroke_opacity,fill_opacity,font_size,font_family,font_color,use_axis_numbering,precision)); |
||
18556 | bpr | 5503 | fprintf(js_include_file,"use_xlogscale=1;use_ylogscale=1;snap_x = xlogbase;snap_y = ylogbase;"); |
5504 | add_to_buffer(tmp_buffer); |
||
5505 | break; |
||
5506 | default:break; |
||
5507 | } |
||
5508 | } |
||
5509 | break; |
||
18552 | bpr | 5510 | case Y_AXIS_STRINGS: |
5511 | /* |
||
18556 | bpr | 5512 | @ yaxis num1:string1:num2:string2:num3:string3:num4:string4:....num_n:string_n |
5513 | @ alternative: yaxistext |
||
5514 | @ use command ''fontcolor``, ''fontfamily`` to adjust font <br>defaults: black,12,Arial<br> note: command ''fontsize`` is not active for this command.(''fontsize`` can be used for the <a href="#legend">legend</a> in a <a href="#grid">grid</a>) |
||
5515 | @ no need to use keyword <a href="#axisnumbering">axisnumbering</a> |
||
5516 | @ use command <a href="#axis">axis</a> to have visual x/y-axis lines (see command <a href="#grid">grid</a> |
||
5517 | @ use these y-axis num1...num_n values instead of default ymin...ymax |
||
5518 | @ a javascript error message will flag non-matching value:name pairs |
||
5519 | @ to be used before command grid (see <a href="#grid">command grid</a>) |
||
5520 | @%yaxistext%size 400,400%yrange 0,13%xrange -100,500%axis%yaxis 1:january:2:february:3:march:5:may:6:june:7:july:8:august:9:september:10:october:11:november:12:december%#'ymajor' steps should be synchronised with numbers eg. "1" in this example%grid 100,1,grey,4,1,6,grey |
||
18552 | bpr | 5521 | */ |
18556 | bpr | 5522 | temp = get_string(infile,1); |
5523 | if( strstr(temp,":") != 0 ){ temp = str_replace(temp,":","\",\"");} |
||
5524 | if( strstr(temp,"pi") != 0 ){ temp = str_replace(temp,"pi","(3.1415927)");}/* we need to replace pi for javascript y-value*/ |
||
5525 | fprintf(js_include_file,"y_strings = [\"%s\"];\n ",temp); |
||
5526 | use_axis_numbering++; |
||
5527 | break; |
||
18552 | bpr | 5528 | case YERRORBARS: |
5529 | /* |
||
5530 | @ yerrorbars color,E1,E2,x1,y1,x2,y2,...,x_n,y_n |
||
5531 | @ draw multiple points with y-errorbars E1 (error value under point) and E2 (error value above point) at given coordinates in color 'color' |
||
5532 | @ the errors E1 and E2 values are in yrange. |
||
5533 | @ use command ''linewidth int`` to adust size |
||
5534 | @ may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
||
5535 | @%yerrorbars%size 400,400%xrange -10,10%yrange -10,10%linewidth 2%onclick%yerrorbars red,0.8,1.3,0,0,1,1,2,3,3,2,4,5,5,2,6,1,-1,-2,-2,0,-3,2,-4,4,-5,-1 |
||
5536 | */ |
||
5537 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
5538 | fill_color = stroke_color; |
||
5539 | i=0; |
||
5540 | while( ! done ){ /* get next item until EOL*/ |
||
18556 | bpr | 5541 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
5542 | if(i%2 == 0 ){ |
||
5543 | double_data[i] = get_real(infile,0); /* x */ |
||
5544 | } |
||
5545 | else |
||
5546 | { |
||
5547 | double_data[i] = get_real(infile,1); /* y */ |
||
5548 | } |
||
5549 | i++; |
||
18552 | bpr | 5550 | } |
5551 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5552 | for(c = 2 ; c < i-1 ; c = c+2){ |
||
18557 | bpr | 5553 | tmp_buffer=my_newmem(MAX_BUFFER); |
5554 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "dragstuff.addShape(new Shape(%d,%d,%d,%d,19,[%.*f],[%.*f],[%.2f],[%.2f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],double_data[0],double_data[1],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,1,0,0,0,use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
18556 | bpr | 5555 | add_to_buffer(tmp_buffer); |
18552 | bpr | 5556 | /* object_cnt++; */ |
18556 | bpr | 5557 | if(onclick != 0){object_cnt++;} |
18552 | bpr | 5558 | } |
5559 | decimals = find_number_of_digits(precision); |
||
5560 | reset(); |
||
5561 | dragstuff[19] = 1; |
||
5562 | if(use_dragstuff == 0 ){ use_dragstuff = 1;} |
||
5563 | break; |
||
5564 | case YOFFSET: |
||
5565 | /* |
||
18556 | bpr | 5566 | @ yoffset |
5567 | @ keyword; to place the text centered above the text coordinates(x:y) ... |
||
5568 | @ may be used for points or other things requiring centered labels |
||
5569 | @ use <a href="#fontfamily">fontfamily</a> for setting the font |
||
5570 | @ may be active for commands <a href="#text">text</a> and <a href="#string">string</a> (e.g. objects in the drag/drop/onclick-library) |
||
5571 | @%yoffset%size 400,400%xrange -10,10%yrange -10,10%fontfamily 12pt Arial%string blue,-9,-9,no offset%point -9,-9,red%centered%string blue,-6,-6,centered%point -6,-6,red%xoffset%string blue,-3,-3,xoffset%point -3,-3,red%yoffset%string blue,0,0,yoffset%point 0,0,red%xyoffset%string blue,3,3,xyoffset%point 3,3,red%resetoffset%string blue,6,6,resetoffset%point 6,6,red |
||
18552 | bpr | 5572 | */ |
18556 | bpr | 5573 | use_offset = 1; |
5574 | break; |
||
18552 | bpr | 5575 | case YRANGE: |
5576 | /* |
||
5577 | @ yrange ymin,ymax |
||
5578 | @ alternative: rangey |
||
5579 | @ if not given 0,ysize (eg in pixels) |
||
5580 | */ |
||
18556 | bpr | 5581 | for(i = 0 ; i<2; i++){ |
5582 | switch(i){ |
||
5583 | case 0: ymin = get_real(infile,0);break; |
||
5584 | case 1: ymax = get_real(infile,1);break; |
||
5585 | default: break; |
||
5586 | } |
||
5587 | } |
||
5588 | if(ymin >= ymax){canvas_error(" yrange is not OK: ymin < ymax !<br>");} |
||
5589 | fprintf(js_include_file,"var ymin = %f;var ymax = %f;",ymin,ymax); |
||
5590 | found_size_command++; |
||
5591 | break; |
||
18552 | bpr | 5592 | case YSNAPTOGRID: |
5593 | /* |
||
18556 | bpr | 5594 | @ ysnaptogrid |
5595 | @ keyword (no arguments required) |
||
5596 | @ a draggable object (use command ''drag x|y|xy``) will snap to the given y-grid values when dragged (mouseup) |
||
5597 | @ in case of userdraw the drawn points will snap to ymajor grid |
||
5598 | @ if no grid is defined, points will snap to every integer yrange value. (eg snap_y=1) |
||
5599 | @ if you do not want a visible grid, but you only want a ''snaptogrid`` with some value...define this grid with opacity 0. |
||
5600 | @ if yminor is defined (use keyword ''axis`` to activate yminor), the drawing will snap to yminor <br>use only even dividers in y-minor...for example<br><code>ysnaptogrid<br>axis<br>grid 2,1,grey,4,4,7,red</code><br> will snap on x=0, x=0.5, x=1, x=1.5 ....<br> will snap on y=0, y=0.25 y=0.5 y=0.75 ...<br> |
||
5601 | @%ysnaptogrid_1%size 400,400%xrange -10,10%yrange -10,10%ysnaptogrid%grid 1,1,grey%linewidth 2%userdraw crosshairs,blue%css font-size:8px;color:blue%clearbutton delete all crosshairs |
||
5602 | @%ysnaptogrid_2%size 400,400%xrange -10,10%yrange -10,10%ysnaptogrid%grid 1,1,grey%linewidth 3%drag y%points red,0,0,0,0,0,0,0,0,0,0 |
||
18552 | bpr | 5603 | */ |
18556 | bpr | 5604 | use_snap = 3; |
5605 | break; |
||
18552 | bpr | 5606 | case YLABEL: |
5607 | /* |
||
5608 | @ ylabel some_string |
||
5609 | @ will be used to create a (vertical) label for the y-axis (label is in quadrant I) |
||
5610 | @ can only be used together with command <a href="#grid">grid</a><br>not depending on keywords ''axis`` and ''axisnumbering`` |
||
5611 | @ font setting: italic Courier, fontsize will be slightly larger (fontsize + 4)<br>use command ''fontsize`` to adjust (command ''fontsize`` is not active for this command) |
||
5612 | @ use <a href="#xlabel">xlabel</a> |
||
5613 | @%ylabel%size 400,400%xrange -10,10%yrange -10,10%fontsize 8%axis%axisnumbering%precision 1%xlabel x-axis%ylabel y-axis%grid 1,1,grey,2,2,2,red |
||
5614 | */ |
||
18556 | bpr | 5615 | temp = get_string(infile,1); |
5616 | fprintf(js_include_file,"var yaxislabel = \"%s\";",temp); |
||
5617 | break; |
||
18552 | bpr | 5618 | case YLOGBASE: |
5619 | /* |
||
5620 | @ ylogbase number |
||
5621 | @ sets the logbase number for the y-axis |
||
5622 | @ default value 10 |
||
5623 | @ use together with commands ylogscale / xylogscale |
||
5624 | */ |
||
5625 | fprintf(js_include_file,"ylogbase=%d;",(int)(get_real(infile,1))); |
||
5626 | break; |
||
5627 | case YLOGSCALE: |
||
5628 | /* |
||
18556 | bpr | 5629 | @ ylogscale xmajor,xminor,majorcolor,minorcolor |
5630 | @ the x/y-range are set using commands ''xrange xmin,xmax`` and ''yrange ymin,ymax`` |
||
5631 | @ xmajor is the major step on the x-axis; xminor is the divisor for the x-step |
||
5632 | @ the linewidth is set using command ''linewidth int`` |
||
5633 | @ the opacity of major / minor grid lines is set by command ''opacity [0-255],[0-255]`` |
||
5634 | @ default logbase number = 10 ... when needed, set the logbase number with command ''ylogbase number`` |
||
5635 | @ the x/y- axis numbering is triggered by keyword ''axisnumbering``<ul><li>use command ''precision`` before ''ylogscale`` command to set the precision (decimals) of the axis numbering</li><li>use commands ''xlabel some_text`` and/or ''ylabel some_text`` for text on axis: use command ''fontsize int`` to set the fontsize (default 12px)</li><li>use command ''fontfamily fnt_family_string`` to set the fonts for axis-numbering</li><li>use command ''fontcolor`` to set the color</li></ul> |
||
5636 | @ note: the complete canvas will be used for the ''log paper`` |
||
5637 | @ note: userdrawings are done in the log paper, e.g. javascript:read_canvas() will return the real values |
||
5638 | @ note: command ''mouse color,fontsize`` will show the real values in the logpaper.<br>\ |
||
5639 | @ note: when using something like ''yrange 0.0001,0.01``...combined with commands ''mouse color,fontsize`` and/or ''userdraw type,color``...<br> make sure the precision is set accordingly (eg command ''precision 10000``) |
||
5640 | @ note: in case of userdraw, the use of keyword ''userinput_xy`` may be handy ! |
||
5641 | @ <b>attention</b>: do not use command ''zoom`` |
||
5642 | @ <b>attention</b>: keyword ''snaptogrid`` may not lead to the desired result... |
||
18552 | bpr | 5643 | */ |
18555 | bpr | 5644 | use_axis_numbering++;if(use_axis_numbering > 1){use_axis_numbering = 1;} |
5645 | if( js_function[DRAW_GRID] == 1 ){canvas_error("only one type of grid is allowed...");} |
||
5646 | js_function[DRAW_YLOGSCALE] = 1; |
||
5647 | for(i=0;i<4;i++){ |
||
5648 | switch(i){ |
||
5649 | case 0: double_data[0] = get_real(infile,0);break; /* xmajor */ |
||
5650 | case 1: int_data[0] = (int) (get_real(infile,0));break; /* xminor */ |
||
5651 | case 2: stroke_color = get_color(infile,0); break; |
||
5652 | case 3: fill_color = get_color(infile,1); |
||
18557 | bpr | 5653 | tmp_buffer=my_newmem(MAX_BUFFER); |
5654 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER, "draw_grid%d(%d,%d,\"%s\",\"%s\",%.2f,%.2f,%d,\"%s\",\"%s\",%d,%f,%d,%d); ",canvas_root_id,GRID_CANVAS,line_width,stroke_color,fill_color,stroke_opacity,fill_opacity,font_size,font_family,font_color,use_axis_numbering,double_data[0],int_data[0],precision)); |
||
18555 | bpr | 5655 | fprintf(js_include_file,"use_ylogscale=1;snap_x = %f;snap_y = ylogbase;",double_data[0]/int_data[0]); |
5656 | add_to_buffer(tmp_buffer); |
||
5657 | break; |
||
5658 | default:break; |
||
5659 | } |
||
5660 | } |
||
5661 | break; |
||
18552 | bpr | 5662 | case YUNIT: |
5663 | /* |
||
18556 | bpr | 5664 | @ yunit some_unit_for_y-values |
5665 | @ unicode allowed (no html code) |
||
5666 | @ use together with command mousey |
||
5667 | @ will display the cursor y-coordinate in ''unit`` |
||
18552 | bpr | 5668 | */ |
5669 | fprintf(js_include_file,"unit_y = \"%s\";",get_string(infile,1)); |
||
5670 | break; |
||
18555 | bpr | 5671 | case HYPSEGMENTS: |
18556 | bpr | 5672 | /* |
5673 | @ hypsegments color,x1,y1,x2,y2,...,x_n,y_n |
||
5674 | @ draw multiple hyperbolic segments in the Poincaré disk between points (x1:y1)--(x2:y2).....and... (x_n-1:y_n-1)--(x_n:y_n) in color ''color`` |
||
18639 | schaersvoo | 5675 | @ use command ''linewidth int`` to adjust size may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> individually (!) |
18556 | bpr | 5676 | @%hypsegments%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%linewidth 2%hypsegments green,0.1,-0.3,0.6,0.7,0.3,0,-0.8,0.6,0.6,0.5,-0.5,0.6 |
18639 | schaersvoo | 5677 | */ |
18555 | bpr | 5678 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
5679 | fill_color = stroke_color; |
||
5680 | i=0; |
||
5681 | while( ! done ){ /* get next item until EOL*/ |
||
5682 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
5683 | if(i%2 == 0 ){ |
||
5684 | double_data[i] = get_real(infile,0); /* x */ |
||
5685 | } |
||
5686 | else { |
||
5687 | double_data[i] = get_real(infile,1); /* y */ |
||
5688 | } |
||
5689 | i++; |
||
5690 | } |
||
5691 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
5692 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
5693 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5694 | decimals = find_number_of_digits(precision); |
||
5695 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18569 | bpr | 5696 | tmp_buffer=my_newmem(MAX_BUFFER); |
18555 | bpr | 5697 | if (hypgeodaux(double_data+c,res,0)){ |
5698 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,12,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,res[0],decimals,res[0],decimals,res[1],decimals,res[1],decimals,res[2],decimals,res[3],decimals,res[4],decimals,res[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
5699 | } |
||
5700 | else { |
||
5701 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,stroke_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
5702 | } |
||
5703 | add_to_buffer(tmp_buffer); |
||
5704 | if(onclick != 0){object_cnt++;} |
||
5705 | } |
||
5706 | reset(); |
||
5707 | dragstuff[4] = 1;dragstuff[12] = 1; |
||
5708 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5709 | break; |
||
5710 | case HYPLINES: |
||
18639 | schaersvoo | 5711 | /* |
18555 | bpr | 5712 | @ hyplines color,x1,y1,x2,y2...x_n-1,y_n-1,x_n,y_n |
18639 | schaersvoo | 5713 | @ draw multiple hyperbolic lines in the Poincaré disk through points (x1:y1)--(x2:y2) ...(x_n-1:y_n-1)--(x_n:y_n) in color 'color' may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
18555 | bpr | 5714 | @%hyplines%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%hyplines green,0,0.1,0.1,0.3,0.2,0.3,0.1,0.3,0,0.5,-0.5,0.4 |
5715 | */ |
||
5716 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
5717 | fill_color = stroke_color; |
||
5718 | i=0; |
||
5719 | while( ! done ){ /* get next item until EOL*/ |
||
5720 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
18562 | bpr | 5721 | if(i%2 == 0 ){ |
5722 | double_data[i] = get_real(infile,0); /* x */ |
||
5723 | } |
||
18555 | bpr | 5724 | else { |
5725 | double_data[i] = get_real(infile,1); /* y */ |
||
5726 | } |
||
5727 | i++; |
||
5728 | } |
||
5729 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
5730 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
5731 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
18623 | bpr | 5732 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18555 | bpr | 5733 | decimals = find_number_of_digits(precision); |
5734 | for(c = 0 ; c < i-1 ; c = c+4){ |
||
18569 | bpr | 5735 | tmp_buffer=my_newmem(MAX_BUFFER); |
18555 | bpr | 5736 | if (hypgeodaux(double_data+c,res,1)){ |
5737 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,12,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,res[0],decimals,res[0],decimals,res[1],decimals,res[1],decimals,res[2],decimals,res[3],decimals,res[4],decimals,res[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset));} |
||
5738 | else { |
||
18623 | bpr | 5739 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,res[0],decimals,res[2],decimals,res[1],decimals,res[3],line_width,stroke_color,stroke_opacity,fill_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18555 | bpr | 5740 | } |
5741 | add_to_buffer(tmp_buffer); |
||
5742 | if(onclick != 0){object_cnt++;} |
||
5743 | } |
||
5744 | reset(); |
||
5745 | dragstuff[4] = 1;dragstuff[12] = 1; |
||
5746 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5747 | break; |
||
5748 | case HYPPOLY: |
||
18639 | schaersvoo | 5749 | /* |
5750 | @ hyppolygon color,x1,y1,x2,y2...x_n-1,y_n-1,x_n,y_n |
||
5751 | @ draw hyperbolicpolygon in the Poincaré disk through points (x1:y1)--(x2:y2) ...(x_n-1:y_n-1)--(x_n:y_n) -- (x1:y1) in color 'color' may be set <a href="#drag">draggable</a> / <a href="#onclick">onclick</a> |
||
18615 | bpr | 5752 | @ option fhyppolygon only for convex polygon for the moment |
5753 | @%hyppolygon%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%hyppolygon green,0,0,0.5,0.3,0.8,-0.1,0.4,-0.5 |
||
18639 | schaersvoo | 5754 | */ |
18615 | bpr | 5755 | stroke_color=get_color(infile,0); |
18555 | bpr | 5756 | fill_color = stroke_color; |
5757 | i=0; |
||
5758 | while( ! done ){ /* get next item until EOL*/ |
||
5759 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
||
5760 | if(i%2 == 0 ){ |
||
5761 | double_data[i] = get_real(infile,0); /* x */ |
||
5762 | } |
||
5763 | else { |
||
5764 | double_data[i] = get_real(infile,1); /* y */ |
||
5765 | } |
||
5766 | i++; |
||
5767 | } |
||
5768 | /* il faut rajouter le premier point à la fin*/ |
||
5769 | double_data[i]=double_data[0]; double_data[i+1]=double_data[1]; |
||
5770 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
5771 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
5772 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5773 | decimals = find_number_of_digits(precision); |
||
5774 | for(c = 0 ; c < i-1 ; c = c+2){ |
||
18615 | bpr | 5775 | tmp_buffer=my_newmem(MAX_BUFFER); |
18555 | bpr | 5776 | if (hypgeodaux(double_data+c,res,0)){ |
18615 | bpr | 5777 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,12,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,res[0],decimals,res[0],decimals,res[1],decimals,res[1],decimals,res[2],decimals,res[3],decimals,res[4],decimals,res[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18555 | bpr | 5778 | } |
5779 | else { |
||
18623 | bpr | 5780 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+2],decimals,double_data[c+1],decimals,double_data[c+3],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18555 | bpr | 5781 | } |
5782 | add_to_buffer(tmp_buffer); |
||
5783 | if(onclick != 0){object_cnt++;} |
||
18615 | bpr | 5784 | } |
5785 | if(use_filled){ |
||
5786 | hypgeodaux(double_data+2,res,0); |
||
5787 | res[4]=double_data[0]; res[5]=double_data[1]; |
||
5788 | hypgeodaux(res+4,res,0); |
||
5789 | add_js_filltoborder(canvas_type); |
||
5790 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"setTimeout(function(){filltoborder (%.*f,%.*f,[%s,%d],[%s,%d],%d,false,null);},1000);\n",decimals,res[6],decimals,res[7],fill_color,(int) (fill_opacity/0.0039215),fill_color,(int) (fill_opacity/0.0039215),FILL_CANVAS+fill_cnt)); |
||
5791 | add_to_buffer(tmp_buffer); |
||
5792 | fill_cnt++; |
||
18606 | bpr | 5793 | } |
18569 | bpr | 5794 | dragstuff[4] = 1; dragstuff[12] = 1; |
18555 | bpr | 5795 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
5796 | reset(); |
||
5797 | break; |
||
5798 | case HYPRAYS: |
||
5799 | /* |
||
18556 | bpr | 5800 | @ hyprays color,xc,yc,x1,y1,x2,y2,x3,y3...x_n,y_n |
18639 | schaersvoo | 5801 | @ draw hyperbolic rays in the Poincaré disk in color 'color' and center (xc:yc) may be set draggable or onclick (every individual ray) |
18556 | bpr | 5802 | @%hyprays%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%onclick%hyprays blue,0.5,0.5,0.3,0.9,-0.3,0.5,-0.4,0,0.4,-0.9,-0.8,0.1,-0.1,-0.9 |
18639 | schaersvoo | 5803 | */ |
5804 | /* |
||
18555 | bpr | 5805 | hyprays_onclick%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%onclick%hyprays blue,0.5,0.5,0.3,0.9,-0.3,0.5,-0.4,0,0.4,-0.9,-0.8,0.1,-0.1,-0.9 |
5806 | hyprays_drag_xy%size 400,400%xrange -1,1%yrange -1,1%circles black,0,0,1%drag xy%hyprays blue,0,0,0.3,0.9,-0.3,0.5,-0.4,0,0.4,-0.9,-0.8,0.1,-0.1,-0.9 |
||
5807 | */ |
||
5808 | stroke_color=get_color(infile,0); |
||
18623 | bpr | 5809 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18555 | bpr | 5810 | double_data[0] = get_real(infile,0);/* xc */ |
5811 | double_data[1] = get_real(infile,0);/* yc */ |
||
5812 | i=2; |
||
18562 | bpr | 5813 | while( ! done ){ /* get next item until EOL*/ |
18555 | bpr | 5814 | if(i > MAX_INT - 1){canvas_error("in command rays too many points / rays in argument: repeat command multiple times to fit");} |
5815 | if(i%2 == 0 ){ |
||
5816 | double_data[i] = get_real(infile,0); /* x */ |
||
5817 | } |
||
5818 | else { |
||
5819 | double_data[i] = get_real(infile,1); /* y */ |
||
5820 | } |
||
5821 | fprintf(js_include_file,"/* double_data[%d] = %f */\n",i,double_data[i]); |
||
5822 | i++; |
||
5823 | } |
||
5824 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,2);} |
||
5825 | if(use_affine == TRUE ){ transform(i-1,2);} |
||
5826 | if( i%2 != 0 ){canvas_error("in command rays: unpaired x or y value");} |
||
5827 | decimals = find_number_of_digits(precision); |
||
5828 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5829 | for(c=2; c<i;c = c+2){ |
||
18557 | bpr | 5830 | tmp_buffer=my_newmem(MAX_BUFFER); |
18555 | bpr | 5831 | double_data[2]=double_data[c];double_data[3]=double_data[c+1]; |
5832 | if (hypgeodaux(double_data,res,0)){ |
||
5833 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,12,[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],[%.*f,%.*f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,res[0],decimals,res[0],decimals,res[1],decimals,res[1],decimals,res[2],decimals,res[3],decimals,res[4],decimals,res[5],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
||
5834 | } |
||
5835 | else { |
||
18623 | bpr | 5836 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,4,[%.*f,%.*f],[%.*f,%.*f],[30,30],[30,30],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[0],decimals,double_data[c],decimals,double_data[1],decimals,double_data[c+1],line_width,stroke_color,stroke_opacity,fill_color,stroke_opacity,0,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18555 | bpr | 5837 | } |
5838 | add_to_buffer(tmp_buffer); |
||
5839 | /* object_cnt++; */ |
||
5840 | if(onclick != 0){object_cnt++;} |
||
5841 | } |
||
5842 | reset(); |
||
5843 | dragstuff[4] = 1; dragstuff[12] = 1; |
||
5844 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5845 | break; |
||
5846 | case HYPCIRCLES: |
||
5847 | /* |
||
5848 | @ hypcircles color,xc1,yc1,r1,xc2,yc2,r2...xc_n,yc_n,r_n |
||
5849 | @ draw hyperbolic circles in Poincaré disk |
||
5850 | @ <b>attention</b> r = radius in x-range (!) |
||
5851 | @ use keyword <code>filled</code> or command <code>fhypcircles</code> to produce solid circles |
||
5852 | @ use command <code>fillcolor color</code> to set the fillcolor |
||
5853 | @%hypcircles%size 400,400%xrange -1,1%yrange -1,1%filled%fillcolor lightblue%opacity 255,50%hypcircles blue,0,0,1,0.4,0.4,3,0.2,0.6,6 |
||
18639 | schaersvoo | 5854 | */ |
5855 | /* |
||
18555 | bpr | 5856 | hypcircles_drag%size 400,400%xrange -1,1%yrange -1,1%filled%fillcolor lightblue%opacity 255,50%drag xy%hypcircles blue,0,0,2,0.2,0.2,3,0.2,0.2,5%zoom red |
5857 | hypcircles_onclick%size 400,400%xrange -1,1%yrange -1,1%filled%fillcolor lightblue%opacity 255,50%onclick%hypcircles blue,0,0,2,0.2,0.2,3,0.2,0.2,5%zoom red |
||
5858 | hypcircles_drag_slider%size 400,400%xrange -1,1%yrange -1,1%linewidth 2%drag xy%# Click circles(s) to activate%opacity 200,50%fillcolor orange%rotationcenter 2,3%slider 0,2*pi,300,30,angle degrees,Rotate%slider -5,5*pi,300,30,x display,move in x-direction%slider -10,10*pi,300,30,y display,move in y-direction%hypcircles blue,0,0,2,0.2,0.2,3,0.2,0.2,5 |
||
5859 | */ |
||
5860 | stroke_color=get_color(infile,0); /* how nice: now the color comes first...*/ |
||
18623 | bpr | 5861 | if(fillcolor) {fill_color=fillcolor;} else {fill_color=stroke_color;} |
18555 | bpr | 5862 | i=1; |
18562 | bpr | 5863 | while( ! done ){ /* get next item until EOL*/ |
18555 | bpr | 5864 | if(i > MAX_INT - 1){canvas_error("too many points in argument: repeat command multiple times to fit");} |
5865 | switch (i%3){ |
||
5866 | case 1:double_data[i-1] = get_real(infile,0);break; /* x */ |
||
5867 | case 2:double_data[i-1] = get_real(infile,0);break; /* y */ |
||
5868 | case 0:double_data[i-1] = get_real(infile,1);break; /* r */ |
||
5869 | } |
||
5870 | i++; |
||
5871 | } |
||
5872 | if(use_rotate == TRUE ){rotate(i-1,angle,rotationcenter,3);} |
||
5873 | if(use_affine == TRUE ){ transform(i-1,3);} |
||
5874 | if( use_slider != -1 && onclick == 0){ onclick = 3; }/* no drag&onclick but slideable */ |
||
5875 | decimals = find_number_of_digits(precision); |
||
5876 | for(c = 0 ; c < i-1 ; c = c+3){ |
||
18556 | bpr | 5877 | double Z2=double_data[c]*double_data[c]+double_data[c+1]*double_data[c+1];//[Z]^2 |
18555 | bpr | 5878 | double R=tanh(double_data[c+2]/2);double R2=R*R; |
5879 | double den=1-R2*Z2; double XY=(1-R2)/den; |
||
5880 | double_data[c]=XY*double_data[c]; |
||
5881 | double_data[c+1]=XY*double_data[c+1]; |
||
5882 | double_data[c+2]=(1-Z2)/den*R; |
||
18557 | bpr | 5883 | tmp_buffer=my_newmem(MAX_BUFFER); |
18623 | bpr | 5884 | check_string_length(snprintf(tmp_buffer,MAX_BUFFER,"dragstuff.addShape(new Shape(%d,%d,%d,%d,13,[%.*f],[%.*f],[%.3f],[%.3f],%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d,%d,%d,%.1f,\"%s\",%d,\"%s\",%s,%s,%d));\n",drag_type,object_cnt,onclick,use_snap,decimals,double_data[c],decimals,double_data[c+1],double_data[c+2],double_data[c+2],line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype[0],dashtype[1],use_rotate,angle,flytext,font_size,font_family,my_sliders,rotation_center,use_offset)); |
18555 | bpr | 5885 | add_to_buffer(tmp_buffer); |
5886 | if(onclick != 0){object_cnt++;}/* object_cnt++; */ |
||
5887 | } |
||
5888 | reset(); |
||
5889 | dragstuff[13] = 1; |
||
5890 | if(use_dragstuff == 0 ){ use_dragstuff = 1; } |
||
5891 | break; |
||
18552 | bpr | 5892 | case ZOOM: |
5893 | /* |
||
18556 | bpr | 5894 | @ zoom button_color |
5895 | @ introduce a very small ''controlpanel`` at the lower right corner (font size of the panel is fixed to: 22px Arial) |
||
5896 | @ giving six 15×15px ''active`` rectangle areas<br>(''×,↓,↑,←,→,−,+``) for zooming and/or panning of the image |
||
5897 | @ a mouse wheel is active for in/out zooming. Drag panning is not supported (this will conflict with many ''userdraw`` or ''multidraw`` primitives) |
||
5898 | @ the ''controlpanel`` is not active for a ''userdraw`` mousedown (but it can interfere with some ''userdraw`` types) |
||
5899 | @ the ''×`` symbol will reset to your original xmax/xmin ymax/ymin values. |
||
5900 | @ choose an appropriate color, so the small ''×,↓,↑,←,→,−,+`` are clearly visible |
||
5901 | @ command ''opacity`` may be used to set stroke_opacity of buttons |
||
5902 | @ note: on zooming, text will not increase / decrease the font size (todo??) |
||
5903 | @ note: adding ''zooming`` will increase the size of the javascript include with approx. 11 kb |
||
18552 | bpr | 5904 | */ |
18556 | bpr | 5905 | js_function[INTERACTIVE] = 1; |
18552 | bpr | 5906 | js_function[JS_ZOOM] = 1; |
5907 | if( use_userdraw == 1 ){ |
||
5908 | js_function[USERDRAW_AND_ZOOM] = 1; |
||
5909 | fprintf(js_include_file,"forbidden_zone = [%d,%d];",xsize-115,ysize - 20); |
||
5910 | } |
||
5911 | if(jsplot_cnt != -1){ js_function[JSPLOT_AND_ZOOM] = 1;} |
||
5912 | stroke_color = get_color(infile,1); |
||
5913 | /* we use BG_CANVAS (0) */ |
||
5914 | add_js_zoom_buttons(stroke_color,stroke_opacity); |
||
5915 | done = TRUE; |
||
5916 | break; |
||
11806 | schaersvoo | 5917 | |
5918 | /* ready */ |
||
18552 | bpr | 5919 | default:sync_input(infile); |
5920 | break; |
||
5921 | } |
||
7614 | schaersvoo | 5922 | } |
5923 | /* we are done parsing script file */ |
||
18556 | bpr | 5924 | if(use_dragstuff != 0){ |
18562 | bpr | 5925 | /* add the 20kb drag code: nearly always used ... use_dragstuff==1: no-mouse ! */ |
18556 | bpr | 5926 | add_drag_code(DRAG_CANVAS,use_dragstuff,dragstuff,reply_format); |
5927 | if(js_function[JS_ZOOM] == 1){ |
||
15111 | schaersvoo | 5928 | js_function[DRAG_AND_ZOOM] = 1; |
18556 | bpr | 5929 | } |
15111 | schaersvoo | 5930 | } |
15116 | bpr | 5931 | |
14066 | bpr | 5932 | /* check if xrange / yrange was set explicit ... or use xmin=0 xmax=xsize ymin=0 ymax=ysize: Quadrant I */ |
18556 | bpr | 5933 | if( found_size_command == 1 ){ |
5934 | fprintf(js_include_file,"var xmin = 0;var xmax = %d;var ymin = 0;var ymax = %d",xsize,ysize); |
||
7983 | schaersvoo | 5935 | } |
18556 | bpr | 5936 | else |
5937 | { |
||
5938 | if( found_size_command != 3 ){ |
||
5939 | canvas_error("Please specify size first and then both xrange and yrange ..."); |
||
5940 | } |
||
5941 | } |
||
8257 | schaersvoo | 5942 | |
18562 | bpr | 5943 | /* if needed, add generic draw functions (grid / xml etc) to buffer: these are no draggable/clickable shapes / objects ! */ |
18556 | bpr | 5944 | add_javascript_function(); |
7614 | schaersvoo | 5945 | /* add read_canvas() etc functions if needed */ |
18556 | bpr | 5946 | if( reply_format > 0 ){ add_read_canvas(reply_format,reply_precision);} |
7797 | schaersvoo | 5947 | /* no zoom, just add buffer */ |
18556 | bpr | 5948 | fprintf(js_include_file,"\n/* add buffer */\n%s};\n/* end wims_canvas_function */\nwims_canvas_function%d();\n",buffer,canvas_root_id); |
7614 | schaersvoo | 5949 | /* done writing the javascript include file */ |
18556 | bpr | 5950 | fclose(js_include_file); |
5951 | } |
||
7614 | schaersvoo | 5952 | |
5953 | /* if using a tooltip, this should always be printed to the *.phtml file, so stdout */ |
||
18556 | bpr | 5954 | if( use_tooltip > 0 ){ |
5955 | if( use_tooltip == 1 ){ |
||
5956 | add_js_tooltip(tooltip_text,bgcolor); |
||
5957 | } |
||
5958 | else |
||
5959 | { |
||
5960 | if( use_tooltip == 2 ){ |
||
5961 | add_js_popup(getfile_cmd); |
||
5962 | } |
||
5963 | } |
||
9329 | schaersvoo | 5964 | } |
18556 | bpr | 5965 | exit(EXIT_SUCCESS); |
7614 | schaersvoo | 5966 | } |
5967 | /* end main() */ |
||
5968 | |||
5969 | /****************************************************************************** |
||
5970 | ** |
||
5971 | ** sync_input |
||
5972 | ** |
||
5973 | ** synchronises input line - reads to end of line, leaving file pointer |
||
5974 | ** at first character of next line. |
||
5975 | ** |
||
5976 | ** Used by: |
||
5977 | ** main program - error handling. |
||
5978 | ** |
||
5979 | ******************************************************************************/ |
||
5980 | void sync_input(FILE *infile) |
||
5981 | { |
||
18552 | bpr | 5982 | int c = 0; |
7614 | schaersvoo | 5983 | |
18552 | bpr | 5984 | if( c == '\n' || c == ';' ) return; |
5985 | while( ( (c=getc(infile)) != EOF ) && (c != '\n') && (c != '\r') && (c != ';')) ; |
||
5986 | if( c == EOF ) finished = 1; |
||
5987 | if( c == '\n' || c == '\r' || c == ';') line_number++; |
||
5988 | return; |
||
7614 | schaersvoo | 5989 | } |
5990 | |||
5991 | /******************************************************************************/ |
||
15111 | schaersvoo | 5992 | void transform(int num,int incr){ |
5993 | /*. |
||
5994 | only "double_data[]" is used for transformations !! |
||
5995 | */ |
||
5996 | int i;int ii;double x,y; |
||
5997 | for(i=0;i<num;i = i+incr){ |
||
5998 | ii = i+1; |
||
5999 | x = double_data[i]*affine_matrix[0] + double_data[ii]*affine_matrix[1]+affine_matrix[4]; |
||
6000 | y = double_data[i]*affine_matrix[2] + double_data[ii]*affine_matrix[3]+affine_matrix[5]; |
||
15601 | schaersvoo | 6001 | /* |
17351 | bpr | 6002 | printf("(%f:%f) → (%f:%f)<br>",double_data[i],double_data[ii],x,y); |
15601 | schaersvoo | 6003 | */ |
15111 | schaersvoo | 6004 | double_data[i] = x; |
6005 | double_data[ii] = y; |
||
6006 | } |
||
6007 | } |
||
6008 | |||
6009 | void rotate(int num,double angle,double center[],int incr){ |
||
6010 | int i;int ii;double rad = angle * 0.0174532925199; |
||
6011 | double c = cos(rad); |
||
6012 | double s = sin(rad); |
||
6013 | double x,y; |
||
6014 | for(i=0;i<num;i = i+incr){ |
||
6015 | ii = i+1; |
||
6016 | x = c*(double_data[i]-center[0]) + s*(double_data[ii] - center[1] ) + center[0]; |
||
6017 | y = c*(double_data[ii]-center[1]) - s*(double_data[i] - center[0] ) + center[1]; |
||
6018 | double_data[i] = x; |
||
6019 | double_data[ii] = y; |
||
17351 | bpr | 6020 | // printf("(x:y) - (%f:%f)<br>",x,y); |
15111 | schaersvoo | 6021 | } |
6022 | } |
||
6023 | /* not used: see transform() |
||
6024 | void translate(int num){ |
||
6025 | int i;int ii; |
||
6026 | double x,y; |
||
6027 | for(i=0;i<num;i = i+2){ |
||
6028 | ii = i+1; |
||
6029 | x = double_data[i] + affine_matrix[4]; |
||
6030 | y = double_data[ii] + affine_matrix[5]; |
||
6031 | double_data[i] = x; |
||
6032 | double_data[ii] = y; |
||
6033 | } |
||
6034 | } |
||
6035 | */ |
||
7614 | schaersvoo | 6036 | char *str_replace(const char *str, const char *old, const char *new){ |
18562 | bpr | 6037 | if(strlen(str) > MAX_BUFFER){canvas_error("string argument too big");} |
6038 | char *ret, *r; |
||
6039 | const char *p, *q; |
||
6040 | size_t oldlen = strlen(old); |
||
6041 | size_t count = 0; |
||
6042 | size_t retlen = 0; |
||
6043 | size_t newlen = strlen(new); |
||
6044 | if (oldlen != newlen){ |
||
6045 | for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen){ |
||
18552 | bpr | 6046 | count++; |
6047 | retlen = p - str + strlen(p) + count * (newlen - oldlen); |
||
18562 | bpr | 6048 | } |
18552 | bpr | 6049 | } |
18562 | bpr | 6050 | else { |
6051 | retlen = strlen(str); |
||
6052 | } |
||
6053 | if ((ret = malloc(retlen + 1)) == NULL){ |
||
6054 | ret = NULL; |
||
6055 | canvas_error("string argument is NULL"); |
||
6056 | } |
||
6057 | else |
||
6058 | { |
||
6059 | for (r = ret, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) { |
||
18552 | bpr | 6060 | size_t l = q - p; |
6061 | memcpy(r, p, l); |
||
6062 | r += l; |
||
6063 | memcpy(r, new, newlen); |
||
6064 | r += newlen; |
||
18562 | bpr | 6065 | } |
6066 | strcpy(r, p); |
||
18552 | bpr | 6067 | } |
18562 | bpr | 6068 | return ret; |
7614 | schaersvoo | 6069 | } |
6070 | |||
6071 | /******************************************************************************/ |
||
7848 | bpr | 6072 | |
7614 | schaersvoo | 6073 | char *get_color(FILE *infile , int last){ |
18562 | bpr | 6074 | int c,i = 0,is_hex = 0; |
6075 | char temp[MAX_COLOR_STRING], *string; |
||
6076 | const char *not_allowed = "0123456789"; |
||
6077 | while(( (c=getc(infile)) != EOF ) && ( c != '\n') && ( c != ',' ) && ( c != ';' ) && ( c != '\t' ) ){ |
||
6078 | if( i > MAX_COLOR_STRING ){ canvas_error("colour string is too big ... ? ");} |
||
6079 | if( c == '#' ){ |
||
18552 | bpr | 6080 | is_hex = 1; |
18562 | bpr | 6081 | } |
6082 | if( c != ' '){ |
||
18552 | bpr | 6083 | if( is_hex == 0 ){if(strchr(not_allowed,c) != 0){canvas_error("found something like a number...but is should have been a colour or #hex color number...<br>Do not use R,G,B !!! ");}} |
6084 | temp[i]=tolower(c); |
||
6085 | i++; |
||
18562 | bpr | 6086 | } |
18552 | bpr | 6087 | } |
18562 | bpr | 6088 | if( ( c == '\n' || c == EOF || c == ';' || c == '\t' ) && last == 0){canvas_error("expecting more arguments in command");} |
6089 | if( c == '\n' || c == ';' || c == '\t' ){ done = TRUE; line_number++; } |
||
6090 | if( c == EOF ){finished = 1;} |
||
6091 | if( finished == 1 && last != 1 ){ canvas_error("expected more arguments");} |
||
6092 | temp[i]='\0'; |
||
6093 | if( strlen(temp) == 0 ){ canvas_error("expected a colorname or hexnumber, but found nothing !!");} |
||
6094 | if( is_hex == 1 ){ |
||
6095 | char red[3], green[3], blue[3]; |
||
6096 | red[0] = toupper(temp[1]); red[1] = toupper(temp[2]); red[2] = '\0'; |
||
6097 | green[0] = toupper(temp[3]); green[1] = toupper(temp[4]); green[2] = '\0'; |
||
6098 | blue[0] = toupper(temp[5]); blue[1] = toupper(temp[6]); blue[2] = '\0'; |
||
6099 | int r = (int) strtol(red, NULL, 16); |
||
6100 | int g = (int) strtol(green, NULL, 16); |
||
6101 | int b = (int) strtol(blue, NULL, 16); |
||
6102 | int L0 = 1+snprintf(NULL,0,"%d,%d,%d",r,g,b); |
||
6103 | string = my_newmem(L0); |
||
6104 | snprintf(string,L0,"%d,%d,%d",r,g,b); |
||
6105 | return string; |
||
6106 | } |
||
6107 | else |
||
6108 | { |
||
6109 | string = (char *)my_newmem(sizeof(temp)); |
||
6110 | snprintf(string,sizeof(temp),"%s",temp); |
||
6111 | for( i = 0; i < NUMBER_OF_COLORNAMES ; i++ ){ |
||
18552 | bpr | 6112 | if( strcmp( colors[i].name , string ) == 0 ){ |
18562 | bpr | 6113 | return colors[i].rgb; |
18552 | bpr | 6114 | } |
18562 | bpr | 6115 | } |
6116 | canvas_error("I was expecting a color name or hexnumber...but found nothing."); |
||
18552 | bpr | 6117 | } |
18562 | bpr | 6118 | return "0,0,255"; |
7614 | schaersvoo | 6119 | } |
6120 | |||
14066 | bpr | 6121 | char *get_string(FILE *infile,int last){ /* last = 0: more arguments ; last=1 final argument */ |
18562 | bpr | 6122 | int c,i=0; |
6123 | char temp[MAX_BUFFER], *string; |
||
6124 | while(( (c=getc(infile)) != EOF ) && ( c != '\n') && ( c != '\t') ){ |
||
6125 | temp[i]=c; |
||
6126 | i++; |
||
6127 | if(i > MAX_BUFFER){ canvas_error("string size too big...repeat command to fit string");break;} |
||
6128 | } |
||
6129 | if( ( c == '\n' || c == '\t' || c == EOF ) && last == 0){ |
||
6130 | canvas_error("expecting more arguments in command");} |
||
6131 | if( c == '\n' || c == '\t') { done = TRUE; line_number++; } |
||
6132 | if( c == EOF ) {finished = 1;} |
||
6133 | temp[i]='\0'; |
||
6134 | if( strlen(temp) == 0 && last != 3 ){ |
||
6135 | canvas_error("expected a word or string, but found nothing!");} |
||
6136 | string=(char *)my_newmem(strlen(temp)); |
||
6137 | snprintf(string,sizeof(temp),"%s",temp); |
||
6138 | return string; |
||
7614 | schaersvoo | 6139 | } |
6140 | |||
14066 | bpr | 6141 | char *get_string_argument(FILE *infile,int last){ /* last = 0: more arguments ; last=1 final argument */ |
18562 | bpr | 6142 | int c,i=0; |
6143 | char temp[MAX_BUFFER], *string; |
||
6144 | while(( (c=getc(infile)) != EOF ) && ( c != '\n') && ( c != '\t') && ( c != ',')){ |
||
6145 | temp[i]=c; |
||
6146 | i++; |
||
6147 | if(i > MAX_BUFFER){ canvas_error("string size too big...will cut it off");break;} |
||
6148 | } |
||
6149 | if( ( c == '\n' || c == EOF) && last == 0){canvas_error("expecting more arguments in command");} |
||
6150 | if( c == '\n' || c == '\t' ) { line_number++; } |
||
6151 | if( c == EOF ) {finished = 1;} |
||
6152 | if( finished == 1 && last == 0 ){ canvas_error("expected more arguments");} |
||
6153 | temp[i]='\0'; |
||
10953 | bpr | 6154 | /* |
18562 | bpr | 6155 | 17.10.2014 removed (question Perrin) |
6156 | may cause some unwanted effects... |
||
6157 | if( strlen(temp) == 0 ){ canvas_error("expected a word or string (without comma), but found nothing !!");} |
||
8322 | schaersvoo | 6158 | */ |
18562 | bpr | 6159 | string=(char *)my_newmem(sizeof(temp)); |
6160 | snprintf(string,sizeof(temp),"%s",temp); |
||
6161 | done = TRUE; |
||
6162 | return string; |
||
7614 | schaersvoo | 6163 | } |
6164 | |||
14066 | bpr | 6165 | double get_real(FILE *infile, int last){ /* accept anything that looks like an number ? last = 0: more arguments ; last=1 final argument */ |
18562 | bpr | 6166 | int c,i=0,found_calc = 0; |
6167 | double y; |
||
6168 | char tmp[MAX_INT]; |
||
6169 | /* |
||
6170 | these things are 'allowed functions': *,^,+,-,/,(,),e,arc,cos,tan,pi,log,ln,sqrt,abs |
||
6171 | but there should be a better way to avoid segfaults ! |
||
6172 | */ |
||
6173 | const char *allowed = "earcostanpilogqb*+-/^()";/* assuming these are allowed stuff in a 'number'*/ |
||
6174 | const char *not_allowed = "#dfhjkmuvwxyz{}[]%&~!$";/* avoid segmentation faults in a "atof()" and "wims eval" */ |
||
6175 | while(( (c=getc(infile)) != EOF ) && ( c != ',') && (c != '\n') && (c != '\t') && ( c != ';')){ |
||
6176 | if( c != ' ' ){ |
||
8224 | bpr | 6177 | if( i == 0 && c == '+' ){ |
18562 | bpr | 6178 | continue; |
8224 | bpr | 6179 | } |
7614 | schaersvoo | 6180 | else |
6181 | { |
||
18562 | bpr | 6182 | c = tolower(c); |
6183 | if( strchr(not_allowed,c) != 0 ){canvas_error("found a character not associated with a number...");} |
||
6184 | if( strchr(allowed,c) != 0 ){found_calc = 1;}/* hand the string over to wims eval() */ |
||
6185 | tmp[i] = c; |
||
6186 | i++; |
||
7614 | schaersvoo | 6187 | } |
6188 | } |
||
18562 | bpr | 6189 | if( i > MAX_INT - 1){canvas_error("number too large");} |
6190 | } |
||
6191 | if( ( c == '\n' || c == EOF || c == ';' || c == '\t' ) && last == 0){canvas_error("expecting more arguments in command");} |
||
6192 | if( c == '\n' || c == ';' || c == '\t' ){ done = TRUE; line_number++; } |
||
6193 | if( c == EOF ){done = TRUE ; finished = 1;} |
||
6194 | tmp[i]='\0'; |
||
6195 | if( strlen(tmp) == 0 ){canvas_error("expected a number, but found nothing !!");} |
||
6196 | if( found_calc == 1 ){ /* use wims eval to calculate 2*pi/3 */ |
||
6197 | void *f = eval_create(tmp); |
||
6198 | assert(f);if( f == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;} |
||
6199 | y = eval_x(f, 1); |
||
6200 | /* if function is bogus; y = 1: so no core dumps */ |
||
6201 | eval_destroy(f); |
||
6202 | } |
||
6203 | else |
||
6204 | { |
||
6205 | y = atof(tmp); |
||
6206 | } |
||
6207 | return y; |
||
7614 | schaersvoo | 6208 | } |
6209 | void canvas_error(char *msg){ |
||
18562 | bpr | 6210 | fprintf(stdout,"\n</script><hr><span style=\"color:red\">FATAL syntax error: line %d: %s</span><hr>",line_number,msg); |
6211 | finished = 1; |
||
6212 | exit(EXIT_SUCCESS); |
||
7614 | schaersvoo | 6213 | } |
6214 | /* convert x/y coordinates to pixel */ |
||
6215 | int x2px(double x){ |
||
18606 | bpr | 6216 | int res=(x-xmin)/(xmax-xmin)*xsize; |
6217 | return (res==xsize)?xsize-1:res; |
||
7614 | schaersvoo | 6218 | } |
6219 | int y2px(double y){ |
||
18606 | bpr | 6220 | int res=(ymax-y)/(ymax-ymin)*ysize; |
6221 | return (res==ysize)?ysize-1:res; |
||
7614 | schaersvoo | 6222 | } |
6223 | double px2x(int x){ |
||
18562 | bpr | 6224 | return (x*(xmax - xmin)/xsize + xmin); |
7614 | schaersvoo | 6225 | } |
6226 | double px2y(int y){ |
||
18562 | bpr | 6227 | return (y*(ymax - ymin)/ysize + ymin); |
7614 | schaersvoo | 6228 | } |
6229 | void add_to_buffer(char *tmp){ |
||
17351 | bpr | 6230 | //fprintf(stdout,"tmp = %s<br>buffer = %s<br>",tmp,buffer); |
18562 | bpr | 6231 | if( tmp == NULL || tmp == 0 ){ canvas_error("nothing to add_to_buffer()...");} |
6232 | /* do we have enough space left in buffer[MAX_BUFFER] ? */ |
||
6233 | int space_left = (int) (sizeof(buffer) - strlen(buffer)); |
||
6234 | if( space_left > strlen(tmp)){ |
||
6235 | strncat(buffer,tmp,space_left - 1);/* add safely "tmp" to the string buffer */ |
||
6236 | } |
||
6237 | else |
||
6238 | { |
||
6239 | canvas_error("your memory buffer is too big<br>simplify your script...it produces too many lines "); |
||
6240 | } |
||
6241 | tmp = NULL;free(tmp); |
||
6242 | return; |
||
7614 | schaersvoo | 6243 | } |
6244 | void reset(){ |
||
18562 | bpr | 6245 | if(no_reset == FALSE){ /* 8/5/2020 */ |
6246 | use_filled = FALSE; |
||
6247 | use_dashed = FALSE; |
||
6248 | if(onclick != 4 ){onclick = 0;} /* slider param 'active'... onclick=4 */ |
||
6249 | drag_type = -1; |
||
6250 | use_offset = 0; |
||
18623 | bpr | 6251 | fillcolor = FALSE; |
18562 | bpr | 6252 | } |
7614 | schaersvoo | 6253 | } |
15111 | schaersvoo | 6254 | char *getMML(char *tex){ |
18562 | bpr | 6255 | int my_pipe[2];pid_t pid; |
6256 | if(pipe(my_pipe)){canvas_error("mathml(): pipe() failure.\n");} |
||
15111 | schaersvoo | 6257 | pid = fork(); |
6258 | if (pid == (pid_t) 0){ |
||
18562 | bpr | 6259 | char *argv[]={"wims_mathml","--use-zoom","0","--tex-size 100%","--max-mml-size","1024","--tex-string",tex,NULL}; |
6260 | close(my_pipe[0]);dup2(my_pipe[1], 1);dup2(my_pipe[1], 2);close(my_pipe[1]); |
||
6261 | execv("../bin/wims_mathml",argv);canvas_error("could not execute wims_mathml\n"); |
||
15111 | schaersvoo | 6262 | } |
6263 | else |
||
15116 | bpr | 6264 | { |
18562 | bpr | 6265 | if (pid < (pid_t) 0){ |
6266 | close(my_pipe[0]);close(my_pipe[1]);canvas_error("mathml(): fork() failure.\n"); |
||
6267 | } |
||
6268 | int status;FILE *stream;close(my_pipe[1]);stream = fdopen (my_pipe[0], "r"); |
||
6269 | char buffer[MAX_BUFFER+1];memset(buffer,'\0',MAX_BUFFER); |
||
6270 | fgets(buffer, MAX_BUFFER, stream); |
||
6271 | int L0 = 1 + snprintf(NULL,0,"%s", buffer); |
||
6272 | tex = my_newmem(L0);memset(tex,'\0',L0); |
||
6273 | snprintf(tex,L0,"%s",buffer); |
||
6274 | fclose (stream);close(my_pipe[0]);waitpid(pid, &status, 0); |
||
15111 | schaersvoo | 6275 | } |
18562 | bpr | 6276 | return tex; |
15111 | schaersvoo | 6277 | } |
7614 | schaersvoo | 6278 | |
15111 | schaersvoo | 6279 | char *getSVGMOL(char *inputtype,char *keys){ |
6280 | int idx; |
||
6281 | char *forbidden[] = {"-O","-H","-z","-L","-o","-m"}; |
||
6282 | char *argv[1+strlen(keys)]; |
||
6283 | argv[0] = "obabel"; argv[1] = "-i"; argv[2] = inputtype; |
||
6284 | idx = 3;int i; |
||
6285 | char *ptr = strtok(keys,","); |
||
6286 | while(ptr != NULL ){ |
||
6287 | for(i = 0 ; i < 6; i++ ){if( strncmp(ptr,forbidden[i],2) == 0 ){return "NOT ALLOWED ARGUMENT";}} |
||
6288 | argv[idx] = ptr; idx++; |
||
17351 | bpr | 6289 | if(idx > 18){canvas_error("too many arguments for obabel....see docs<br>");} |
15111 | schaersvoo | 6290 | ptr = strtok(NULL,","); |
6291 | } |
||
6292 | /* last arguments; no 'javascript', only 'svg to STDOUT' and 'NULL' */ |
||
6293 | argv[idx] = "-xj";argv[idx+1] = "-o"; argv[idx+2] = "svg";argv[idx+3] = NULL; |
||
6294 | int link[2]; |
||
6295 | pid_t pid; |
||
6296 | char buffer[MAX_BUFFER+1]; |
||
6297 | memset(buffer,'\0',MAX_BUFFER); |
||
6298 | if (pipe(link)==-1){canvas_error("pipe");} |
||
6299 | if ((pid = fork()) == -1){canvas_error("fork");} |
||
15116 | bpr | 6300 | |
15111 | schaersvoo | 6301 | char *svgmol = "error"; |
6302 | int string_length = 0; |
||
15116 | bpr | 6303 | |
15111 | schaersvoo | 6304 | if(pid == 0) { |
6305 | dup2 (link[1], STDOUT_FILENO); |
||
6306 | dup2(link[0], STDERR_FILENO);/* remove annoying messages '1 molecule converted' */ |
||
6307 | close(link[0]); |
||
6308 | close(link[1]); |
||
6309 | execvp("obabel",argv); |
||
6310 | } else { |
||
6311 | close(link[1]); |
||
18109 | schaersvoo | 6312 | read(link[0],buffer, sizeof(buffer)); |
15111 | schaersvoo | 6313 | close(link[0]); |
6314 | /* need to remover newline from svg-string on freebsd */ |
||
6315 | char *pch = strstr(buffer, "\n"); |
||
6316 | while(pch != NULL){ |
||
18555 | bpr | 6317 | strncpy(pch, " ", 1); |
6318 | pch = strstr(buffer, "\n"); |
||
15111 | schaersvoo | 6319 | } |
6320 | string_length = 1 + snprintf(NULL,0,"%s",buffer); |
||
6321 | svgmol= my_newmem(string_length); |
||
6322 | snprintf(svgmol,string_length,"%s",buffer); |
||
6323 | wait(NULL); |
||
6324 | } |
||
18562 | bpr | 6325 | return svgmol; |
15111 | schaersvoo | 6326 | } |
6327 | /* GNU libmatheval library for evaluating mathematical functions. */ |
||
15601 | schaersvoo | 6328 | char *eval(int xsize,int ysize,char *fun,double xmin,double xmax,double ymin,double ymax,int plotsteps,int precision,double rotationcenter[]){ |
18555 | bpr | 6329 | void *f; |
6330 | double x; |
||
6331 | double y; |
||
6332 | double xorg; |
||
6333 | int xv; |
||
6334 | int i = 0; |
||
6335 | int xstep =(int)(xsize/plotsteps); |
||
6336 | if( xstep == 0 ){xstep = 1;} |
||
6337 | double a = (xmax - xmin)/xsize; |
||
6338 | f = eval_create(fun); |
||
6339 | assert (f); |
||
6340 | if( f == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;} |
||
6341 | /* we supply the true x/y values...draw_curve() will convert these (x:y) to pixels : used for pan/scale */ |
||
6342 | double xydata[MAX_BUFFER+1];/* hmmm */ |
||
6343 | int lim_ymin =(int)( ymin - 4*fabs(ymin));/* 19-4-2015 replacing "abs" by "fabs"*/ |
||
6344 | int lim_ymax =(int)( ymax + 4*fabs(ymax));/* 19-4-2015 replacing "abs" by "fabs"*/ |
||
6345 | double c = 1.0;double s = 1.0; |
||
6346 | if( use_rotate == TRUE ){s = sin(angle*0.0174533);c = cos(angle*0.0174533);} |
||
6347 | for ( xv = 0 ;xv < xsize ; xv = xv+xstep ){ |
||
18562 | bpr | 6348 | x = (double) (xv*a + xmin); |
6349 | xorg = x; |
||
6350 | if( i < MAX_BUFFER - 2){ |
||
18552 | bpr | 6351 | y = eval_x(f, x); |
6352 | if(y < lim_ymax && y > lim_ymin ){ |
||
18562 | bpr | 6353 | if( use_affine == TRUE ){ |
6354 | x = x*affine_matrix[0] + y*affine_matrix[1]+affine_matrix[4]; |
||
6355 | y = xorg*affine_matrix[2] + y*affine_matrix[3]+affine_matrix[5]; |
||
6356 | } |
||
6357 | if( use_rotate == TRUE){ |
||
6358 | x = (c * (x - rotationcenter[0])) + (s * (y - rotationcenter[1])) + rotationcenter[0]; |
||
6359 | y = (c * (y - rotationcenter[1])) - (s * (xorg - rotationcenter[0])) + rotationcenter[1]; |
||
6360 | } |
||
6361 | xydata[i++] = x; |
||
18552 | bpr | 6362 | xydata[i++] = y; |
6363 | } |
||
18562 | bpr | 6364 | } |
6365 | else |
||
6366 | { |
||
18552 | bpr | 6367 | canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps or some other means to reduce the amount of data... "); |
18562 | bpr | 6368 | } |
18552 | bpr | 6369 | } |
18562 | bpr | 6370 | eval_destroy(f); |
6371 | return double_xy2js_array(xydata,i,find_number_of_digits(precision)); |
||
15111 | schaersvoo | 6372 | } |
6373 | /* plot a very primitive (!) levelcurve : not to be compared with "flydraw levelcurve" */ |
||
6374 | char *eval_levelcurve(int xsize,int ysize,char *fun,double xmin,double xmax,double ymin,double ymax,int plotsteps,int precision,double level){ |
||
18562 | bpr | 6375 | void *f = eval_create(fun); |
6376 | assert (f); |
||
6377 | if( f == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;} |
||
6378 | double a = (double)((xmax - xmin)/plotsteps); |
||
6379 | double b = (double)((ymax - ymin)/plotsteps); |
||
6380 | double x;double y;double diff; |
||
6381 | double xydata[MAX_BUFFER+1]; |
||
6382 | int i = 0; |
||
6383 | ymin = ymin - 1; |
||
6384 | xmin = xmin - 1; |
||
6385 | ymax = ymax + 1; |
||
6386 | xmax = xmax + 1; |
||
6387 | for( x = xmin ;x < xmax ; x = x + a ){ |
||
6388 | for ( y = ymin ;y < ymax ; y = y + b ){ |
||
18552 | bpr | 6389 | if( i < MAX_BUFFER - 2){ |
18562 | bpr | 6390 | diff = level - eval_x_y(f, x,y); |
6391 | if(diff < 0.1 && diff > -0.1){ |
||
6392 | xydata[i++] = x; |
||
6393 | xydata[i++] = y; |
||
6394 | } |
||
18552 | bpr | 6395 | } |
6396 | else |
||
6397 | { |
||
18562 | bpr | 6398 | canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps, decrease image size...\nor some other means to reduce the amount of data... "); |
18552 | bpr | 6399 | } |
18562 | bpr | 6400 | } |
18552 | bpr | 6401 | } |
18562 | bpr | 6402 | eval_destroy(f); |
6403 | return double_xy2js_array(xydata,i,find_number_of_digits(precision)); |
||
15111 | schaersvoo | 6404 | } |
7614 | schaersvoo | 6405 | |
15111 | schaersvoo | 6406 | /* plot parametric function */ |
18562 | bpr | 6407 | char *eval_parametric(int xsize,int ysize,char *fun1,char* fun2,double xmin, |
6408 | double xmax,double ymin,double ymax, |
||
6409 | double tmin,double tmax,int plotsteps,int precision,double rotationcenter[]){ |
||
6410 | void *fx; |
||
6411 | void *fy; |
||
6412 | double t; |
||
6413 | int i = 0; |
||
6414 | double tstep = (tmax-tmin)/plotsteps; |
||
6415 | if( tstep == 0 ){canvas_error("zero step for t variable : reduce plotsteps or inrease trange");} |
||
6416 | fx = eval_create(fun1); |
||
6417 | fy = eval_create(fun2); |
||
6418 | assert(fx); |
||
6419 | assert(fy); |
||
6420 | if( fx == NULL || fy == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;} |
||
15111 | schaersvoo | 6421 | /* we supply the true x/y values...draw_curve() will convert these (x:y) to pixels : used for pan/scale */ |
18562 | bpr | 6422 | double xydata[MAX_BUFFER+1];/* hmmm */ |
6423 | double x; /* real x-values */ |
||
6424 | double y; /* real y-values */ |
||
6425 | double xorg; |
||
6426 | /* |
||
6427 | 29/12/2020 |
||
6428 | disabled to try and synchronise curve+affine behaviour in complex scripts produced by "elec, tool circuit" (BPR) |
||
15623 | schaersvoo | 6429 | int lim_ymin =(int)( ymin - 4*fabs(ymin)); |
6430 | int lim_ymax =(int)( ymax + 4*fabs(ymax)); |
||
6431 | */ |
||
18562 | bpr | 6432 | double c = 1.0;double s = 1.0; |
6433 | if( use_rotate == TRUE ){s = sin(angle*0.0174533);c = cos(angle*0.0174533);} |
||
6434 | for( t = tmin ;t <= tmax ; t = t + tstep ){ |
||
6435 | if( i < MAX_BUFFER - 2 ){ |
||
18552 | bpr | 6436 | y = eval_t(fy, t); |
6437 | /* if(y > lim_ymin && y < lim_ymax){*/ |
||
18562 | bpr | 6438 | x = eval_t(fx, t); |
6439 | if( x == x){ /* no NaN */ |
||
6440 | xorg = x; |
||
6441 | if( use_affine == TRUE ){ |
||
6442 | x = x*affine_matrix[0] + y*affine_matrix[1]+affine_matrix[4]; |
||
6443 | y = xorg*affine_matrix[2] + y*affine_matrix[3]+affine_matrix[5]; |
||
6444 | } |
||
6445 | if( use_rotate == TRUE){ |
||
6446 | x = (c * (x - rotationcenter[0])) + (s * (y - rotationcenter[1])) + rotationcenter[0]; |
||
6447 | y = (c * (y - rotationcenter[1])) - (s * (xorg - rotationcenter[0])) + rotationcenter[1]; |
||
6448 | } |
||
6449 | xydata[i++] = x; |
||
6450 | xydata[i++] = y; |
||
6451 | } |
||
6452 | /* } */ |
||
18552 | bpr | 6453 | } |
18562 | bpr | 6454 | else |
6455 | { |
||
18552 | bpr | 6456 | canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps or some other means to reduce the amount of data... "); |
18562 | bpr | 6457 | } |
18552 | bpr | 6458 | } |
18562 | bpr | 6459 | eval_destroy(fx); |
6460 | eval_destroy(fy); |
||
6461 | return double_xy2js_array(xydata,i,find_number_of_digits(precision)); |
||
15111 | schaersvoo | 6462 | } |
7614 | schaersvoo | 6463 | |
15111 | schaersvoo | 6464 | char *double_xy2js_array(double xy[],int len,int decimals){ |
6465 | /* |
||
6466 | 1,2,3,4,5,6,7,8 --> [1,3,5,7],[2,4,6,8] |
||
6467 | int xy[] is already checked for errors or overflow in "get_real()" |
||
6468 | just to be sure we double check the size of "temp" |
||
7614 | schaersvoo | 6469 | */ |
18562 | bpr | 6470 | char temp[2*MAX_BUFFER], *string; |
6471 | char *tmp = my_newmem(16);/* <= 9999999999999999 */ |
||
6472 | memset(temp,'\0',2*MAX_BUFFER);/* clear memory */ |
||
6473 | int i;int space_left; |
||
6474 | temp[0] = '[';/* start js-array */ |
||
6475 | for(i = 0; i < len;i = i + 2){ /* x_points[] */ |
||
6476 | if(i == len - 2){sprintf(tmp, "%.*f",decimals, xy[i]);} |
||
6477 | else {sprintf(tmp, "%.*f,",decimals,xy[i]);} |
||
6478 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6479 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);} |
||
6480 | else{ |
||
6481 | canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce your image size or plotsteps ");} |
||
15111 | schaersvoo | 6482 | } |
6483 | strncat(temp,"],[",4); /* close js x_values array and start new */ |
||
6484 | for(i = 1; i < len;i = i + 2){ /* y_points */ |
||
18557 | bpr | 6485 | if(i == len - 1){ sprintf(tmp, "%.*f",decimals,xy[i]);}else{sprintf(tmp, "%.*f,",decimals,xy[i]);} |
6486 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6487 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce your image size or plotsteps");} |
||
15111 | schaersvoo | 6488 | } |
6489 | strncat(temp,"]",2); |
||
6490 | string=(char *)my_newmem(sizeof(temp)); |
||
6491 | snprintf(string,sizeof(temp),"%s",temp); |
||
6492 | return string; |
||
6493 | } |
||
7614 | schaersvoo | 6494 | |
15111 | schaersvoo | 6495 | char *list2js_array(char *list, char *s){/* abc:defg:hjiuy:qwer --> ["abc","defg","hjiuy","qwer"] */ |
6496 | #define MAX_ARG 128 |
||
18562 | bpr | 6497 | if( strlen(list)> MAX_ARG - 1){canvas_error("argument is too large (> 128)");} |
6498 | char tmp[MAX_ARG]; |
||
6499 | size_t p = 0; |
||
6500 | tmp[0] = '['; |
||
6501 | tmp[1] = '\"'; |
||
6502 | size_t t = 2; |
||
6503 | while(list[p] != '\0'){ |
||
6504 | if( list[p] == s[0] ){ |
||
6505 | tmp[t++]='\"';tmp[t++]=',';tmp[t++]='\"'; |
||
6506 | } |
||
6507 | else |
||
6508 | { |
||
6509 | tmp[t++] = list[p]; |
||
6510 | } |
||
6511 | p++; |
||
15111 | schaersvoo | 6512 | } |
18562 | bpr | 6513 | tmp[t++]='\"';tmp[t++]=']';tmp[t++]= '\0'; |
6514 | char *js_array = (char *)my_newmem(sizeof(tmp)); |
||
6515 | snprintf(js_array,sizeof(tmp),"%s",tmp); |
||
6516 | return js_array; |
||
15111 | schaersvoo | 6517 | } |
7963 | schaersvoo | 6518 | |
15111 | schaersvoo | 6519 | char *xy2js_array(int xy[],int len){ |
6520 | /* |
||
6521 | 1,2,3,4,5,6,7,8 --> [1,3,5,7],[2,4,6,8] |
||
6522 | int xy[] is already checked for errors or overflow in "get_real()" |
||
6523 | just to be sure we double check the size of "temp" |
||
7614 | schaersvoo | 6524 | */ |
18562 | bpr | 6525 | char temp[MAX_BUFFER], *string; |
6526 | char *tmp = my_newmem(16);/* <= 9999999999999999 */ |
||
6527 | memset(temp,'\0',MAX_BUFFER);/* clear memory */ |
||
6528 | int i;int space_left; |
||
6529 | temp[0] = '[';/* start js-array */ |
||
6530 | for(i = 0; i < len;i = i + 2){ /* x_points[] */ |
||
6531 | if(i == len - 2){sprintf(tmp, "%d", xy[i]);}else{sprintf(tmp, "%d,", xy[i]);} |
||
6532 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6533 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);} |
||
6534 | else { |
||
6535 | canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce image size or plotsteps ");} |
||
6536 | } |
||
6537 | strncat(temp,"],[",4); /* close js x_values array and start new */ |
||
6538 | for(i = 1; i < len;i = i + 2){ /* y_points */ |
||
6539 | if(i == len - 1){ sprintf(tmp, "%d", xy[i]);}else{sprintf(tmp, "%d,", xy[i]);} |
||
6540 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6541 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);} |
||
6542 | else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data\nreduce image size or plotsteps \n");} |
||
6543 | } |
||
6544 | strncat(temp,"]",2); |
||
6545 | string=(char *)my_newmem(sizeof(temp)); |
||
6546 | snprintf(string,sizeof(temp),"%s",temp); |
||
6547 | return string; |
||
7614 | schaersvoo | 6548 | } |
6549 | |||
15111 | schaersvoo | 6550 | char *data2js_array(int data[],int len){ |
6551 | /* |
||
6552 | 1,2,3,4,5,6,7,8 --> [1,2,3,4,5,6,7,8] |
||
6553 | int data[] is already checked for errors or overflow in "get_real()" |
||
6554 | just to be sure we double check the size of "temp" |
||
7614 | schaersvoo | 6555 | */ |
18562 | bpr | 6556 | char temp[MAX_BUFFER], *string; |
6557 | char *tmp = my_newmem(16);/* <= 9999999999999999 */ |
||
6558 | memset(temp,'\0',MAX_BUFFER);/* clear memory */ |
||
6559 | int i;int space_left; |
||
6560 | temp[0] = '[';/* start js-array */ |
||
6561 | for(i = 0; i < len; i++){ |
||
6562 | if(i == len - 1){sprintf(tmp, "%d", data[i]);}else{sprintf(tmp, "%d,", data[i]);} |
||
6563 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6564 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);} |
||
6565 | else{ |
||
6566 | canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce image size or plotsteps "); |
||
15111 | schaersvoo | 6567 | } |
18562 | bpr | 6568 | } |
6569 | strncat(temp,"]",2); |
||
6570 | string=(char *)my_newmem(sizeof(temp)); |
||
6571 | snprintf(string,sizeof(temp),"%s",temp); |
||
6572 | return string; |
||
15111 | schaersvoo | 6573 | } |
7614 | schaersvoo | 6574 | |
15111 | schaersvoo | 6575 | char *doubledata2js_array(double data[],int len, int decimals){ |
6576 | /* |
||
15116 | bpr | 6577 | 1.4355,2.345353,3.3455 --> [1.44,2.35,3.35] |
15111 | schaersvoo | 6578 | double data[] is already checked for errors or overflow in "get_real()" |
6579 | just to be sure we double check the size of "temp" |
||
8448 | schaersvoo | 6580 | */ |
18562 | bpr | 6581 | char temp[MAX_BUFFER], *string; |
6582 | char *tmp = my_newmem(16);/* <= 9999999999999999 */ |
||
6583 | memset(temp,'\0',MAX_BUFFER);/* clear memory */ |
||
6584 | int i;int space_left; |
||
6585 | temp[0] = '[';/* start js-array */ |
||
6586 | for(i = 0; i < len; i++){ |
||
6587 | if(i == len - 1){sprintf(tmp, "%.*f",decimals,data[i]);} |
||
6588 | else{sprintf(tmp, "%.*f,",decimals,data[i]);} |
||
6589 | space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1); |
||
6590 | if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);} |
||
6591 | else{ |
||
6592 | canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce image size or plotsteps ");} |
||
6593 | } |
||
6594 | strncat(temp,"]",2); |
||
6595 | string=(char *)my_newmem(sizeof(temp)); |
||
6596 | snprintf(string,sizeof(temp),"%s",temp); |
||
6597 | return string; |
||
15111 | schaersvoo | 6598 | } |
13829 | bpr | 6599 | |
15111 | schaersvoo | 6600 | void *my_newmem(size_t size){ |
18562 | bpr | 6601 | void *p; |
6602 | if((p = malloc(size +1)) == NULL){canvas_error("canvasdraw: ran out of memory\n");} |
||
6603 | return p; |
||
15111 | schaersvoo | 6604 | } |
8224 | bpr | 6605 | |
15111 | schaersvoo | 6606 | int find_number_of_digits(int i){ |
18562 | bpr | 6607 | if(i < 0 ){ i = -1*i;} |
6608 | int digits = 0; |
||
6609 | while ( i > 0){ |
||
6610 | digits++; |
||
6611 | i = i/10; |
||
6612 | } |
||
6613 | return digits; |
||
15111 | schaersvoo | 6614 | } |
7645 | schaersvoo | 6615 | |
16828 | schaersvoo | 6616 | int count_substring(char* string, char* substring) { |
18164 | schaersvoo | 6617 | int i, j, l1, l2; |
16828 | schaersvoo | 6618 | int count = 0; |
6619 | l1 = strlen(string); |
||
6620 | l2 = strlen(substring); |
||
6621 | for(i = 0; i < l1 - l2 + 1; i++) { |
||
6622 | if(strstr(string + i, substring) == string + i) { |
||
6623 | count++; |
||
6624 | i = i + l2 -1; |
||
6625 | } |
||
6626 | } |
||
6627 | return count; |
||
6628 | } |
||
11830 | schaersvoo | 6629 | |
7614 | schaersvoo | 6630 | void check_string_length(int L){ |
18555 | bpr | 6631 | if( L > MAX_BUFFER-1){ |
6632 | canvas_error("problem with your arguments to command..."); |
||
6633 | } |
||
6634 | return; |
||
7614 | schaersvoo | 6635 | } |
18555 | bpr | 6636 | /* useful in hyp commands: determine if the hypsegment is an arc or a line */ |
18615 | bpr | 6637 | /* give a point on the arc */ |
18555 | bpr | 6638 | int hypgeodaux(double *q, double* ress, int full){ |
6639 | double alpha,beta,gamma,r,cx,cy,a1,a2,a3,tmp, |
||
6640 | nx = -q[0]*q[2]*q[2]+(q[0]*q[0]+q[1]*q[1]+1)*q[2]-q[0]*q[3]*q[3]-q[0], |
||
6641 | ny = -q[1]*q[2]*q[2]-q[1]*q[3]*q[3]+(q[0]*q[0]+q[1]*q[1]+1)*q[3]-q[1], |
||
6642 | dy = -2*q[1]*q[2]+2*q[0]*q[3]; |
||
6643 | if (dy*dy*1e4 <= nx*nx+ny*ny){ |
||
6644 | if(full){ |
||
6645 | if (q[1]*q[1]+q[0]*q[0] > q[2]*q[2]+q[3]*q[3]) |
||
6646 | gamma = atan2(q[1],q[0]); |
||
6647 | else |
||
6648 | gamma = atan2(q[3],q[2]); |
||
6649 | ress[0]=cos(gamma); ress[1]=sin(gamma); ress[2]=-cos(gamma); ress[3]=-sin(gamma); |
||
6650 | } |
||
6651 | else |
||
6652 | {int i;for(i=0;i<4;++i) ress[i]=q[i];} |
||
18615 | bpr | 6653 | ress[6]=(q[0]+q[2])/2; |
6654 | ress[7]=(q[1]+q[3])/2; |
||
18555 | bpr | 6655 | return 0;} |
6656 | cx = ny/dy; cy=-nx/dy; |
||
6657 | r = sqrt(cx*cx+cy*cy-1); |
||
6658 | if(full) |
||
6659 | {alpha=atan(1/r); beta = atan2(cy,cx);a1=M_PI+beta-alpha;a2=M_PI+beta+alpha;} |
||
6660 | else |
||
6661 | {a1 = atan2(q[1]-cy, q[0]-cx);a2 = atan2(q[3]-cy, q[2]-cx);} |
||
6662 | if (fabs(a2-a1)>M_PI){if(a1<a2) a1+=2*M_PI; else a2+=2*M_PI;}; |
||
6663 | a3 = (a1+a2)/2; |
||
6664 | if(a1>a2) {tmp=a1; a1=a2; a2=tmp;} |
||
6665 | ress[0]=cx; |
||
6666 | ress[1]=cy; |
||
6667 | ress[2]=2*r; |
||
6668 | ress[3]=2*r; |
||
6669 | ress[4]=360+180/M_PI*a1; |
||
6670 | ress[5]=360+180/M_PI*a2; |
||
6671 | ress[6]=cx+r*cos(a3); |
||
6672 | ress[7]=cy+r*sin(a3); |
||
6673 | return 1; |
||
6674 | } |
||
7614 | schaersvoo | 6675 | |
6676 | int get_token(FILE *infile){ |
||
18589 | bpr | 6677 | int left,milieu,delta,right,c,i=0; |
18562 | bpr | 6678 | char temp[MAX_INT], *input_type; |
18589 | bpr | 6679 | enum{rien,usefilled,usedashed}; |
6680 | static struct commande {char *nom; int res; int special;} table[]= |
||
6681 | { |
||
6682 | {"#",COMMENT,0}, |
||
6683 | {"affine",AFFINE,0}, |
||
6684 | {"allowdups",ALLOW_DUPLICATES,0}, |
||
6685 | {"angle",ANGLE,0}, |
||
6686 | {"animate",ANIMATE,0}, |
||
6687 | {"arc",ARC,0}, |
||
6688 | {"arcarrow",ARCARROW,0}, |
||
6689 | {"arrow",ARROW,0}, |
||
6690 | {"arrow2",ARROW2,0}, |
||
6691 | {"arrowarc",ARCARROW,0}, |
||
6692 | {"arrowhead",ARROWHEAD,0}, |
||
6693 | {"arrows",ARROWS,0}, |
||
6694 | {"arrows2",ARROWS2,0}, |
||
6695 | {"audio",AUDIO,0}, |
||
6696 | {"audioobject",AUDIOOBJECT,0}, |
||
6697 | {"axis",AXIS,0}, |
||
6698 | {"axisnumbering",AXIS_NUMBERING,0}, |
||
6699 | {"axisnumbers",AXIS_NUMBERING,0}, |
||
6700 | {"backgroundimage",BGIMAGE,0}, |
||
6701 | {"barchart",BARCHART,0}, |
||
6702 | {"bezier",BEZIER,0}, |
||
6703 | {"bgcolor",BGCOLOR,0}, |
||
6704 | {"bgimage",BGIMAGE,0}, |
||
6705 | {"blink",BLINK,0}, |
||
6706 | {"boxplot",BOXPLOT,0}, |
||
6707 | {"boxplotdata",BOXPLOTDATA,0}, |
||
6708 | {"brokenline",POLYLINE,0}, |
||
6709 | {"canvastype",CANVASTYPE,0}, |
||
6710 | {"centered",CENTERED,0}, |
||
6711 | {"centerstring",CENTERSTRING,0}, |
||
6712 | {"chemtex",CHEMTEX,0}, |
||
6713 | {"circle",CIRCLE,0}, |
||
6714 | {"circles",CIRCLES,0}, |
||
6715 | {"clearbutton",CLEARBUTTON,0}, |
||
6716 | {"clicktile",CLICKTILE,0}, |
||
6717 | {"clicktile_colors",CLICKTILE_COLORS,0}, |
||
6718 | {"clock",CLOCK,0}, |
||
6719 | {"colorpalette",COLORPALETTE,0}, |
||
6720 | {"colors",MULTISTROKECOLORS,0}, |
||
6721 | {"copy",COPY,0}, |
||
6722 | {"copyresized",COPYRESIZED,0}, |
||
6723 | {"crosshair",CROSSHAIR,0}, |
||
6724 | {"crosshairs",CROSSHAIRS,0}, |
||
6725 | {"crosshairsize",CROSSHAIRSIZE,0}, |
||
6726 | {"css",CSS,0}, |
||
6727 | {"cursor",CURSOR,0}, |
||
6728 | {"curve",CURVE,0}, |
||
6729 | {"curvedarrow",CURVEDARROW,0}, |
||
6730 | {"curvedarrow2",CURVEDARROW2,0}, |
||
6731 | {"curvedarrows",CURVEDARROWS,0}, |
||
6732 | {"curvedarrows2",CURVEDARROWS2,0}, |
||
6733 | {"darrow",ARROW,usedashed}, |
||
6734 | {"darrow2",ARROW2,usedashed}, |
||
6735 | {"dashed",DASHED,0}, |
||
6736 | {"dashtype",DASHTYPE,0}, |
||
6737 | {"dcurve",CURVE,usedashed}, |
||
6738 | {"delete",CLEARBUTTON,0}, |
||
6739 | {"demiline",HALFLINE,0}, |
||
6740 | {"demilines",HALFLINES,0}, |
||
6741 | {"dhline",HLINE,usedashed}, |
||
6742 | {"diafill",DIAMONDFILL,0}, |
||
6743 | {"diamondfill",DIAMONDFILL,0}, |
||
6744 | {"disk",CIRCLE,usefilled}, |
||
6745 | {"disks",CIRCLES,usefilled}, |
||
6746 | {"display",MOUSE_DISPLAY,0}, |
||
6747 | {"dline",LINE,usedashed}, |
||
6748 | {"dotfill",DOTFILL,0}, |
||
6749 | {"dplot",CURVE,usedashed}, |
||
6750 | {"dpolyline",POLYLINE,usedashed}, |
||
6751 | {"drag",DRAG,0}, |
||
6752 | {"dsegment",SEGMENT,usedashed}, |
||
6753 | {"dsegments",SEGMENTS,usedashed}, |
||
6754 | {"duplicates",ALLOW_DUPLICATES,0}, |
||
6755 | {"dvline",VLINE,usedashed}, |
||
6756 | {"ellipse",ELLIPSE,0}, |
||
6757 | {"ellipses",ELLIPSES,0}, |
||
6758 | {"end",END,0}, |
||
6759 | {"erase",CLEARBUTTON,0}, |
||
6760 | {"farc",ARC,usefilled}, |
||
6761 | {"fcircle",CIRCLE,usefilled}, |
||
6762 | {"fcircles",CIRCLES,usefilled}, |
||
6763 | {"fellipse",ELLIPSE,usefilled}, |
||
6764 | {"fhypcircles",HYPCIRCLES,usefilled}, |
||
18615 | bpr | 6765 | {"fhyppolygon",HYPPOLY,usefilled}, |
18589 | bpr | 6766 | {"fill",FLOODFILL,0}, |
6767 | {"fillall",FILLALL,0}, |
||
6768 | {"fillcolor",FILLCOLOR,0}, |
||
6769 | {"fillcolors",MULTIFILLCOLORS,0}, |
||
6770 | {"filled",FILLED,0}, |
||
6771 | {"filledarc",ARC,usefilled}, |
||
6772 | {"filledpoly",POLY,usefilled}, |
||
6773 | {"filledpolygon",POLY,usefilled}, |
||
18608 | bpr | 6774 | {"fillopacity",FILLOPACITY,0}, |
18589 | bpr | 6775 | {"fillpattern",FILLPATTERN,0}, |
6776 | {"filltoborder",FILLTOBORDER,0}, |
||
6777 | {"floodfill",FLOODFILL,0}, |
||
6778 | {"fontcolor",FONTCOLOR,0}, |
||
6779 | {"fontfamily",FONTFAMILY,0}, |
||
6780 | {"fontsize",FONTSIZE,0}, |
||
6781 | {"fpoly",POLY,usefilled}, |
||
6782 | {"fpolygon",POLY,usefilled}, |
||
6783 | {"frect",RECT,usefilled}, |
||
6784 | {"frectangle",RECT,usefilled}, |
||
6785 | {"frects",RECTS,usefilled}, |
||
6786 | {"froundrect",ROUNDRECT,usefilled}, |
||
6787 | {"froundrects",ROUNDRECTS,usefilled}, |
||
6788 | {"fsquare",SQUARE,usefilled}, |
||
6789 | {"fsquares",RECTS,usefilled}, |
||
6790 | {"ftriangle",TRIANGLE,usefilled}, |
||
6791 | {"ftriangles",TRIANGLES,usefilled}, |
||
6792 | {"functionlabel",FUNCTION_LABEL,0}, |
||
6793 | {"functionlabels",FUNCTION_LABEL,0}, |
||
6794 | {"grid",GRID,0}, |
||
6795 | {"gridfill",GRIDFILL,0}, |
||
6796 | {"group",GROUP,0}, |
||
6797 | {"halfline",HALFLINE,0}, |
||
6798 | {"halflines",HALFLINES,0}, |
||
6799 | {"hatchfill",HATCHFILL,0}, |
||
6800 | {"highlight",STYLE,0}, |
||
6801 | {"hline",HLINE,0}, |
||
6802 | {"hlines",HLINES,0}, |
||
6803 | {"horizontalline",HLINE,0}, |
||
6804 | {"horizontallines",HLINES,0}, |
||
6805 | {"html",HTML,0}, |
||
6806 | {"http",HTTP,0}, |
||
6807 | {"hypcircles",HYPCIRCLES,0}, |
||
6808 | {"hyplines",HYPLINES,0}, |
||
6809 | {"hyppolygon",HYPPOLY,0}, |
||
6810 | {"hyprays",HYPRAYS,0}, |
||
6811 | {"hypsegments",HYPSEGMENTS,0}, |
||
6812 | {"imagefill",IMAGEFILL,0}, |
||
6813 | {"imagepalette",IMAGEPALETTE,0}, |
||
6814 | {"input",INPUT,0}, |
||
6815 | {"intooltip",INTOOLTIP,0}, |
||
6816 | {"jscurve",JSCURVE,0}, |
||
6817 | {"jsmath",JSMATH,0}, |
||
6818 | {"jsplot",JSCURVE,0}, |
||
6819 | {"katex",LATEX,0}, |
||
6820 | {"kill",KILL,0}, |
||
6821 | {"killaffine",KILLAFFINE,0}, |
||
6822 | {"killgroup",KILLSLIDER,0}, |
||
6823 | {"killinear",KILLLINEAR,0}, |
||
6824 | {"killlinear",KILLLINEAR,0}, |
||
6825 | {"killreset",NORESET,0}, |
||
6826 | {"killrotate",KILLROTATE,0}, |
||
6827 | {"killslider",KILLSLIDER,0}, |
||
6828 | {"killtranslate",KILLTRANSLATION,0}, |
||
6829 | {"killtranslation",KILLTRANSLATION,0}, |
||
6830 | {"latex",LATEX,0}, |
||
6831 | {"lattice",LATTICE,0}, |
||
6832 | {"legend",LEGEND,0}, |
||
6833 | {"legendcolors",LEGENDCOLORS,0}, |
||
6834 | {"levelcurve",LEVELCURVE,0}, |
||
6835 | {"line",LINE,0}, |
||
6836 | {"linear",LINEAR,0}, |
||
6837 | {"linegraph",LINEGRAPH,0}, |
||
6838 | {"lines",LINES,0}, |
||
6839 | {"linewidth",LINEWIDTH,0}, |
||
6840 | {"linewidths",MULTILINEWIDTH,0}, |
||
6841 | {"math",LATEX,0}, |
||
6842 | {"mathml",MATHML,0}, |
||
6843 | {"mouse",MOUSE,0}, |
||
6844 | {"mousedegree",MOUSE_DEGREE,0}, |
||
6845 | {"mouseprecision",MOUSE_PRECISION,0}, |
||
6846 | {"mousex",MOUSEX,0}, |
||
6847 | {"mousey",MOUSEY,0}, |
||
6848 | {"multicolors",MULTISTROKECOLORS,0}, |
||
6849 | {"multidash",MULTIDASH,0}, |
||
6850 | {"multidraw",MULTIDRAW,0}, |
||
6851 | {"multifill",MULTIFILL,0}, |
||
6852 | {"multifillcolors",MULTIFILLCOLORS,0}, |
||
6853 | {"multifillopacity",MULTIFILLOPACITY,0}, |
||
6854 | {"multiinput",MULTIUSERINPUT,0}, |
||
6855 | {"multilabel",MULTILABEL,0}, |
||
6856 | {"multilinewidth",MULTILINEWIDTH,0}, |
||
6857 | {"multisnap",MULTISNAPTOGRID,0}, |
||
6858 | {"multisnaptogrid",MULTISNAPTOGRID,0}, |
||
6859 | {"multistrokecolors",MULTISTROKECOLORS,0}, |
||
6860 | {"multistrokeopacity",MULTISTROKEOPACITY,0}, |
||
6861 | {"multiuserinput",MULTIUSERINPUT,0}, |
||
6862 | {"newrange",NEWRANGE,0}, |
||
6863 | {"noreset",NORESET,0}, |
||
6864 | {"nostatus",STATUS,0}, |
||
6865 | {"noxaxis",NOXAXIS,0}, |
||
6866 | {"noyaxis",NOYAXIS,0}, |
||
6867 | {"numberline",NUMBERLINE,0}, |
||
6868 | {"obabel",OBABEL,0}, |
||
6869 | {"onclick",ONCLICK,0}, |
||
6870 | {"opacity",OPACITY,0}, |
||
6871 | {"parallel",PARALLEL,0}, |
||
6872 | {"path",POLYLINE,0}, |
||
6873 | {"patternfill",PATTERNFILL,0}, |
||
6874 | {"piechart",PIECHART,0}, |
||
6875 | {"pixels",PIXELS,0}, |
||
6876 | {"pixelsize",PIXELSIZE,0}, |
||
6877 | {"plot",CURVE,0}, |
||
6878 | {"plotstep",PLOTSTEPS,0}, |
||
6879 | {"plotsteps",PLOTSTEPS,0}, |
||
6880 | {"point",POINT,0}, |
||
6881 | {"pointer",CURSOR,0}, |
||
6882 | {"points",POINTS,0}, |
||
6883 | {"poly",POLY,0}, |
||
6884 | {"polygon",POLY,0}, |
||
6885 | {"polyline",POLYLINE,0}, |
||
6886 | {"popup",POPUP,0}, |
||
6887 | {"precision",MOUSE_PRECISION,0}, |
||
6888 | {"protractor",PROTRACTOR,0}, |
||
6889 | {"range",RANGE,0}, |
||
6890 | {"ranget",TRANGE,0}, |
||
6891 | {"rangex",XRANGE,0}, |
||
6892 | {"rangey",YRANGE,0}, |
||
6893 | {"rays",RAYS,0}, |
||
6894 | {"rect",RECT,0}, |
||
6895 | {"rectangle",RECT,0}, |
||
6896 | {"rects",RECTS,0}, |
||
6897 | {"replyformat",REPLYFORMAT,0}, |
||
6898 | {"reset",RESET,0}, |
||
6899 | {"resetoffset",RESETOFFSET,0}, |
||
6900 | {"rotate",ROTATE,0}, |
||
6901 | {"rotationcenter",ROTATION_CENTER,0}, |
||
6902 | {"roundrect",ROUNDRECT,0}, |
||
6903 | {"roundrectangle",ROUNDRECT,0}, |
||
6904 | {"roundrects",ROUNDRECTS,0}, |
||
6905 | {"ruler",RULER,0}, |
||
6906 | {"seg",SEGMENT,0}, |
||
6907 | {"segment",SEGMENT,0}, |
||
6908 | {"segments",SEGMENTS,0}, |
||
6909 | {"segs",SEGMENTS,0}, |
||
6910 | {"setlimits",SETLIMITS,0}, |
||
6911 | {"setpixel",SETPIXEL,0}, |
||
6912 | {"settile",FILLPATTERN,0}, |
||
6913 | {"sgraph",SGRAPH,0}, |
||
6914 | {"size",SIZE,0}, |
||
6915 | {"slider",SLIDER,0}, |
||
6916 | {"snaptofun",SNAPTOFUNCTION,0}, |
||
6917 | {"snaptofunction",SNAPTOFUNCTION,0}, |
||
6918 | {"snaptogrid",SNAPTOGRID,0}, |
||
6919 | {"snaptopoints",SNAPTOPOINTS,0}, |
||
6920 | {"square",SQUARE,0}, |
||
6921 | {"status",STATUS,0}, |
||
6922 | {"string",STRING,0}, |
||
6923 | {"stringup",STRINGUP,0}, |
||
6924 | {"strokecolor",STROKECOLOR,0}, |
||
6925 | {"strokecolors",MULTISTROKECOLORS,0}, |
||
18608 | bpr | 6926 | {"strokeopacity",STROKEOPACITY,0}, |
18589 | bpr | 6927 | {"style",STYLE,0}, |
6928 | {"text",FLY_TEXT,0}, |
||
6929 | {"textarea",TEXTAREA,0}, |
||
6930 | {"textfill",TEXTFILL,0}, |
||
6931 | {"textup",FLY_TEXTUP,0}, |
||
6932 | {"title",CENTERSTRING,0}, |
||
6933 | {"trace_jscurve",TRACE_JSCURVE,0}, |
||
6934 | {"trange",TRANGE,0}, |
||
6935 | {"translate",TRANSLATION,0}, |
||
6936 | {"translation",TRANSLATION,0}, |
||
6937 | {"transparent",OPACITY,0}, |
||
6938 | {"triangle",TRIANGLE,0}, |
||
6939 | {"triangles",TRIANGLES,0}, |
||
6940 | {"tsteps",PLOTSTEPS,0}, |
||
6941 | {"userboxplot",USERBOXPLOT,0}, |
||
6942 | {"userboxplotdata",USERBOXPLOT,0}, |
||
6943 | {"userdraw",USERDRAW,0}, |
||
6944 | {"userinput",USERINPUT,0}, |
||
6945 | {"userinput_function",USERINPUT_FUNCTION,0}, |
||
6946 | {"userinput_xy",USERINPUT_XY,0}, |
||
6947 | {"vector",ARROW,0}, |
||
6948 | {"vectors",ARROWS,0}, |
||
6949 | {"verticalline",VLINE,0}, |
||
6950 | {"verticallines",VLINES,0}, |
||
6951 | {"video",VIDEO,0}, |
||
6952 | {"vline",VLINE,0}, |
||
6953 | {"vlines",VLINES,0}, |
||
6954 | {"xaxis",X_AXIS_STRINGS,0}, |
||
6955 | {"xaxistext",X_AXIS_STRINGS,0}, |
||
6956 | {"xaxistextup",X_AXIS_STRINGS_UP,0}, |
||
6957 | {"xaxisup",X_AXIS_STRINGS_UP,0}, |
||
6958 | {"xerrorbars",XERRORBARS,0}, |
||
6959 | {"xlabel",XLABEL,0}, |
||
6960 | {"xlogbase",XLOGBASE,0}, |
||
6961 | {"xlogscale",XLOGSCALE,0}, |
||
6962 | {"xoffset",XOFFSET,0}, |
||
6963 | {"xrange",XRANGE,0}, |
||
6964 | {"xsnaptogrid",XSNAPTOGRID,0}, |
||
6965 | {"xunit",XUNIT,0}, |
||
6966 | {"xylogscale",XYLOGSCALE,0}, |
||
6967 | {"xyoffset",XYOFFSET,0}, |
||
6968 | {"yaxis",Y_AXIS_STRINGS,0}, |
||
6969 | {"yaxistext",Y_AXIS_STRINGS,0}, |
||
6970 | {"yerrorbars",YERRORBARS,0}, |
||
6971 | {"ylabel",YLABEL,0}, |
||
6972 | {"ylogbase",YLOGBASE,0}, |
||
6973 | {"ylogscale",YLOGSCALE,0}, |
||
6974 | {"yoffset",YOFFSET,0}, |
||
6975 | {"yrange",YRANGE,0}, |
||
6976 | {"ysnaptogrid",YSNAPTOGRID,0}, |
||
6977 | {"yunit",YUNIT,0}, |
||
6978 | {"zoom",ZOOM,0} |
||
6979 | }; |
||
7614 | schaersvoo | 6980 | |
18552 | bpr | 6981 | while(((c = getc(infile)) != EOF)&&(c!='\n')&&(c!=',')&&(c!='=')&&(c!='\r')&&(c!='\t')){ |
6982 | if( i == 0 && (c == ' ') ){ continue; /* white spaces or tabs allowed before first command identifier */ |
||
6983 | }else{ |
||
6984 | if( c == ' ' ){ |
||
6985 | break; |
||
6986 | }else{ |
||
6987 | temp[i] = c; |
||
6988 | if(i > MAX_INT - 2){canvas_error("command string too long !");} |
||
6989 | i++; |
||
6990 | } |
||
6991 | } |
||
6992 | if(temp[0] == '#'){ break; } |
||
6993 | } |
||
6994 | if (c == '\n' || c == '\r' || c == '\t' ){ line_number++; } |
||
6995 | if (c == EOF) {finished=1;return 0;} |
||
7614 | schaersvoo | 6996 | |
18552 | bpr | 6997 | temp[i]='\0'; |
6998 | if(strstr(temp,"dash") !=0 && strlen(temp) > 4 && strstr(temp,"dashtype") == 0 ){ |
||
6999 | /* 4/2024 adapt to Flydraw's dashing syntax for all objects with prefix "dash" */ |
||
7000 | use_dashed = TRUE;int idx=0;int p; |
||
7001 | for( p = 4; p < strlen(temp); p++){temp[idx] = temp[p];idx++;} |
||
7002 | input_type = (char*)my_newmem(idx); snprintf(input_type,idx+1,"%s",temp); |
||
7003 | }else{ |
||
7004 | input_type=(char*)my_newmem(strlen(temp)); |
||
7005 | snprintf(input_type,sizeof(temp),"%s",temp); |
||
7006 | } |
||
18572 | bpr | 7007 | /* fprintf(stdout,"input_type = %s no_reset = %d <br>",input_type,no_reset);*/ |
18589 | bpr | 7008 | |
7009 | left=0; right=sizeof(table)/sizeof(struct commande); |
||
7010 | while (left<right){ |
||
7011 | milieu = (left+right)/2; |
||
7012 | delta = strcmp(input_type, table[milieu].nom); |
||
7013 | if (delta == 0){ |
||
7014 | free(input_type); |
||
7015 | if (table[milieu].special==usefilled) use_filled=TRUE; |
||
7016 | if (table[milieu].special==usedashed) use_dashed=TRUE; |
||
7017 | return table[milieu].res; |
||
7018 | } |
||
7019 | if (delta<0) right=milieu; else left=milieu+1; |
||
18552 | bpr | 7020 | } |
7021 | free(input_type); |
||
18562 | bpr | 7022 | ungetc(c,infile); |
7023 | return 0; |
||
7614 | schaersvoo | 7024 | } |