]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/gfx/demos/career_test.html
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / gfx / demos / career_test.html
1 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
2 <head>
3 <title>dojox.gfx: Career Aptitude Test</title>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <style type="text/css">
6         @import "../../../dojo/resources/dojo.css";
7         @import "../../../dijit/tests/css/dijitTests.css";
8 </style>
9 <!--
10 The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
11 <script type="text/javascript" src="Silverlight.js"></script>
12 -->
13 <script type="text/javascript" src="../../../dojo/dojo.js"></script>
14
15 <!--
16 <script type="text/javascript" src="../Mover.js"></script>
17 <script type="text/javascript" src="../Moveable.js"></script>
18 <script type="text/javascript" src="../move.js"></script>
19 <script type="text/javascript" src="../fx.js"></script>
20 <script type="text/javascript" src="../shape.js"></script>
21 -->
22
23 <script type="text/javascript">
24
25 dojo.require("dojox.gfx");
26 dojo.require("dojox.gfx.move");
27 dojo.require("dojox.gfx.fx");
28 dojo.require("dojo.colors");
29 dojo.require("dojo.fx");
30
31 var g = dojox.gfx, m = g.matrix;
32
33 var container, surface, surface_size,
34         vat, freezer, broiler, score, startTime, endTime;
35
36 var totalItems = 10, goodItems = 0, badItems = 0;
37
38 var radius = 30,                // pixels
39         slowRate = 10,          // speed in ms per pixel
40         fastRate = 2,           // speed in ms per pixel
41         freezeTime = 5000,      // ms
42         frostTime = 2000,       // ms
43         broilTime = 5000,       // ms
44         burnTime = 2000,        // ms
45         pulseTime = 200;        // ms
46         
47 function getRand(from, to){
48         return Math.random() * (to - from) + from;
49 }
50
51 function inRect(rect, crd){
52         return  rect.x <= crd.x && crd.x < rect.x + rect.width &&
53                         rect.y <= crd.y && crd.y < rect.y + rect.height;
54 }
55
56 function getCenter(circle){
57         var shape = circle.getShape(), matrix = circle.getTransform();
58         return m.multiplyPoint(matrix ? matrix : m.identity, shape.cx, shape.cy);
59 }
60
61 function getDuration(x1, y1, x2, y2, rate){
62         return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * rate);
63 }
64
65 function updateScore(){
66         var shape = score.getShape();
67         endTime = (new Date()).getTime();
68         shape.text = goodItems + " item" + (goodItems != 1 ? "s" : "") + 
69                 " in " + ((endTime - startTime) / 1000) + "s"
70         score.setShape(shape);
71         
72         if(goodItems + badItems != totalItems){ return; }
73         
74         var rating = goodItems / (endTime - startTime) * 60000 * (40 - radius) / 10;
75         dojo.byId("result_pass").style.display = badItems || rating < 5 ? "none" : "";
76         dojo.byId("result_dollar").innerHTML = rating.toFixed(2);
77         dojo.byId("result_but").style.display = badItems ? "" : "none";
78         dojo.byId("result_waste").innerHTML = (badItems * 5).toFixed(2);
79         dojo.byId("result_and").style.display = badItems ? "none" : "";
80         dojo.byId("result_fail").style.display = badItems ? "" : "none";
81         if(!badItems){
82                 var pos;
83                 if(rating < 1){
84                         pos = "Junior Speciment Flipper";
85                 }else if(rating < 2){
86                         pos = "Senior Speciment Flipper";
87                 }else if(rating < 4){
88                         pos = "Shift Supervisor";
89                 }else if(rating < 6){
90                         pos = "Joint Manager";
91                 }else if(rating < 8){
92                         pos = "Night Director";
93                 }else if(rating < 10){
94                         pos = "Morning Director";
95                 }else if(rating < 12){
96                         pos = "Vice President";
97                 }else if(rating < 14){
98                         pos = "Senior Vice President";
99                 }else if(rating < 16){
100                         pos = "Chief of Something";
101                 }else{
102                         pos = "Nominal President";
103                 }
104                 dojo.byId("result_pos").innerHTML = pos;
105         }
106         var anim1 = dojo.fx.wipeOut({
107                         node: "gfx_holder",
108                         duration: 500,
109                         delay: 1000
110                 }),
111                 anim2 = dojo.fx.wipeIn({
112                         node: "result",
113                         duration: 500,
114                         delay: 1000
115                 });
116         anim1.play();
117         anim2.play();
118 }
119
120 function showStatus(circle, text){
121         var c = getCenter(circle),
122                 status = surface.createText({});
123         status.moveToBack().setFill(new dojo.Color([0, 0, 0, 0.5]))
124                 .setFont({family: "serif", variant: "small-caps", weight: "bold"})
125                 .setShape({x: c.x, y: c.y, text: text, align: "middle"});
126         var anim = dojo.fx.combine([
127                 g.fx.animateFill({
128                         shape:          status,
129                         duration:       3000,
130                         color:          {end: "transparent"}
131                 }),
132                 g.fx.animateTransform({
133                         shape:          status,
134                         duration:       3000,
135                         transform:      [
136                                 {name: "translate", start: [0, 0], end: [0, 300]},
137                                 {name: "original"}
138                         ]
139                 })
140         ]);
141         dojo.connect(anim, "onEnd", function(){ status.removeShape(); });
142         anim.play();
143 }
144
145 function moveToPile(shape, bad){
146         if(shape.moveable){
147                 shape.moveable.destroy();
148                 delete shape.moveable;
149         }
150         
151         var oldColor = shape.getFill(), c = getCenter(shape),
152                 newX = 80 + (bad ? badItems++ : goodItems++) * 2.25 * 10,
153                 newY = bad ? 445 : 415,
154                 duration = getDuration(newX, newY, c.x, c.y, fastRate),
155                 anim = dojo.fx.chain([
156                         g.fx.animateFill({
157                                 shape: shape,
158                                 duration: 250,
159                                 color: {end: "transparent"}
160                         }),
161                         g.fx.animateTransform({
162                                 shape: shape,
163                                 duration: duration,
164                                 transform:      [
165                                         {name: "translate", start: [0, 0], end: [newX - c.x, newY - c.y]},
166                                         {name: "original"}
167                                 ]
168                         }),
169                         g.fx.animateFill({
170                                 shape: shape,
171                                 duration: 250,
172                                 color: {end: oldColor}
173                         }),
174                         g.fx.animateTransform({
175                                 shape: shape,
176                                 duration: duration,
177                                 transform:      [
178                                         {name: "scaleAt", start: [1, newX, newY], end: [10 / radius, newX, newY]},
179                                         {name: "original"}
180                                 ]
181                         })
182                 ]);
183         dojo.connect(anim, "onEnd", updateScore);
184         anim.play();
185 }
186
187 function repeatMove(){
188         var rect = vat.getShape(), c = getCenter(this),
189                 x = getRand(rect.x + radius, rect.x + rect.width - radius),
190                 y = getRand(rect.y + radius, rect.y + rect.height - radius),
191                 duration = getDuration(x, y, c.x, c.y, slowRate);
192         this.anim = g.fx.animateTransform({
193                 duration:       duration,
194                 shape:          this,
195                 transform:      [
196                         {name: "translate", start: [0, 0], end: [x - c.x, y - c.y]},
197                         {name: "original"}
198                 ]
199         });
200         dojo.connect(this.anim, "onEnd", this, repeatMove);
201         this.anim.play();
202 }
203
204 function repeatFrost(){
205         this.status = "frozen";
206         this.setStroke({color: "orange", width: 3});
207         showStatus(this, "Ready");
208         this.anim = g.fx.animateFill({
209                 duration:       frostTime,
210                 shape:          this,
211                 color:          {end: "white"}
212         });
213         // calculate a shift
214         var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1;
215         this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2});
216         dojo.connect(this.anim, "onAnimate", this, function(){
217                 this.applyLeftTransform({dx: sign * dx, dy: sign * dy});
218                 sign = -sign;
219         });
220         dojo.connect(this.anim, "onEnd", this, function(){
221                 showStatus(this, "Frozen");
222                 moveToPile(this, true);
223         });
224         this.anim.play();
225 }
226
227 function repeatFreeze(){
228         this.status = "freezing";
229         this.setStroke({color: "black", width: 3});
230         this.anim = g.fx.animateFill({
231                 duration:       freezeTime,
232                 shape:          this,
233                 color:          {end: "blue"}
234         });
235         // calculate a shift
236         var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1;
237         this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2});
238         dojo.connect(this.anim, "onAnimate", this, function(){
239                 this.applyLeftTransform({dx: sign * dx, dy: sign * dy});
240                 sign = -sign;
241         });
242         dojo.connect(this.anim, "onEnd", this, repeatFrost);
243         this.anim.play();
244 }
245
246 function repeatBurn(){
247         this.status = "burnt";
248         this.setStroke({color: "orange", width: 3});
249         showStatus(this, "Done");
250         var anim1 = g.fx.animateFill({
251                 duration:       burnTime,
252                 shape:          this,
253                 color:          {end: "black"}
254         });
255         var anim2 = new dojo._Animation({
256                 duration:       freezeTime,
257                 curve:          [0, freezeTime]
258         });
259         var matrix = this.getTransform(), c = getCenter(this);
260         dojo.connect(anim2, "onAnimate", this, function(val){
261                 var scale = (val % pulseTime) / pulseTime / 4 + 1;
262                 this.setTransform([m.scaleAt(scale, c), matrix]);
263         });
264         this.anim = dojo.fx.combine([anim1, anim2]);
265         dojo.connect(this.anim, "onEnd", this, function(){
266                 showStatus(this, "Burnt");
267                 moveToPile(this, true);
268         });
269         this.anim.play();
270 }
271
272 function repeatBroil(){
273         this.status = "broiling";
274         this.setStroke({color: "black", width: 3});
275         var anim1 = g.fx.animateFill({
276                 duration:       broilTime,
277                 shape:          this,
278                 color:          {end: "red"}
279         });
280         var anim2 = new dojo._Animation({
281                 duration:       freezeTime,
282                 curve:          [0, freezeTime]
283         });
284         var matrix = this.getTransform(), c = getCenter(this);
285         dojo.connect(anim2, "onAnimate", this, function(val){
286                 var scale = (val % pulseTime) / pulseTime / 4 + 1;
287                 this.setTransform([m.scaleAt(scale, c), matrix]);
288         });
289         this.anim = dojo.fx.combine([anim1, anim2]);
290         dojo.connect(this.anim, "onEnd", this, repeatBurn);
291         this.anim.play();
292 }
293
294 function drag(mover){
295         var shape = mover.shape;
296         shape.anim.stop();
297         shape.anim = null;
298 }
299
300 function drop(mover){
301         var c = getCenter(mover.shape);
302         do{     // break block
303                 if(inRect(vat.getShape(), c)){
304                         if(mover.shape.status == "fresh"){
305                                 repeatMove.call(mover.shape);
306                                 return;
307                         }
308                         break;
309                 }
310                 if(inRect(freezer.getShape(), c)){
311                         if(mover.shape.status == "fresh"){
312                                 repeatFreeze.call(mover.shape);
313                                 return;
314                         }
315                         break;
316                 }
317                 if(inRect(broiler.getShape(), c)){
318                         if(mover.shape.status == "frozen"){
319                                 repeatBroil.call(mover.shape);
320                                 return;
321                         }
322                         break;
323                 }
324                 if(mover.shape.status == "burnt"){
325                         moveToPile(mover.shape, false); // good
326                         return;
327                 }
328         }while(false);
329         moveToPile(mover.shape, true);  // bad
330 }
331
332 function makePatties(n){
333         var rect = vat.getShape();
334         for(var i = 0; i < n; ++i){
335                 var cx = getRand(rect.x + radius, rect.x + rect.width - radius),
336                         cy = getRand(rect.y + radius, rect.y + rect.height - radius),
337                         patty = surface.createCircle({
338                                 cx: cx, cy: cy, r: radius
339                         }).setFill("green").setStroke({
340                                 color: "black",
341                                 width: 3
342                         });
343                 patty.status = "fresh";
344                 patty.moveable = new g.Moveable(patty);
345                 repeatMove.call(patty);
346         }
347 }
348
349 function initGfx(){
350         container = dojo.byId("gfx_holder");
351         surface = g.createSurface(container, 500, 500);
352         surface_size = {width: 500, height: 500};
353         
354         vat = surface.createRect({x: 10, y: 210, width: 480, height: 180})
355                 .setStroke({color: "black", width: 7, join: "round"});
356         surface.createText({x: 15, y: 230, text: "Ye Olde Vat v3.2"})
357                 .setFill("black");
358                         
359         freezer = surface.createRect({x: 10, y: 10, width: 230, height: 180})
360                 .setStroke({color: "blue", width: 7, join: "round"});
361         surface.createText({x: 15, y: 30, text: "Deep Freeze 7000"})
362                 .setFill("blue");
363                         
364         broiler = surface.createRect({x: 260, y: 10, width: 230, height: 180})
365                 .setStroke({color: "red", width: 7, join: "round"});
366         surface.createText({x: 265, y: 30, text: "Hellfire Broiler A4"})
367                 .setFill("red");
368                         
369         surface.createText({x: 15, y: 420, text: "Good:"})
370                 .setFont({weight: "bold"}).setFill("green");
371         surface.createText({x: 15, y: 450, text: "Bad:"})
372                 .setFont({weight: "bold"}).setFill("red");
373         surface.createText({x: 15, y: 480, text: "Total:"})
374                 .setFont({weight: "bold"}).setFill("black");
375         score = surface.createText({x: 80, y: 485, text: "0"})
376                 .setFont({weight: "bold", size: "24pt"}).setFill("black");
377         surface.createText({x: 120, y: 460, text: "DROP HERE!"})
378                 .setFont({size: "50px"})
379                 .setFill(new dojo.Color([0, 0, 0, 0.1])).moveToBack();
380
381         dojo.subscribe("/gfx/move/start", drag);
382         dojo.subscribe("/gfx/move/stop",  drop);
383         makePatties(totalItems);
384         
385         startTime = (new Date()).getTime();
386
387         // cancel text selection and text dragging
388         dojo.connect(container, "ondragstart",   dojo, "stopEvent");
389         dojo.connect(container, "onselectstart", dojo, "stopEvent");
390 }
391
392 //dojo.addOnLoad(initGfx);
393
394 function startTest(level){
395         radius = level;
396         var anim = dojo.fx.wipeOut({
397                 node: "explanation",
398                 duration: 500
399         });
400         dojo.connect(anim, "onEnd", function(){
401                 dojo.byId("gfx_holder").style.display = "";
402                 initGfx();
403         });
404         anim.play();
405 }
406
407 </script>
408
409 <style type="text/css">
410 .movable { cursor: pointer; }
411 </style>
412
413 </head>
414 <body>
415 <h1>dojox.gfx: Career Aptitude Test</h1>
416 <p>Warning: Canvas renderer doesn't implement event handling.</p>
417
418 <div id="explanation">
419 <p>Thank you for your interest in <em>"I can't believe it's manure" Eateries&trade;</em> 
420 and for submitting your resume for our review. While this is an automated response, 
421 please be assured that every resume is reviewed by us, and forwarded to the hiring
422 managers if the skills fit our needs.</p>
423 <p>In order order to evaluate your skills we ask you to take a career aptitude test. 
424 You will have an exciting chance to operate one of our state-of-the-art workstations 
425 remotely. Don't forget:
426 </p>
427 <ol>
428         <li>Fish out a live speciment of <em>dung-42</em> from the container.</li>
429         <li>Freeze it until you see an orange glow to kill the elements and make it less green.</li>
430         <li>Broil it until you see the orange glow again, and drop it on the table below.</li>
431         <li>You have to process all items without wasting resources and in minimal time.</li>
432 </ol>
433 <p>Warnings: don't overfreeze, don't overheat, don't drop the speciment, don't change the sequence, 
434 don't touch the speciment in heating and freezing chambers until it is's ready.</p>
435 <p>Use your head and your mouse!</p>
436 <p>Please select the desired position:</p>
437 <table>
438         <tr>
439                 <td>Workstation Supervisor&nbsp;</td>
440                 <td><button onclick="startTest(30);">Apply</button></td>
441         </tr>
442         <tr>
443                 <td>Shift Director&nbsp;</td>
444                 <td><button onclick="startTest(20);">Apply</button></td>
445         </tr>
446         <tr>
447                 <td>Vice President #49653&nbsp;</td>
448                 <td><button onclick="startTest(10);">Apply</button></td>
449         </tr>
450 </table>
451 </div>
452
453 <div id="gfx_holder" style="width: 500px; height: 500px; display: none;"></div>
454
455 <div id="result" style="display: none;">
456 <p id="result_pass"><strong>Impressive! Please contact us immediately.</strong></p>
457 <p>You have made $<span id="result_dollar"></span> per minute for us.
458 <span id="result_but">But you wasted $<span id="result_waste"></span> in materials.</span>
459 <span id="result_and">It qualifies you to be a <em id="result_pos"></em>.</span>
460 </p>
461 <p id="result_fail">Should our hiring managers have an interest in your skills and
462 capabilities, they will contact you directly. In addition, we will keep
463 your resume on file for one year.</p>
464 </div>
465
466 </body>
467 </html>