<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BinaryNumberContentViewer</title> <!-- Since GitHub Raw files use text/plain as MIME type the script cannot be executed when linking directly, instead routed over jsdelivr--> <script src="https://cdn.jsdelivr.net/gh/MicroContent/BinaryNumberContentViewer/seamless.child.min.js"></script> <script type="application/javascript"> var connection = window.seamless.connect({ url: window.location.url, allowStyleInjection: true, }); connection.receive(function(data) { switch(data.type) { case 'setContent': // parent for varying type of input sends data as special object; data.main[0] is the array of arrays with your message inside window.data = {number: parseInt(data.main[0].number,10)} binaryString = parseInt(data.main[0].number,10).toString(2); solution = binaryString.split('').map(function (c) { return c === "1" }); init(); break; case 'submit': if (data.value === 'true'){ onSubmit(); } break; case 'getXapiStatements': stmts = data.stmts; break; } }); function init() { if(window.data === undefined) { window.data = {number: 255}; binaryString } document.getElementById('question').innerHTML = "What is the binary representation of " + window.data.number + "?<br />Click on the switches to set the correct binary number."; } function updateLayout() { connection.send({ type: 'updateLayout' }); } function sendStatement(stmt) { connection.send({ type: 'sendXapiStatement', stmt: stmt }); } function getStatements() { connection.send({ type: 'getXapiStatements' }); } </script> </head> <body> <!-- EXAMPLE CODE - EDIT BELOW TO VIEW DATA --> <div style="text-align: center;"> <p id="question"></p> <button id="showHintBtn" class="btn btn-primary" onclick="showHideHint()">Show Hint</button> <canvas id="canvas" width="600" height="300" style="width: 100%"></canvas> <p id="solution"></p> </div> <div id="statistics"></div> <script type="application/javascript"> function showHideHint() { showHint = !showHint; draw(); document.getElementById("showHintBtn").innerHTML = showHint ? "Hide Hint" : "Show Hint"; } function draw() { ctx.clearRect(0, 0, 600, 300); for (var i = 0; i < 8; i++) { if (showHint) { ctx.beginPath(); ctx.font = "24px Arial"; var text = (Math.pow(2, (7 - i))).toString(); var twh = Math.round(ctx.measureText(text).width / 2); ctx.fillStyle = "#000000"; ctx.fillText(text, i * 60 + 60 + 20 - twh, 60); ctx.closePath(); } ctx.beginPath(); ctx.strokeStyle = isShowingSolution && active[i] && !solution[i] ? "#ff0000" : "#000000"; ctx.lineWidth = isShowingSolution && active[i] && !solution[i] ? 3 : 1; ctx.arc(i * 60 + 60 + 20, 100, 20, 0, Math.PI * 2, false); ctx.stroke(); if (active[i] || (isShowingSolution && solution[i])) { ctx.fillStyle = active[i] ? ((isShowingSolution && !solution[i]) ? "#66ff66" : "#00aa00") : "#ff6666"; ctx.fill(); } ctx.closePath(); ctx.lineWidth = 1; ctx.beginPath(); ctx.font = "60px Arial"; var text = active[i] ? "1" : "0"; var twh = Math.round(ctx.measureText(text).width / 2); ctx.fillStyle = !isShowingSolution || (solution[i] === active[i]) ? "#000000" : "#ff0000"; ctx.fillText(text, i * 60 + 60 + 20 - twh, 200); ctx.closePath(); if (isShowingSolution) { ctx.beginPath(); ctx.font = "60px Arial"; var text = solution[i] ? "1" : "0"; var twh = Math.round(ctx.measureText(text).width / 2); ctx.fillStyle = "#00aa00"; ctx.fillText(text, i * 60 + 60 + 20 - twh, 260); ctx.closePath(); } } } function onCanvasClicked(event) { if (!isShowingSolution) { var outerRect = {left: 0, top: 0}; var rect = canvas.getBoundingClientRect(); var x = (event.clientX - rect.left - outerRect.left) * (600 / (rect.right - rect.left)); var y = (event.clientY - rect.top - outerRect.top) * (300 / (rect.bottom - rect.top)); for (var i = 0; i < 8; i++) { if (Math.pow(x - (i * 60 + 60 + 20), 2) + Math.pow(y - 100, 2) <= 400) { active[i] = !active[i]; onInteraction(); break; } } } draw(); } function onInteraction() { var stmt = {}; // actor is set by hosting application stmt.actor = undefined; stmt.verb = { "id": "http://adlnet.gov/expapi/verbs/interacted", "display": { "de-DE": "interagierte", "en-US": "interacted", "fr-FR": "a interagi", "es-ES": "interactuó" } }; stmt.object = getXapiObject(); var responses = []; for (var i = 0; i < 8; i++) { if (active[i]) { responses.push(Math.pow(2, (7 - i)).toString()); } } stmt.result = { response: responses.reduce(function (acc, e) { return (acc.length > 0 && e.length > 0) ? acc + "[,]" + e : acc.length > 0 ? acc : e; }, "") }; sendStatement(stmt); } function getXapiObject() { // may be called on init() binaryString = window.data.number.toString(2); solution = binaryString.split('').map(function (c) { return c === "1" }); return { "objectType": "Activity", // id is set by hosting application "id": undefined, "definition": { "description": { "de-AT": "What is the binary representation of " + window.data.number + "?" }, "type": "http://adlnet.gov/expapi/activities/cmi.interaction", "interactionType": "choice", "choices": [128, 64, 32, 16, 8, 4, 2, 1].map(function (e, i) { return { id: i.toString(), description: { "de-AT": i.toString() } } }), "correctResponsesPattern": [solution.map(function (e, i) { return e ? Math.pow(2, (7 - i)).toString() : "" }) .reduce(function (acc, e) { return (acc.length > 0 && e.length > 0) ? acc + "[,]" + e : acc.length > 0 ? acc : e; }, "")] } }; } function onSubmit() { if (!isShowingSolution) { var responses = []; var allRight = true; // assign classes and disable for (var i = 0; i < 8; i++) { allRight = allRight && (active[i] === solution[i]); if (active[i]) { responses.push(Math.pow(2, (7 - i)).toString()); } } var stmt = {}; // actor is set by hosting application stmt.actor = undefined; stmt.verb = { "id": "http://adlnet.gov/expapi/verbs/answered", "display": { "de-DE": "beantwortete", "en-US": "answered", "fr-FR": "a répondu", "es-ES": "contestó" } }; stmt.object = getXapiObject(); stmt.result = { response: responses.reduce(function (acc, e) { return (acc.length > 0 && e.length > 0) ? acc + "[,]" + e : acc.length > 0 ? acc : e; }, ""), success: allRight }; sendStatement(stmt); isShowingSolution = true; document.getElementById('solution').innerHTML = "Your number is: " + active.map(function (e, i) { return e ? Math.pow(2, 7 - i) : 0; }).reduce(function (a, e) { return a + e; }, 0) + "<br />" + (allRight ? "Correct!" : "Try again!"); getStatements(); setTimeout(function() { showStatistics(stmt.result) }, 1000); draw(); } else { // remove classes and enable isShowingSolution = false; document.getElementById('solution').innerHTML = ""; hideStatistics(); draw(); } updateLayout(); } function showStatistics(result) { var answered = []; stmts.forEach(function(s) { if (s.verb.id.indexOf('answered') !== -1) { answered.push(s); } }); if(answered.length === 0) return; var correct = []; var wrongRespones = {}; var answeredWrong = 0; answered.forEach(function(s) { if (s.result.success) { correct.push(s); } else { if (wrongRespones[s.result.response] === undefined) { wrongRespones[s.result.response] = 1; } else { wrongRespones[s.result.response]++; } if (!result.success && result.response === s.result.response) { answeredWrong++; } } }); var max = {key: '', value: 0}; for (var response in wrongRespones) { if (wrongRespones[response] > max.value) { max.key = response; max.value = wrongRespones[response]; } }; var showLearningMsg = (max.key === result.response && max.value > 4) ? true : false; document.getElementById('statistics').innerHTML = 'Card answered: ' + answered.length + ' time(s)' + '<br>Ansered correct: ' + correct.length + ' time(s) (' + Math.round(correct.length/answered.length*10000)/100 + '%)' + (answeredWrong > 1 ? ('<br>You\'ve made the same mistake before ' + (answeredWrong-1) +' time(s).') : ('')) + (showLearningMsg ? ('<br>This seems to be your most common mistake, try to reflect why you keep answering that way!') : ('')); updateLayout(); } function hideStatistics() { document.getElementById('statistics').innerHTML = ''; } init(); var canvas = document.getElementById('canvas'); var ctx = canvas.getContext("2d"); var active = [false, false, false, false, false, false, false, false]; var stmts = []; var binaryString = window.data.number.toString(2); var solution = binaryString.split('').map(function (c) { return c === "1" }); var showHint = false; var isShowingSolution = false; draw(); canvas.addEventListener('click', onCanvasClicked); // updateLayout(); </script> <!-- END OF EXAMPLE CODE --> </body> </html>