You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
463 lines
13 KiB
463 lines
13 KiB
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"> |
|
<head> |
|
<title>dojox.gfx: Career Aptitude Test</title> |
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|
<style type="text/css"> |
|
@import "../../../dojo/resources/dojo.css"; |
|
@import "../../../dijit/tests/css/dijitTests.css"; |
|
</style> |
|
<script type="text/javascript" src="../../../dojo/dojo.js"></script> |
|
|
|
<!-- |
|
<script type="text/javascript" src="../Mover.js"></script> |
|
<script type="text/javascript" src="../Moveable.js"></script> |
|
<script type="text/javascript" src="../move.js"></script> |
|
<script type="text/javascript" src="../fx.js"></script> |
|
<script type="text/javascript" src="../shape.js"></script> |
|
--> |
|
|
|
<script type="text/javascript"> |
|
|
|
dojo.require("dojox.gfx"); |
|
dojo.require("dojox.gfx.move"); |
|
dojo.require("dojox.gfx.fx"); |
|
dojo.require("dojo.colors"); |
|
dojo.require("dojo.fx"); |
|
|
|
var g = dojox.gfx, m = g.matrix; |
|
|
|
var container, surface, surface_size, |
|
vat, freezer, broiler, score, startTime, endTime; |
|
|
|
var totalItems = 10, goodItems = 0, badItems = 0; |
|
|
|
var radius = 30, // pixels |
|
slowRate = 10, // speed in ms per pixel |
|
fastRate = 2, // speed in ms per pixel |
|
freezeTime = 5000, // ms |
|
frostTime = 2000, // ms |
|
broilTime = 5000, // ms |
|
burnTime = 2000, // ms |
|
pulseTime = 200; // ms |
|
|
|
function getRand(from, to){ |
|
return Math.random() * (to - from) + from; |
|
} |
|
|
|
function inRect(rect, crd){ |
|
return rect.x <= crd.x && crd.x < rect.x + rect.width && |
|
rect.y <= crd.y && crd.y < rect.y + rect.height; |
|
} |
|
|
|
function getCenter(circle){ |
|
var shape = circle.getShape(), matrix = circle.getTransform(); |
|
return m.multiplyPoint(matrix ? matrix : m.identity, shape.cx, shape.cy); |
|
} |
|
|
|
function getDuration(x1, y1, x2, y2, rate){ |
|
return Math.floor(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * rate); |
|
} |
|
|
|
function updateScore(){ |
|
var shape = score.getShape(); |
|
endTime = (new Date()).getTime(); |
|
shape.text = goodItems + " item" + (goodItems != 1 ? "s" : "") + |
|
" in " + ((endTime - startTime) / 1000) + "s" |
|
score.setShape(shape); |
|
|
|
if(goodItems + badItems != totalItems){ return; } |
|
|
|
var rating = goodItems / (endTime - startTime) * 60000 * (40 - radius) / 10; |
|
dojo.byId("result_pass").style.display = badItems || rating < 5 ? "none" : ""; |
|
dojo.byId("result_dollar").innerHTML = rating.toFixed(2); |
|
dojo.byId("result_but").style.display = badItems ? "" : "none"; |
|
dojo.byId("result_waste").innerHTML = (badItems * 5).toFixed(2); |
|
dojo.byId("result_and").style.display = badItems ? "none" : ""; |
|
dojo.byId("result_fail").style.display = badItems ? "" : "none"; |
|
if(!badItems){ |
|
var pos; |
|
if(rating < 1){ |
|
pos = "Junior Speciment Flipper"; |
|
}else if(rating < 2){ |
|
pos = "Senior Speciment Flipper"; |
|
}else if(rating < 4){ |
|
pos = "Shift Supervisor"; |
|
}else if(rating < 6){ |
|
pos = "Joint Manager"; |
|
}else if(rating < 8){ |
|
pos = "Night Director"; |
|
}else if(rating < 10){ |
|
pos = "Morning Director"; |
|
}else if(rating < 12){ |
|
pos = "Vice President"; |
|
}else if(rating < 14){ |
|
pos = "Senior Vice President"; |
|
}else if(rating < 16){ |
|
pos = "Chief of Something"; |
|
}else{ |
|
pos = "Nominal President"; |
|
} |
|
dojo.byId("result_pos").innerHTML = pos; |
|
} |
|
var anim1 = dojo.fx.wipeOut({ |
|
node: "gfx_holder", |
|
duration: 500, |
|
delay: 1000 |
|
}), |
|
anim2 = dojo.fx.wipeIn({ |
|
node: "result", |
|
duration: 500, |
|
delay: 1000 |
|
}); |
|
anim1.play(); |
|
anim2.play(); |
|
} |
|
|
|
function showStatus(circle, text){ |
|
var c = getCenter(circle), |
|
status = surface.createText({}); |
|
status.moveToBack().setFill(new dojo.Color([0, 0, 0, 0.5])) |
|
.setFont({family: "serif", variant: "small-caps", weight: "bold"}) |
|
.setShape({x: c.x, y: c.y, text: text, align: "middle"}); |
|
var anim = dojo.fx.combine([ |
|
g.fx.animateFill({ |
|
shape: status, |
|
duration: 3000, |
|
color: {end: "transparent"} |
|
}), |
|
g.fx.animateTransform({ |
|
shape: status, |
|
duration: 3000, |
|
transform: [ |
|
{name: "translate", start: [0, 0], end: [0, 300]}, |
|
{name: "original"} |
|
] |
|
}) |
|
]); |
|
dojo.connect(anim, "onEnd", function(){ status.removeShape(); }); |
|
anim.play(); |
|
} |
|
|
|
function moveToPile(shape, bad){ |
|
if(shape.moveable){ |
|
shape.moveable.destroy(); |
|
delete shape.moveable; |
|
} |
|
|
|
var oldColor = shape.getFill(), c = getCenter(shape), |
|
newX = 80 + (bad ? badItems++ : goodItems++) * 2.25 * 10, |
|
newY = bad ? 445 : 415, |
|
duration = getDuration(newX, newY, c.x, c.y, fastRate), |
|
anim = dojo.fx.chain([ |
|
g.fx.animateFill({ |
|
shape: shape, |
|
duration: 250, |
|
color: {end: "transparent"} |
|
}), |
|
g.fx.animateTransform({ |
|
shape: shape, |
|
duration: duration, |
|
transform: [ |
|
{name: "translate", start: [0, 0], end: [newX - c.x, newY - c.y]}, |
|
{name: "original"} |
|
] |
|
}), |
|
g.fx.animateFill({ |
|
shape: shape, |
|
duration: 250, |
|
color: {end: oldColor} |
|
}), |
|
g.fx.animateTransform({ |
|
shape: shape, |
|
duration: duration, |
|
transform: [ |
|
{name: "scaleAt", start: [1, newX, newY], end: [10 / radius, newX, newY]}, |
|
{name: "original"} |
|
] |
|
}) |
|
]); |
|
dojo.connect(anim, "onEnd", updateScore); |
|
anim.play(); |
|
} |
|
|
|
function repeatMove(){ |
|
var rect = vat.getShape(), c = getCenter(this), |
|
x = getRand(rect.x + radius, rect.x + rect.width - radius), |
|
y = getRand(rect.y + radius, rect.y + rect.height - radius), |
|
duration = getDuration(x, y, c.x, c.y, slowRate); |
|
this.anim = g.fx.animateTransform({ |
|
duration: duration, |
|
shape: this, |
|
transform: [ |
|
{name: "translate", start: [0, 0], end: [x - c.x, y - c.y]}, |
|
{name: "original"} |
|
] |
|
}); |
|
dojo.connect(this.anim, "onEnd", this, repeatMove); |
|
this.anim.play(); |
|
} |
|
|
|
function repeatFrost(){ |
|
this.status = "frozen"; |
|
this.setStroke({color: "orange", width: 3}); |
|
showStatus(this, "Ready"); |
|
this.anim = g.fx.animateFill({ |
|
duration: frostTime, |
|
shape: this, |
|
color: {end: "white"} |
|
}); |
|
// calculate a shift |
|
var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1; |
|
this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2}); |
|
dojo.connect(this.anim, "onAnimate", this, function(){ |
|
this.applyLeftTransform({dx: sign * dx, dy: sign * dy}); |
|
sign = -sign; |
|
}); |
|
dojo.connect(this.anim, "onEnd", this, function(){ |
|
showStatus(this, "Frozen"); |
|
moveToPile(this, true); |
|
}); |
|
this.anim.play(); |
|
} |
|
|
|
function repeatFreeze(){ |
|
this.status = "freezing"; |
|
this.setStroke({color: "black", width: 3}); |
|
this.anim = g.fx.animateFill({ |
|
duration: freezeTime, |
|
shape: this, |
|
color: {end: "blue"} |
|
}); |
|
// calculate a shift |
|
var dx = getRand(-radius, radius) / 2, dy = getRand(-radius, radius) / 2, sign = 1; |
|
this.applyLeftTransform({dx: -dx / 2, dy: -dy / 2}); |
|
dojo.connect(this.anim, "onAnimate", this, function(){ |
|
this.applyLeftTransform({dx: sign * dx, dy: sign * dy}); |
|
sign = -sign; |
|
}); |
|
dojo.connect(this.anim, "onEnd", this, repeatFrost); |
|
this.anim.play(); |
|
} |
|
|
|
function repeatBurn(){ |
|
this.status = "burnt"; |
|
this.setStroke({color: "orange", width: 3}); |
|
showStatus(this, "Done"); |
|
var anim1 = g.fx.animateFill({ |
|
duration: burnTime, |
|
shape: this, |
|
color: {end: "black"} |
|
}); |
|
var anim2 = new dojo.Animation({ |
|
duration: freezeTime, |
|
curve: [0, freezeTime] |
|
}); |
|
var matrix = this.getTransform(), c = getCenter(this); |
|
dojo.connect(anim2, "onAnimate", this, function(val){ |
|
var scale = (val % pulseTime) / pulseTime / 4 + 1; |
|
this.setTransform([m.scaleAt(scale, c), matrix]); |
|
}); |
|
this.anim = dojo.fx.combine([anim1, anim2]); |
|
dojo.connect(this.anim, "onEnd", this, function(){ |
|
showStatus(this, "Burnt"); |
|
moveToPile(this, true); |
|
}); |
|
this.anim.play(); |
|
} |
|
|
|
function repeatBroil(){ |
|
this.status = "broiling"; |
|
this.setStroke({color: "black", width: 3}); |
|
var anim1 = g.fx.animateFill({ |
|
duration: broilTime, |
|
shape: this, |
|
color: {end: "red"} |
|
}); |
|
var anim2 = new dojo.Animation({ |
|
duration: freezeTime, |
|
curve: [0, freezeTime] |
|
}); |
|
var matrix = this.getTransform(), c = getCenter(this); |
|
dojo.connect(anim2, "onAnimate", this, function(val){ |
|
var scale = (val % pulseTime) / pulseTime / 4 + 1; |
|
this.setTransform([m.scaleAt(scale, c), matrix]); |
|
}); |
|
this.anim = dojo.fx.combine([anim1, anim2]); |
|
dojo.connect(this.anim, "onEnd", this, repeatBurn); |
|
this.anim.play(); |
|
} |
|
|
|
function drag(mover){ |
|
var shape = mover.shape; |
|
shape.anim.stop(); |
|
shape.anim = null; |
|
} |
|
|
|
function drop(mover){ |
|
var c = getCenter(mover.shape); |
|
do{ // break block |
|
if(inRect(vat.getShape(), c)){ |
|
if(mover.shape.status == "fresh"){ |
|
repeatMove.call(mover.shape); |
|
return; |
|
} |
|
break; |
|
} |
|
if(inRect(freezer.getShape(), c)){ |
|
if(mover.shape.status == "fresh"){ |
|
repeatFreeze.call(mover.shape); |
|
return; |
|
} |
|
break; |
|
} |
|
if(inRect(broiler.getShape(), c)){ |
|
if(mover.shape.status == "frozen"){ |
|
repeatBroil.call(mover.shape); |
|
return; |
|
} |
|
break; |
|
} |
|
if(mover.shape.status == "burnt"){ |
|
moveToPile(mover.shape, false); // good |
|
return; |
|
} |
|
}while(false); |
|
moveToPile(mover.shape, true); // bad |
|
} |
|
|
|
function makePatties(n){ |
|
var rect = vat.getShape(); |
|
for(var i = 0; i < n; ++i){ |
|
var cx = getRand(rect.x + radius, rect.x + rect.width - radius), |
|
cy = getRand(rect.y + radius, rect.y + rect.height - radius), |
|
patty = surface.createCircle({ |
|
cx: cx, cy: cy, r: radius |
|
}).setFill("green").setStroke({ |
|
color: "black", |
|
width: 3 |
|
}); |
|
patty.status = "fresh"; |
|
patty.moveable = new g.Moveable(patty); |
|
repeatMove.call(patty); |
|
} |
|
} |
|
|
|
function initGfx(){ |
|
container = dojo.byId("gfx_holder"); |
|
surface = g.createSurface(container, 500, 500); |
|
surface_size = {width: 500, height: 500}; |
|
|
|
vat = surface.createRect({x: 10, y: 210, width: 480, height: 180}) |
|
.setStroke({color: "black", width: 7, join: "round"}); |
|
surface.createText({x: 15, y: 230, text: "Ye Olde Vat v3.2"}) |
|
.setFill("black"); |
|
|
|
freezer = surface.createRect({x: 10, y: 10, width: 230, height: 180}) |
|
.setStroke({color: "blue", width: 7, join: "round"}); |
|
surface.createText({x: 15, y: 30, text: "Deep Freeze 7000"}) |
|
.setFill("blue"); |
|
|
|
broiler = surface.createRect({x: 260, y: 10, width: 230, height: 180}) |
|
.setStroke({color: "red", width: 7, join: "round"}); |
|
surface.createText({x: 265, y: 30, text: "Hellfire Broiler A4"}) |
|
.setFill("red"); |
|
|
|
surface.createText({x: 15, y: 420, text: "Good:"}) |
|
.setFont({weight: "bold"}).setFill("green"); |
|
surface.createText({x: 15, y: 450, text: "Bad:"}) |
|
.setFont({weight: "bold"}).setFill("red"); |
|
surface.createText({x: 15, y: 480, text: "Total:"}) |
|
.setFont({weight: "bold"}).setFill("black"); |
|
score = surface.createText({x: 80, y: 485, text: "0"}) |
|
.setFont({weight: "bold", size: "24pt"}).setFill("black"); |
|
surface.createText({x: 120, y: 460, text: "DROP HERE!"}) |
|
.setFont({size: "50px"}) |
|
.setFill(new dojo.Color([0, 0, 0, 0.1])).moveToBack(); |
|
|
|
dojo.subscribe("/gfx/move/start", drag); |
|
dojo.subscribe("/gfx/move/stop", drop); |
|
makePatties(totalItems); |
|
|
|
startTime = (new Date()).getTime(); |
|
|
|
// cancel text selection and text dragging |
|
dojo.connect(container, "ondragstart", dojo, "stopEvent"); |
|
dojo.connect(container, "onselectstart", dojo, "stopEvent"); |
|
} |
|
|
|
//dojo.addOnLoad(initGfx); |
|
|
|
function startTest(level){ |
|
radius = level; |
|
var anim = dojo.fx.wipeOut({ |
|
node: "explanation", |
|
duration: 500 |
|
}); |
|
dojo.connect(anim, "onEnd", function(){ |
|
dojo.byId("gfx_holder").style.display = ""; |
|
initGfx(); |
|
}); |
|
anim.play(); |
|
} |
|
|
|
</script> |
|
|
|
<style type="text/css"> |
|
.movable { cursor: pointer; } |
|
</style> |
|
|
|
</head> |
|
<body> |
|
<h1>dojox.gfx: Career Aptitude Test</h1> |
|
<p>Warning: Canvas renderer doesn't implement event handling.</p> |
|
|
|
<div id="explanation"> |
|
<p>Thank you for your interest in <em>"I can't believe it's manure" Eateries™</em> |
|
and for submitting your resume for our review. While this is an automated response, |
|
please be assured that every resume is reviewed by us, and forwarded to the hiring |
|
managers if the skills fit our needs.</p> |
|
<p>In order order to evaluate your skills we ask you to take a career aptitude test. |
|
You will have an exciting chance to operate one of our state-of-the-art workstations |
|
remotely. Don't forget: |
|
</p> |
|
<ol> |
|
<li>Fish out a live speciment of <em>dung-42</em> from the container.</li> |
|
<li>Freeze it until you see an orange glow to kill the elements and make it less green.</li> |
|
<li>Broil it until you see the orange glow again, and drop it on the table below.</li> |
|
<li>You have to process all items without wasting resources and in minimal time.</li> |
|
</ol> |
|
<p>Warnings: don't overfreeze, don't overheat, don't drop the speciment, don't change the sequence, |
|
don't touch the speciment in heating and freezing chambers until it is's ready.</p> |
|
<p>Use your head and your mouse!</p> |
|
<p>Please select the desired position:</p> |
|
<table> |
|
<tr> |
|
<td>Workstation Supervisor </td> |
|
<td><button onclick="startTest(30);">Apply</button></td> |
|
</tr> |
|
<tr> |
|
<td>Shift Director </td> |
|
<td><button onclick="startTest(20);">Apply</button></td> |
|
</tr> |
|
<tr> |
|
<td>Vice President #49653 </td> |
|
<td><button onclick="startTest(10);">Apply</button></td> |
|
</tr> |
|
</table> |
|
</div> |
|
|
|
<div id="gfx_holder" style="width: 500px; height: 500px; display: none;"></div> |
|
|
|
<div id="result" style="display: none;"> |
|
<p id="result_pass"><strong>Impressive! Please contact us immediately.</strong></p> |
|
<p>You have made $<span id="result_dollar"></span> per minute for us. |
|
<span id="result_but">But you wasted $<span id="result_waste"></span> in materials.</span> |
|
<span id="result_and">It qualifies you to be a <em id="result_pos"></em>.</span> |
|
</p> |
|
<p id="result_fail">Should our hiring managers have an interest in your skills and |
|
capabilities, they will contact you directly. In addition, we will keep |
|
your resume on file for one year.</p> |
|
</div> |
|
|
|
</body> |
|
</html>
|
|
|