1 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
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";
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>
13 <script type="text/javascript" src="../../../dojo/dojo.js"></script>
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>
23 <script type="text/javascript">
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");
31 var g = dojox.gfx, m = g.matrix;
33 var container, surface, surface_size,
34 vat, freezer, broiler, score, startTime, endTime;
36 var totalItems = 10, goodItems = 0, badItems = 0;
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
47 function getRand(from, to){
48 return Math.random() * (to - from) + from;
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;
56 function getCenter(circle){
57 var shape = circle.getShape(), matrix = circle.getTransform();
58 return m.multiplyPoint(matrix ? matrix : m.identity, shape.cx, shape.cy);
61 function getDuration(x1, y1, x2, y2, rate){
62 return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * rate);
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);
72 if(goodItems + badItems != totalItems){ return; }
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";
84 pos = "Junior Speciment Flipper";
86 pos = "Senior Speciment Flipper";
88 pos = "Shift Supervisor";
90 pos = "Joint Manager";
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";
102 pos = "Nominal President";
104 dojo.byId("result_pos").innerHTML = pos;
106 var anim1 = dojo.fx.wipeOut({
111 anim2 = dojo.fx.wipeIn({
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([
130 color: {end: "transparent"}
132 g.fx.animateTransform({
136 {name: "translate", start: [0, 0], end: [0, 300]},
141 dojo.connect(anim, "onEnd", function(){ status.removeShape(); });
145 function moveToPile(shape, bad){
147 shape.moveable.destroy();
148 delete shape.moveable;
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([
159 color: {end: "transparent"}
161 g.fx.animateTransform({
165 {name: "translate", start: [0, 0], end: [newX - c.x, newY - c.y]},
172 color: {end: oldColor}
174 g.fx.animateTransform({
178 {name: "scaleAt", start: [1, newX, newY], end: [10 / radius, newX, newY]},
183 dojo.connect(anim, "onEnd", updateScore);
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({
196 {name: "translate", start: [0, 0], end: [x - c.x, y - c.y]},
200 dojo.connect(this.anim, "onEnd", this, repeatMove);
204 function repeatFrost(){
205 this.status = "frozen";
206 this.setStroke({color: "orange", width: 3});
207 showStatus(this, "Ready");
208 this.anim = g.fx.animateFill({
211 color: {end: "white"}
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});
220 dojo.connect(this.anim, "onEnd", this, function(){
221 showStatus(this, "Frozen");
222 moveToPile(this, true);
227 function repeatFreeze(){
228 this.status = "freezing";
229 this.setStroke({color: "black", width: 3});
230 this.anim = g.fx.animateFill({
231 duration: freezeTime,
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});
242 dojo.connect(this.anim, "onEnd", this, repeatFrost);
246 function repeatBurn(){
247 this.status = "burnt";
248 this.setStroke({color: "orange", width: 3});
249 showStatus(this, "Done");
250 var anim1 = g.fx.animateFill({
253 color: {end: "black"}
255 var anim2 = new dojo._Animation({
256 duration: freezeTime,
257 curve: [0, freezeTime]
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]);
264 this.anim = dojo.fx.combine([anim1, anim2]);
265 dojo.connect(this.anim, "onEnd", this, function(){
266 showStatus(this, "Burnt");
267 moveToPile(this, true);
272 function repeatBroil(){
273 this.status = "broiling";
274 this.setStroke({color: "black", width: 3});
275 var anim1 = g.fx.animateFill({
280 var anim2 = new dojo._Animation({
281 duration: freezeTime,
282 curve: [0, freezeTime]
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]);
289 this.anim = dojo.fx.combine([anim1, anim2]);
290 dojo.connect(this.anim, "onEnd", this, repeatBurn);
294 function drag(mover){
295 var shape = mover.shape;
300 function drop(mover){
301 var c = getCenter(mover.shape);
303 if(inRect(vat.getShape(), c)){
304 if(mover.shape.status == "fresh"){
305 repeatMove.call(mover.shape);
310 if(inRect(freezer.getShape(), c)){
311 if(mover.shape.status == "fresh"){
312 repeatFreeze.call(mover.shape);
317 if(inRect(broiler.getShape(), c)){
318 if(mover.shape.status == "frozen"){
319 repeatBroil.call(mover.shape);
324 if(mover.shape.status == "burnt"){
325 moveToPile(mover.shape, false); // good
329 moveToPile(mover.shape, true); // bad
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({
343 patty.status = "fresh";
344 patty.moveable = new g.Moveable(patty);
345 repeatMove.call(patty);
350 container = dojo.byId("gfx_holder");
351 surface = g.createSurface(container, 500, 500);
352 surface_size = {width: 500, height: 500};
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"})
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"})
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"})
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();
381 dojo.subscribe("/gfx/move/start", drag);
382 dojo.subscribe("/gfx/move/stop", drop);
383 makePatties(totalItems);
385 startTime = (new Date()).getTime();
387 // cancel text selection and text dragging
388 dojo.connect(container, "ondragstart", dojo, "stopEvent");
389 dojo.connect(container, "onselectstart", dojo, "stopEvent");
392 //dojo.addOnLoad(initGfx);
394 function startTest(level){
396 var anim = dojo.fx.wipeOut({
400 dojo.connect(anim, "onEnd", function(){
401 dojo.byId("gfx_holder").style.display = "";
409 <style type="text/css">
410 .movable { cursor: pointer; }
415 <h1>dojox.gfx: Career Aptitude Test</h1>
416 <p>Warning: Canvas renderer doesn't implement event handling.</p>
418 <div id="explanation">
419 <p>Thank you for your interest in <em>"I can't believe it's manure" Eateries™</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:
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>
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>
439 <td>Workstation Supervisor </td>
440 <td><button onclick="startTest(30);">Apply</button></td>
443 <td>Shift Director </td>
444 <td><button onclick="startTest(20);">Apply</button></td>
447 <td>Vice President #49653 </td>
448 <td><button onclick="startTest(10);">Apply</button></td>
453 <div id="gfx_holder" style="width: 500px; height: 500px; display: none;"></div>
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>
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>